AutoMapper Documentation
repository·main·Indexed 27 days ago
https://github.com/luckypennysoftware/automapperA library for automating data mapping between different object types to reduce boilerplate code. Includes guides on configuration via MapperConfiguration or IServiceCollection, executing mappings with Map(), and detailed upgrade paths for versions 10.0 through 15.0, covering changes to .NET target frameworks, dependency injection, and licensing requirements.
What's inside AutoMapper
- AutoMapper is a convention-based object-to-object mapper designed for model projection. It uses a fluent configuration API and a convention-based matching algorithm to map source values to destination values. It is primarily used to flatten complex object models into DTOs (Data Transfer Objects) or other simple objects suitable for serialization, messaging, or acting as an anti-corruption layer between domain and application layers.
Replace removed attributes `MapToAttribute` and `IgnoreMapAttribute`
mainTheMapToAttributeandIgnoreMapAttributehave been removed. To achieve the same functionality, switch to the fluent API or implement the attribute logic manually in your own code.Migrate ConstructProjectionUsing to ConstructUsing
mainThe
ConstructProjectionUsingmethod has been consolidated intoConstructUsing. TheConstructUsingmethod now accepts anExpression<Func<TSource, TDestination>>to handle both in-memory mapping and LINQ projections.Migration Steps:
- Replace all usages of
ConstructProjectionUsingwithConstructUsing. - If your existing
ConstructUsinguses lambda statements, method groups, or delegates, you must either:- Convert the logic to a lambda expression.
- Move to the
Func-based overloads (ensure you add necessary parameters to your delegates).
// Old IMappingExpression<TSource, TDestination> ConstructUsing(Func<TSource, TDestination> ctor); IMappingExpression<TSource, TDestination> ConstructProjectionUsing(Expression<Func<TSource, TDestination>> ctorExpression); // New IMappingExpression<TSource, TDestination> ConstructUsing(Expression<Func<TSource, TDestination>> ctor); IMappingExpression<TSource, TDestination> ConstructUsing(Func<TSource, ResolutionContext, TDestination> ctor);- Replace all usages of
Gather configuration before initialization
mainYou can decouple the definition of your mapping rules from the initialization of the
MapperConfiguration. UseMapperConfigurationExpressionto collect yourCreateMapandAddProfilecalls, which can then be passed to a bootstrapper or used to instantiate the finalMapperConfiguration.var cfg = new MapperConfigurationExpression(); cfg.CreateMap<Source, Dest>(); cfg.AddProfile<MyProfile>(); MyBootstrapper.InitAutoMapper(cfg); var mapperConfig = new MapperConfiguration(cfg, loggerFactory); IMapper mapper = new Mapper(mapperConfig);Handle collection mapping changes in v10.0
mainIn version 10.0, all collections are mapped by default, even if they do not have a setter. If you want to prevent a collection from being mapped, you must explicitly ignore it.Organize mappings using Profile instances
mainTo organize mapping configurations, create classes that inherit from
Profile. Define your mappings within the class constructor.Note: As of version 5.0, the
Configure()method is obsolete and will be removed in version 6.0. Use the constructor instead.Configuration applied inside a profile only affects maps within that profile, whereas configuration applied to the root
MapperConfigurationapplies to all maps.public class OrganizationProfile : Profile { public OrganizationProfile() { CreateMap<Foo, FooDto>(); // Use CreateMap... Etc.. here (Profile methods are the same as configuration methods) } }Upgrade to AutoMapper 13.0: Target .NET 6
mainAutoMapper 13.0 now targets .NET 6. Ensure your project environment is compatible with .NET 6 before upgrading.Explicitly ignore C# Indexers (`Item` property)
mainC# Indexers (the
Itemproperty) are no longer ignored by default. To ignore them, you must explicitly configure this using:ShouldMapProperty(globally)GlobalIgnores(globally)- Per-member configuration
Get started with AutoMapper
mainIf you are new to AutoMapper, you should begin with the 'Getting-started' guide to learn the fundamental concepts and initial setup required to use the library.Use Dependency Injection with Destination Factories
mainDestination factories are resolved from the DI container, allowing you to inject services into the factory's constructor. To use this, register your services and the factory in the DI container, then use
.ConstructUsing<TFactory>()in your AutoMapper configuration.public class DIAwareConstructor : IDestinationFactory<Source, Destination> { private readonly IMyService _service; public DIAwareConstructor(IMyService service) { _service = service; } public Destination Construct(Source source, ResolutionContext context) { return new Destination { InitialValue = _service.CalculateValue(source.Value) }; } } // Registration services.AddScoped<IMyService, MyService>(); services.AddAutoMapper(cfg => { cfg.CreateMap<Source, Destination>() .ConstructUsing<DIAwareConstructor>(); }, typeof(IMyService).Assembly);Handle reversed string-based MapFrom and Attribute mapping in v10.0
mainString-basedMapFromconfigurations and attribute mappings are now reversed. To resolve issues caused by this, you can explicitly create a reverse map or ignore the reversed member.Create open generic type maps
mainAutoMapper allows you to define a single mapping for open generic types. Because C# requires closed generic type parameters, you must use the
System.Typeoverload ofCreateMapto define the mapping for the open generic types (e.g.,typeof(Source<>)). Once defined, AutoMapper will automatically apply this configuration to any closed generic types (e.g.,Source<int>toDestination<int>) at runtime.Note: AutoMapper skips open generic type maps during configuration validation to avoid errors on incompatible closed types (like
Source<Foo>toDestination<Bar>) that do not have a valid conversion.public class Source<T> { public T Value { get; set; } } public class Destination<T> { public T Value { get; set; } } // Create the mapping using System.Type var configuration = new MapperConfiguration(cfg => cfg.CreateMap(typeof(Source<>), typeof(Destination<>)), loggerFactory); // Usage with closed types var source = new Source<int> { Value = 10 }; var dest = mapper.Map<Source<int>, Destination<int>>(source);