Skip to content

Commit

Permalink
feat: enable multiple calls of RegisterAutoMapper
Browse files Browse the repository at this point in the history
  • Loading branch information
alsami committed Jul 5, 2023
1 parent dc096e2 commit 6bd63ba
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 6 deletions.
7 changes: 7 additions & 0 deletions AutoMapper.Contrib.Autofac.DependencyInjection.sln
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
.github\workflows\tag.yml = .github\workflows\tag.yml
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoMapper.Contrib.Autofac.DependencyInjection.SecondAssembly", "test\AutoMapper.Contrib.Autofac.DependencyInjection.SecondAssembly\AutoMapper.Contrib.Autofac.DependencyInjection.SecondAssembly.csproj", "{9772890F-1F2A-4085-AF2B-384DF3ED45E1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -66,6 +68,10 @@ Global
{518E0DB7-8C83-41C6-A020-5AF0DFF05F19}.Debug|Any CPU.Build.0 = Debug|Any CPU
{518E0DB7-8C83-41C6-A020-5AF0DFF05F19}.Release|Any CPU.ActiveCfg = Release|Any CPU
{518E0DB7-8C83-41C6-A020-5AF0DFF05F19}.Release|Any CPU.Build.0 = Release|Any CPU
{9772890F-1F2A-4085-AF2B-384DF3ED45E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9772890F-1F2A-4085-AF2B-384DF3ED45E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9772890F-1F2A-4085-AF2B-384DF3ED45E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9772890F-1F2A-4085-AF2B-384DF3ED45E1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -77,6 +83,7 @@ Global
{5EADD7CB-210A-4169-A0DF-C4AE7EDBE731} = {243D0BEA-EA8B-4D7E-B645-BE17B9763896}
{518E0DB7-8C83-41C6-A020-5AF0DFF05F19} = {243D0BEA-EA8B-4D7E-B645-BE17B9763896}
{1393ACB8-9707-446C-B6FD-4C2513B43592} = {717509EE-6F82-4DCD-9110-B5EEFFDBA678}
{9772890F-1F2A-4085-AF2B-384DF3ED45E1} = {7E905FA2-EB17-4082-92C8-244C3933783F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C58D8048-52B6-44D8-AF85-8759A9ED42FA}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Version>7.1.0</Version>
<Version>7.2.0-alpha.0</Version>
<FileVersion>7.1.0.0</FileVersion>
<Copyright>2022©Sami Al Khatib</Copyright>
<Authors>Sami Al Khatib</Authors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ internal class AutoMapperModule : Module
private readonly Action<IMapperConfigurationExpression> mappingConfigurationAction;
private readonly bool propertiesAutowired;

public AutoMapperModule(Assembly[] assembliesToScan,
private static readonly MapperConfigurationExpression MapperConfigurationExpression = new();

public AutoMapperModule(
Assembly[] assembliesToScan,
Action<IMapperConfigurationExpression> mappingConfigurationAction,
bool propertiesAutowired)
{
Expand All @@ -27,18 +30,51 @@ protected override void Load(ContainerBuilder builder)
.Distinct()
.ToArray();

var profiles = builder.RegisterAssemblyTypes(distinctAssemblies)
var profiles = builder
.RegisterAssemblyTypes(distinctAssemblies)
.AssignableTo(typeof(Profile))
.As<Profile>()
.SingleInstance();

if (propertiesAutowired)
{
profiles.PropertiesAutowired();
}

builder
.Register(componentContext => new MapperConfiguration(config => this.ConfigurationAction(config, componentContext)))
.RegisterType<MapperConfigurationExpression>()
.AsSelf()
.IfNotRegistered(typeof(MapperConfigurationExpression))
.SingleInstance();

builder
.Register(componentContext => new MapperConfiguration(componentContext.Resolve<MapperConfigurationExpression>()))
.AsSelf()
.As<IConfigurationProvider>()
.IfNotRegistered(typeof(MapperConfigurationExpression))
.SingleInstance();

builder
.Register(componentContext =>
{
var expression = componentContext.Resolve<MapperConfigurationExpression>();
this.ConfigurationAction(expression, componentContext);
return new MapperConfigurationExpressionAdapter(expression);
})
.AsSelf()
.InstancePerDependency();


builder
.Register(componentContext =>
{
var adapter = componentContext.Resolve<MapperConfigurationExpressionAdapter>();
return new MapperConfiguration(adapter.MapperConfigurationExpression);
})
.As<IConfigurationProvider>()
.AsSelf()
.IfNotRegistered(typeof(IConfigurationProvider))
.SingleInstance();

var openTypes = new[]
Expand All @@ -58,14 +94,17 @@ protected override void Load(ContainerBuilder builder)
.InstancePerDependency();

if (propertiesAutowired)
{
openTypeBuilder.PropertiesAutowired();
}
}

builder
.Register(componentContext => componentContext
.Resolve<MapperConfiguration>()
.CreateMapper(componentContext.Resolve<IComponentContext>().Resolve))
.As<IMapper>()
.IfNotRegistered(typeof(IMapper))
.InstancePerLifetimeScope();
}

Expand All @@ -74,8 +113,10 @@ private void ConfigurationAction(IMapperConfigurationExpression cfg, IComponentC
this.mappingConfigurationAction.Invoke(cfg);

var profiles = componentContext.Resolve<IEnumerable<Profile>>();

foreach (var profile in profiles)

foreach (var profile in profiles)
{
cfg.AddProfile(profile);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace AutoMapper.Contrib.Autofac.DependencyInjection;

internal class MapperConfigurationExpressionAdapter
{
public MapperConfigurationExpression MapperConfigurationExpression { get; }

public MapperConfigurationExpressionAdapter(MapperConfigurationExpression mapperConfigurationExpression)
{
this.MapperConfigurationExpression = mapperConfigurationExpression;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoMapper" Version="12.0.1" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace AutoMapper.Contrib.Autofac.DependencyInjection.SecondAssembly;

public class ObjectDestination
{
public string? Id { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace AutoMapper.Contrib.Autofac.DependencyInjection.SecondAssembly;

public class ObjectSource
{
public string? Id { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace AutoMapper.Contrib.Autofac.DependencyInjection.SecondAssembly;

public class SecondAssemblyProfile : Profile
{
public SecondAssemblyProfile()
{
this.CreateMap<ObjectSource, ObjectDestination>().ReverseMap();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\AutoMapper.Contrib.Autofac.DependencyInjection\AutoMapper.Contrib.Autofac.DependencyInjection.csproj" />
<ProjectReference Include="..\AutoMapper.Contrib.Autofac.DependencyInjection.SecondAssembly\AutoMapper.Contrib.Autofac.DependencyInjection.SecondAssembly.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Autofac;
using AutoMapper.Contrib.Autofac.DependencyInjection.SecondAssembly;
using AutoMapper.Contrib.Autofac.DependencyInjection.Tests.Dtos;
using AutoMapper.Contrib.Autofac.DependencyInjection.Tests.Entities;
using AutoMapper.Contrib.Autofac.DependencyInjection.Tests.Profiles;
Expand Down Expand Up @@ -147,4 +148,44 @@ public void ContainerBuilderExtension_PropertiesAutowired_CustomValueResolverWit
Assert.True(result.IsValidFirstName);
Assert.True(result.FirstName.Length < configuration.FirstNameCharacterLimit);
}

[Fact]
public void ContainerBuilderExtensions_CallRegisterAutoMapperTwice_OnlyNewStuffAddedOnSecondCall()
{
var builder = new ContainerBuilder()
.RegisterAutoMapper(typeof(Customer).Assembly)
.RegisterAutoMapper(typeof(SecondAssemblyProfile).Assembly);

builder.RegisterType<Dependency>()
.AsSelf();

var container = builder.Build();

Assert.True(container.IsRegistered<IEnumerable<Profile>>());
Assert.True(container.IsRegistered<MapperConfiguration>());
Assert.True(container.IsRegistered<IConfigurationProvider>());
Assert.True(container.IsRegistered<IMapper>());
Assert.True(container.IsRegistered<IValueResolver<Customer, CustomerDto, string>>());
Assert.True(container.IsRegistered<IValueConverter<string, string>>());
Assert.True(container.IsRegistered<ITypeConverter<CustomerDto, Customer>>());

var profiles = container.Resolve<IEnumerable<Profile>>();
var resolver = container.Resolve<IValueResolver<Customer, CustomerDto, string>>();
var converter = container.Resolve<IValueConverter<string, string>>();
var mappers = container.Resolve<IEnumerable<IMapper>>().ToArray();
var configurationProvider = container.Resolve<IEnumerable<IConfigurationProvider>>().ToArray();
var mapperConfigurationExpressions = container.Resolve<IEnumerable<MapperConfigurationExpression>>().ToArray();

Assert.Single(mappers);
Assert.Single(configurationProvider);
Assert.Single(mapperConfigurationExpressions);
Assert.Equal(4, profiles.Count());
Assert.NotNull(resolver);
Assert.NotNull(converter);

var mapper = mappers.Single();
var src = new ObjectSource { Id = "1" };
var dest = mapper.Map<ObjectDestination>(src);
Assert.Equal(src.Id, dest.Id);
}
}

0 comments on commit 6bd63ba

Please sign in to comment.