Skip to content

Commit

Permalink
Added IConfigurationHelper interface to dynamically choose the method…
Browse files Browse the repository at this point in the history
… to call given arguments.
  • Loading branch information
almostchristian committed Oct 23, 2022
1 parent 3b804aa commit f30f420
Show file tree
Hide file tree
Showing 8 changed files with 343 additions and 151 deletions.
26 changes: 26 additions & 0 deletions src/ConfigurationProcessor.Core/IConfigurationProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// -------------------------------------------------------------------------------------------------
// Copyright (c) almostchristian. All rights reserved.
// -------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;

namespace ConfigurationProcessor
{
/// <summary>
/// Represents a configuration helper for dynamically executing methods.
/// </summary>
public interface IConfigurationProcessor
{
/// <summary>
/// Invokes a specificed configuration method with specificed arguments. Method is chosen based on the argument types.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="instance"></param>
/// <param name="methodName"></param>
/// <param name="arguments"></param>
void Invoke<T>(T instance, string methodName, params object[] arguments)
where T : class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// -------------------------------------------------------------------------------------------------
// Copyright (c) almostchristian. All rights reserved.
// -------------------------------------------------------------------------------------------------

using System;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.Configuration;

namespace ConfigurationProcessor.Core.Implementation
{
internal class ConfigurationHelperImplementation : IConfigurationProcessor
{
private readonly ResolutionContext resolutionContext;
private readonly IConfigurationSection configurationSection;
private readonly ConfigurationReaderOptions? options;

public ConfigurationHelperImplementation(ResolutionContext resolutionContext, IConfigurationSection configurationSection, ConfigurationReaderOptions? options)
{
this.resolutionContext = resolutionContext;
this.configurationSection = configurationSection;
this.options = options;
}

public void Invoke<T>(T instance, string methodName, params object[] arguments)
where T : class
{
resolutionContext.CallConfigurationMethod(
typeof(T),
methodName,
configurationSection,
null,
Array.Empty<TypeResolver>(),
null!,
() => arguments.ToList(),
(arguments, methodInfo) =>
{
if (methodInfo.IsStatic)
{
arguments.Insert(0, instance);
methodInfo.Invoke(null, arguments.ToArray());
}
else
{
methodInfo.Invoke(instance, arguments.ToArray());
}
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ public void AddServices(TConfig builder, string? sectionName, bool getChildren,
var builderDirective = string.IsNullOrEmpty(sectionName) ? ConfigurationSection : ConfigurationSection.GetSection(sectionName);
if (!getChildren || builderDirective.GetChildren().Any())
{
var methodCalls = ResolutionContext.GetMethodCalls(builderDirective, getChildren);
ResolutionContext.CallConfigurationMethods(
typeof(TConfig),
methodCalls,
builderDirective,
getChildren,
null,
options.MethodFilterFactory,
(arguments, methodInfo) =>
{
Expand Down
356 changes: 208 additions & 148 deletions src/ConfigurationProcessor.Core/Implementation/Extensions.cs

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</PropertyGroup>

<PropertyGroup>
<Version>1.5.1</Version>
<Version>1.6.0</Version>
<FileVersion>$(Version).$([System.DateTime]::Now.ToString(yy))$([System.DateTime]::Now.DayOfYear.ToString(000))</FileVersion>
<PackageVersion>$(Version)</PackageVersion>
<InformationalVersion>$(FileVersion)-$(GIT_VERSION)</InformationalVersion>
Expand All @@ -23,6 +23,8 @@
<PackageTags>dependencyinjection;configuration;ioc;di;</PackageTags>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageReleaseNotes>
v1.6.0
- Added IConfigurationProcessor interface to dynamically call methods
v1.5.1
- Fixed exception with optional parameters
v1.5.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,42 @@ public void WithObjectNotation_CallExtensionMethodOnConfigurationObject_Executes
Assert.Equal("helloworld2314", option.Value.Name);
}

[Fact]
public void WithObjectNotation_UsingHelper_CallsDynamicAddConfigureName()
{
var randomValue = Guid.NewGuid().ToString();
var json = @$"
{{
'WithHelper': '{randomValue}'
}}";

var sp = BuildFromJson(json);
var option = sp.GetService<IOptions<ComplexObject>>();

Assert.NotNull(option);
Assert.Equal(randomValue, option.Value.Name);
}

[Theory]
[InlineData("Time")]
[InlineData("Time2")]
public void WithObjectNotation_UsingHelperWithComplexOptions_CallsDynamicAddConfigureName(string timeProperty)
{
var randomValue = Guid.NewGuid().ToString();
var json = @$"
{{
'WithHelper': {{
'{timeProperty}' : '13:00:10'
}}
}}";

var sp = BuildFromJson(json);
var option = sp.GetService<IOptions<ComplexObject>>();

Assert.NotNull(option);
Assert.Equal(new TimeSpan(13, 0, 10), option.Value.Value.Time);
}

private IServiceProvider BuildFromJson(string json)
{
var serviceCollection = ProcessJson(json);
Expand Down
13 changes: 13 additions & 0 deletions tests/TestDummies/DummyServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Copyright (c) Integrated Health Information Systems Pte Ltd. All rights reserved.
// -------------------------------------------------------------------------------------------------

using ConfigurationProcessor;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
Expand Down Expand Up @@ -275,5 +276,17 @@ public static void Append<T>(this ComplexObject obj, string value)
{
obj.Name += value;
}

public static IServiceCollection AddWithHelper(this IServiceCollection services, string text, IConfigurationProcessor helper)
{
services.AddConfigurationAction(c => helper.Invoke(c, "AddConfigureName", text));
return services;
}

public static IServiceCollection AddWithHelper(this IServiceCollection services, Action<ComplexObject.ChildValue> configure, IConfigurationProcessor helper)
{
services.AddConfigurationAction(c => helper.Invoke(c, "AddConfigureValue", configure));
return services;
}
}
}
4 changes: 4 additions & 0 deletions tests/TestDummies/TestDummies.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\ConfigurationProcessor.Core\ConfigurationProcessor.Core.csproj" />
</ItemGroup>

</Project>

0 comments on commit f30f420

Please sign in to comment.