AdaskoTheBeAsT.AutoMapper.SimpleInjector
13.1.0
dotnet add package AdaskoTheBeAsT.AutoMapper.SimpleInjector --version 13.1.0
NuGet\Install-Package AdaskoTheBeAsT.AutoMapper.SimpleInjector -Version 13.1.0
<PackageReference Include="AdaskoTheBeAsT.AutoMapper.SimpleInjector" Version="13.1.0" />
<PackageVersion Include="AdaskoTheBeAsT.AutoMapper.SimpleInjector" Version="13.1.0" />
<PackageReference Include="AdaskoTheBeAsT.AutoMapper.SimpleInjector" />
paket add AdaskoTheBeAsT.AutoMapper.SimpleInjector --version 13.1.0
#r "nuget: AdaskoTheBeAsT.AutoMapper.SimpleInjector, 13.1.0"
#:package AdaskoTheBeAsT.AutoMapper.SimpleInjector@13.1.0
#addin nuget:?package=AdaskoTheBeAsT.AutoMapper.SimpleInjector&version=13.1.0
#tool nuget:?package=AdaskoTheBeAsT.AutoMapper.SimpleInjector&version=13.1.0
AdaskoTheBeAsT.AutoMapper.SimpleInjector
Seamless AutoMapper integration for SimpleInjector with automatic registration and configuration
Why Use This?
This library eliminates the boilerplate of manually registering AutoMapper with SimpleInjector. It automatically:
- 🔍 Scans assemblies for
Profileclasses and registers them - 🔄 Auto-registers all AutoMapper extensions (
ITypeConverter,IValueResolver,IMemberValueResolver,IValueConverter,IMappingAction) - 💉 Handles dependency injection for your custom converters and resolvers
- ⚙️ Configures everything with a single fluent API call
- 🎯 Supports .NET 8, 9, and 10
Installation
dotnet add package AdaskoTheBeAsT.AutoMapper.SimpleInjector
1. Create Your Mapping Profiles
public class UserProfile : Profile
{
public UserProfile()
{
CreateMap<UserEntity, UserDto>();
CreateMap<UserDto, UserEntity>();
}
}
2. Register AutoMapper with SimpleInjector
using AdaskoTheBeAsT.AutoMapper.SimpleInjector;
using SimpleInjector;
var container = new Container();
// Option 1: Scan by marker type (recommended)
container.AddAutoMapper(typeof(UserProfile));
// Option 2: Scan multiple assemblies
container.AddAutoMapper(typeof(UserProfile).Assembly, typeof(OrderProfile).Assembly);
// Option 3: Scan with configuration
container.AddAutoMapper(cfg =>
{
cfg.WithMapperAssemblyMarkerTypes(typeof(UserProfile));
cfg.AsScoped(); // Change lifestyle if needed
});
3. Use IMapper in Your Services
public class UserService
{
private readonly IMapper _mapper;
public UserService(IMapper mapper)
{
_mapper = mapper;
}
public UserDto GetUser(UserEntity entity)
{
return _mapper.Map<UserDto>(entity);
}
}
What Gets Registered?
This library automatically registers the following with your container:
| Type | Registration | Description |
|---|---|---|
IConfigurationProvider |
Singleton | AutoMapper configuration (not registered when using custom mapper instance) |
IMapper |
Singleton* | Main mapper instance |
ITypeConverter<,> |
Transient | Custom type converters |
IValueConverter<,> |
Transient | Custom value converters |
IValueResolver<,,> |
Transient | Custom value resolvers |
IMemberValueResolver<,,,> |
Transient | Custom member resolvers |
IMappingAction<,> |
Transient | Custom mapping actions |
*Lifestyle is configurable (Singleton/Scoped/Transient)
Usage Examples
Basic Usage - Scan by Type
container.AddAutoMapper(typeof(UserProfile), typeof(OrderProfile));
Scan Assemblies from Your Solution
public static class AutoMapperConfigurator
{
private const string NamespacePrefix = "YourCompany.YourProject";
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);
}
}
Using Custom Resolvers with Dependency Injection
Your custom resolvers can have dependencies automatically injected:
public class DependencyResolver : IValueResolver<Source, Dest, int>
{
private readonly ISomeService _service;
public DependencyResolver(ISomeService service)
{
_service = service;
}
public int Resolve(Source source, Dest dest, int destMember, ResolutionContext context)
{
return _service.Modify(destMember);
}
}
// Registration
container.Register<ISomeService, SomeService>();
container.AddAutoMapper(typeof(DependencyResolver));
// The resolver will automatically get ISomeService injected!
Advanced Configuration
Change IMapper Lifestyle (Scoped/Transient)
container.AddAutoMapper(cfg =>
{
cfg.WithMapperAssemblyMarkerTypes(typeof(UserProfile));
cfg.AsScoped(); // Use Scoped lifestyle
// or cfg.AsTransient(); // Use Transient lifestyle
// or cfg.AsSingleton(); // Default: Singleton
});
Custom Mapper Configuration
Add custom mappings programmatically:
container.AddAutoMapper(cfg =>
{
cfg.WithAssembliesToScan(assemblies);
cfg.WithMapperConfigurationExpressionAction((container, expression) =>
{
// Add custom mappings
expression.CreateMap<Foo, Bar>().ReverseMap();
// Configure global settings
expression.AllowNullCollections = true;
});
});
Using Custom IMapper Implementation
public class MyCustomMapper : IMapper
{
// Your custom implementation
}
container.AddAutoMapper(cfg =>
{
cfg.Using<MyCustomMapper>();
cfg.WithMapperAssemblyMarkerTypes(typeof(UserProfile));
});
Unit Testing with Mock IMapper
Perfect for unit tests using Moq or similar frameworks.
When using a custom mapper instance via Using(Func<IMapper>), IConfigurationProvider is not registered
in the container, since the custom mapper fully replaces the default AutoMapper pipeline:
var testMapper = new Mock<IMapper>();
testMapper.Setup(m => m.Map<UserDto>(It.IsAny<UserEntity>()))
.Returns(new UserDto { Id = 1, Name = "Test User" });
container.AddAutoMapper(cfg =>
{
cfg.Using(() => testMapper.Object);
cfg.WithMapperAssemblyMarkerTypes(typeof(UserProfile));
});
Setting AutoMapper License Key
If you're using AutoMapper's premium features:
container.AddAutoMapper(cfg =>
{
cfg.WithLicenseKey("your-license-key");
cfg.WithMapperAssemblyMarkerTypes(typeof(UserProfile));
});
Common Patterns
Using IMapper.Map
Inject IMapper into your services to perform runtime mapping:
public class EmployeesController
{
private readonly IMapper _mapper;
private readonly IEmployeeRepository _repository;
public EmployeesController(IMapper mapper, IEmployeeRepository repository)
{
_mapper = mapper;
_repository = repository;
}
public EmployeeDto GetEmployee(int id)
{
var employee = _repository.GetById(id);
return _mapper.Map<EmployeeDto>(employee);
}
public IEnumerable<EmployeeDto> GetAllEmployees()
{
var employees = _repository.GetAll();
return _mapper.Map<IEnumerable<EmployeeDto>>(employees);
}
}
Using ProjectTo for Entity Framework / LINQ
For efficient database queries, use ProjectTo to project directly to DTOs:
public class OrderService
{
private readonly DbContext _dbContext;
private readonly IConfigurationProvider _configurationProvider;
public OrderService(DbContext dbContext, IConfigurationProvider configurationProvider)
{
_dbContext = dbContext;
_configurationProvider = configurationProvider;
}
// Option 1: Using IConfigurationProvider directly (recommended)
public async Task<List<OrderDto>> GetOrdersAsync()
{
return await _dbContext.Orders
.ProjectTo<OrderDto>(_configurationProvider)
.ToListAsync();
}
}
Or inject IMapper instead:
public class OrderService
{
private readonly DbContext _dbContext;
private readonly IMapper _mapper;
public OrderService(DbContext dbContext, IMapper mapper)
{
_dbContext = dbContext;
_mapper = mapper;
}
// Option 2: Using IMapper.ConfigurationProvider
public async Task<List<OrderDto>> GetOrdersAsync()
{
return await _dbContext.Orders
.ProjectTo<OrderDto>(_mapper.ConfigurationProvider)
.ToListAsync();
}
}
API Reference
AddAutoMapper Extension Methods
| Method | Description |
|---|---|
AddAutoMapper(params Type[]) |
Register AutoMapper by scanning assemblies containing the specified types |
AddAutoMapper(params Assembly[]) |
Register AutoMapper by scanning the specified assemblies |
AddAutoMapper(IEnumerable<Assembly>) |
Register AutoMapper by scanning the specified assemblies |
AddAutoMapper(IEnumerable<Type>) |
Register AutoMapper by scanning assemblies containing the specified types |
AddAutoMapper(Action<AutoMapperSimpleInjectorConfiguration>) |
Register AutoMapper with custom configuration |
Configuration Methods
| Method | Description |
|---|---|
WithMapperAssemblyMarkerTypes(params Type[]) |
Specify types to mark assemblies for scanning (eagerly materialized, throws on null) |
WithAssembliesToScan(IEnumerable<Assembly>) |
Specify assemblies to scan directly (defensively copied, throws on null) |
Using<TMapper>() |
Use a custom IMapper implementation |
Using(Func<IMapper>) |
Use a factory function to create IMapper (useful for testing; skips IConfigurationProvider registration) |
AsSingleton() |
Register IMapper as Singleton (default) |
AsScoped() |
Register IMapper as Scoped |
AsTransient() |
Register IMapper as Transient |
WithMapperConfigurationExpressionAction(...) |
Add custom mapper configuration |
WithLicenseKey(string) |
Set AutoMapper license key (only applied when non-null/non-empty) |
Requirements
- .NET 8.0, 9.0, or 10.0
- AutoMapper 15.1.0+
- SimpleInjector 5.5.0+
Credits
Special thanks to:
- Jimmy Bogard for creating AutoMapper
- Steven van Deursen for creating SimpleInjector
This library is based on AutoMapper.Extensions.Microsoft.DependencyInjection and adapted to work seamlessly with SimpleInjector.
License
Found this helpful? Give it a ⭐ on GitHub!
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- AutoMapper (>= 16.1.1 && < 17.0.0)
- SimpleInjector (>= 5.5.0 && < 6.0.0)
-
net8.0
- AutoMapper (>= 16.1.1 && < 17.0.0)
- SimpleInjector (>= 5.5.0 && < 6.0.0)
-
net9.0
- AutoMapper (>= 16.1.1 && < 17.0.0)
- SimpleInjector (>= 5.5.0 && < 6.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 13.1.0 | 87 | 4/4/2026 |
| 13.0.0 | 436 | 11/11/2025 |
| 12.0.0 | 255 | 10/26/2025 |
| 11.0.0 | 584 | 2/15/2025 |
| 10.0.0 | 299 | 11/13/2024 |
| 9.2.0 | 432 | 8/18/2024 |
| 9.1.0 | 284 | 5/27/2024 |
| 8.0.1 | 583 | 1/27/2024 |
| 8.0.0 | 638 | 11/29/2023 |
| 7.0.1 | 1,263 | 1/22/2023 |
| 7.0.0 | 1,024 | 11/13/2022 |
| 6.0.0 | 1,075 | 10/17/2022 |
| 5.1.0 | 1,079 | 7/24/2022 |
| 5.0.1 | 1,177 | 2/8/2022 |
| 5.0.0 | 968 | 1/6/2022 |
| 4.2.2 | 1,396 | 7/24/2021 |
| 4.2.1 | 994 | 6/27/2021 |
| 4.2.0 | 1,212 | 3/7/2021 |
| 4.1.1 | 1,221 | 1/16/2021 |
| 4.1.0 | 1,300 | 12/16/2020 |
- .NET 10 release