Skip to content

Commit

Permalink
Merge pull request #30 from RaymondHuy/Issue#8
Browse files Browse the repository at this point in the history
Enhance Issue #8: Support complex type when configure module
  • Loading branch information
tillig authored Feb 19, 2020
2 parents 1635b86 + ae0b891 commit f9e5644
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 15 deletions.
3 changes: 2 additions & 1 deletion src/Autofac.Configuration/Autofac.Configuration.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="1.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="2.2.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" Condition="Exists('$(MSBuildThisFileDirectory)../../.git')">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
Expand Down
46 changes: 36 additions & 10 deletions src/Autofac.Configuration/Core/ModuleRegistrar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

using System;
using System.Linq;
using System.Reflection;
using Autofac.Core;
using Autofac.Core.Activators.Reflection;
using Microsoft.Extensions.Configuration;
Expand Down Expand Up @@ -75,19 +76,44 @@ public virtual void RegisterConfiguredModules(ContainerBuilder builder, IConfigu
foreach (var moduleElement in configuration.GetOrderedSubsections("modules"))
{
var moduleType = moduleElement.GetType("type", defaultAssembly);
var module = (IModule)null;
using (var moduleActivator = new ReflectionActivator(
moduleType,
new DefaultConstructorFinder(),
new MostParametersConstructorSelector(),
moduleElement.GetParameters("parameters"),
moduleElement.GetProperties("properties")))
{
module = (IModule)moduleActivator.ActivateInstance(new ContainerBuilder().Build(), Enumerable.Empty<Parameter>());
}

var module = CreateModule(moduleType, moduleElement);

builder.RegisterModule(module);
}
}

private IModule CreateModule(Type type, IConfiguration moduleElement)
{
var constructor = GetMostParametersConstructor(type);

var parametersElement = moduleElement.GetSection("parameters");

var parameters = constructor.GetParameters()
.Select(p => parametersElement.GetSection(p.Name).Get(p.ParameterType))
.ToArray();

var module = constructor.Invoke(parameters) as IModule;

var propertiesElement = moduleElement.GetSection("properties");

propertiesElement.Bind(module);

return module;
}

private static ConstructorInfo GetMostParametersConstructor(Type type)
{
var container = new ContainerBuilder().Build();

var constructors = new DefaultConstructorFinder()
.FindConstructors(type)
.Select(c => new ConstructorParameterBinding(c, Enumerable.Empty<Parameter>(), container))
.ToArray();

return new MostParametersConstructorSelector()
.SelectConstructorBinding(constructors, Enumerable.Empty<Parameter>())
.TargetConstructor;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
<EmbeddedResource Remove="TestResults\**" />
<None Remove="TestResults\**" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="1.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Xml" Version="1.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Xml" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="Moq" Version="4.13.1" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.113">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;

namespace Autofac.Configuration.Test.Core
{
public class ModuleConfiguration_ComplexTypeFixture
{
[Fact]
public void RegisterConfiguredModules_ComplexParameterType()
{
var builder = EmbeddedConfiguration.ConfigureContainerWithJson("ModuleConfiguration_ComplexType.json");
var container = builder.Build();

var poco = container.Resolve<ComplexParameterComponent>();

Assert.Equal(2, poco.List.Count());
Assert.Equal("Val1", poco.List[0]);
Assert.Equal("Val2", poco.List[1]);
}

[Fact]
public void RegisterConfiguredModules_ComplexPropertyType()
{
var builder = EmbeddedConfiguration.ConfigureContainerWithJson("ModuleConfiguration_ComplexType.json");
var container = builder.Build();

var poco = container.Resolve<ComplexPropertyComponent>();

Assert.Equal(2, poco.List.Count());
Assert.Equal("Val3", poco.List[0]);
Assert.Equal("Val4", poco.List[1]);
}

private class ComplexParameterTypeModule : Module
{
public ComplexType ComplexType { get; set; }

public ComplexParameterTypeModule(ComplexType complexType)
{
ComplexType = complexType;
}

protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<ComplexParameterComponent>().WithProperty("List", ComplexType.List);
}
}

private class ComplexPropertyTypeModule : Module
{
public ComplexType ComplexType { get; set; }

protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<ComplexPropertyComponent>().WithProperty("List", ComplexType.List);
}
}

private class ComplexType
{
public IList<string> List { get; set; }
}

private class ComplexParameterComponent
{
public IList<string> List { get; set; }
}

private class ComplexPropertyComponent
{
public IList<string> List { get; set; }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"defaultAssembly": "Autofac.Configuration.Test",
"modules": [
{
"type": "Autofac.Configuration.Test.Core.ModuleConfiguration_ComplexTypeFixture+ComplexParameterTypeModule",
"parameters": {
"ComplexType": {
"List": [ "Val1", "Val2" ]
}
}
},
{
"type": "Autofac.Configuration.Test.Core.ModuleConfiguration_ComplexTypeFixture+ComplexPropertyTypeModule",
"properties": {
"ComplexType": {
"List": [ "Val3", "Val4" ]
}
}
}
]
}

0 comments on commit f9e5644

Please sign in to comment.