AdaskoTheBeAsT.AutoMapper.SimpleInjector
AutoMapper extensions for SimpleInjector
Badges
Usage
Scans assemblies and:
- adds profiles to mapping configuration
- adds implementations of
ITypeConverter
,IValueConverter
,IValueResolver
,IMemberValueResolver
,IMappingAction
instances as transient to the container.
There are few options to use with Container
instance:
-
Marker type from assembly which will be scanned
container.AddAutoMapper(typeof(MyMapper), type2 /*, ...*/);
-
List of assemblies which will be scanned.
Below is sample for scanning assemblies from some solution.
[ExcludeFromCodeCoverage] public static class AutoMapperConfigurator { private const string NamespacePrefix = "YourNamespace"; public static void Configure(Container container) { var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList(); var assemblies = new List<Assembly>(); var mainAssembly = typeof(AutoMapperConfigurator).Assembly; var refAssemblies = mainAssembly.GetReferencedAssemblies(); foreach (var assemblyName in refAssemblies .Where(a => a.FullName.StartsWith(NamespacePrefix, StringComparison.OrdinalIgnoreCase))) { var assembly = loadedAssemblies.Find(l => l.FullName == assemblyName.FullName) ?? AppDomain.CurrentDomain.Load(assemblyName); assemblies.Add(assembly); } container.AddAutoMapper(assemblies); } }
This registers AutoMapper:
-
MapperConfiguration
- As a singleton -
IMapper
- As a singleton -
ITypeConverter
instances as transient -
IValueConverter
instances as transient -
IValueResolver
instances as transient -
IMemberValueResolver
instances as transient -
IMappingAction
instances as transient
Mapping configuration is static as it is the root object that can create an IMapper
.
Mapper instance are registered as singleton. You can configure this with the Lifestyle
parameter. Be careful changing this, as Mapper
takes a dependency on a factory method to instantiate the other extensions.
Advanced usage
IMapper
instance and marker type from assembly for unit testing (Moq sample)
Setting up custom var testMapper = new Mock<IMapper>();
container.AddAutoMapper(
cfg =>
{
cfg.Using(() => testMapper.Object);
cfg.WithMapperAssemblyMarkerTypes(typeof(MyMarkerType));
});
IMapper
implementation and marker type from assembly
Setting up custom container.AddAutoMapper(
cfg =>
{
cfg.Using<MyCustomMapper>();
cfg.WithMapperAssemblyMarkerTypes(typeof(MyMarkerType));
});
IMapper
implementation and assemblies to scan
Setting up custom container.AddAutoMapper(
cfg =>
{
cfg.Using<MyCustomMapper>();
cfg.WithAssembliesToScan(assemblies);
});
IMapper
implementation
Setting assemblies to scan and different lifetime for container.AddAutoMapper(
cfg =>
{
cfg.WithAssembliesToScan(assemblies);
cfg.AsScoped();
});
Setting configuration for MapperConfigurationExpression
container.AddAutoMapper(
cfg =>
{
cfg.WithAssembliesToScan(assemblies);
cfg.AsScoped();
cfg.WithMapperConfigurationExpressionAction(
(
container1,
expression) => expression.CreateMap<Foo, Bar>().ReverseMap());
});
Library scans all descendant classes from Profile
so it is better to store mapping in Profile
descendants
public class Profile1 : Profile
{
public Profile1()
{
CreateMap<Source, Dest>();
}
}
Mapper.Map usage
To map at runtime, add a dependency on IMapper
:
public class EmployeesController {
private readonly IMapper _mapper;
public EmployeesController(IMapper mapper)
=> _mapper = mapper;
// use _mapper.Map to map
}
ProjectTo usage
Starting with 8.0 you can use IMapper.ProjectTo
. The old ProjectTo
is an extension method and does not have dependency injection available. Pass an IConfigurationProvider
instance directly:
var orders = await dbContext.Orders
.ProjectTo<OrderDto>(_configurationProvider)
.ToListAsync();
Or you can use an IMapper
instance:
var orders = await dbContext.Orders
.ProjectTo<OrderDto>(_mapper.ConfigurationProvider)
.ToListAsync();
Thanks to:
- Jimmy Boggard for AutoMapper
- Steven van Deursen for SimpleInjector
Code originates from AutoMapper.Extensions.Microsoft.DependencyInjection and was changed to work with SimpleInjector.