AutoMapper: convention-based object mapping in .NET, and what the licence change means for you
A convention-based object-object mapper in .NET.
At a glance
- What is it?
- AutoMapper removes hand-written property copying between types by building mapping plans from conventions you declare at startup. It is a mature .NET library, but the licence key in the registration snippet is now part of the adoption decision.
- Who is it for?
- Adopt AutoMapper if your codebase has many DTO conversions and you want mapping plans declared once and validated in DEBUG builds. Do not adopt it if you need zero-allocation mapping on a hot path, or if a paid licence is unacceptable for your project.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 21 days ago.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The boilerplate AutoMapper exists to delete
Every layered .NET application eventually grows a folder of methods that copy properties from an entity to a DTO and back. The README describes the problem plainly: "getting rid of code that mapped one object to another", and calls that code "rather dreary and boring to write". The target user is a .NET developer who already has two type families (domain and transport, or entity and view model) whose members mostly line up by name and type, and who wants the alignment expressed as a declaration rather than a loop.
It is a poor fit when the two types do not line up. If most destination members need bespoke computation, the mapping configuration becomes a second, less readable copy of the hand-written code you were trying to avoid. The library pays off in proportion to how conventional your names are.
How mapping plans are built from CreateMap declarations
The unit of configuration is a type pair. You call cfg.CreateMap<Foo, FooDto>() inside a MapperConfiguration callback, and the library builds a plan for that pair. The README shows two entry points: constructing MapperConfiguration directly with an optional loggerFactory, and the more typical services.AddAutoMapper(cfg => { ... }) form used with IServiceCollection.
The second form does more than register the mapper. According to the README, AutoMapper will automatically register implementations of IValueResolver<TSource, TDestination, TDestMember>, IMemberValueResolver<TSource, TDestination, TSourceMember, TDestMember>, ITypeConverter<TSource, TDestination>, IValueConverter<TSourceMember, TDestinationMember>, ICondition<TSource, TDestination, TDestMember>, IPreCondition<TSource, TDestination>, and IMappingAction<TSource, TDestination> found in the provided assemblies. That is the convention-based part: custom logic is discovered by interface, not wired by hand.
At runtime the mapper is an IMapper. You call mapper.Map<FooDto>(foo) and the plan executes. Validation is separate and opt-in. The README puts configuration.AssertConfigurationIsValid() behind an #if DEBUG block with the comment "only during development, validate your mappings; remove it before release". That advice is worth taking literally: the assertion walks every configured map and throws when a destination member has no source, which is exactly the class of bug that otherwise surfaces as a null in production.
Installing AutoMapper and mapping your first type pair
The README points at NuGet as the distribution channel and gives two install commands. From the package manager console, Install-Package AutoMapper. From the .NET CLI, dotnet add package AutoMapper. Pick the one matching your workflow; the CLI form is the one to use in a terminal or a CI script.
dotnet add package AutoMapperAfter the package resolves, register the mapper where you build your service collection. The README's typical form passes a configuration callback to AddAutoMapper and declares the type pairs inside it.
services.AddAutoMapper(cfg =>
{
cfg.CreateMap<Foo, FooDto>();
cfg.CreateMap<Bar, BarDto>();
});Then map in application code. The README's example is two calls, one per pair, and the return value is the destination instance.
var fooDto = mapper.Map<FooDto>(foo);
var barDto = mapper.Map<BarDto>(bar);Before you ship, add the validation call the README recommends for DEBUG builds. It runs at startup and fails fast when a destination member cannot be filled.
#if DEBUG
configuration.AssertConfigurationIsValid();
#endifIf you are not using dependency injection, the README's alternative is to build the mapper yourself from the configuration object: var mapper = configuration.CreateMapper();. That path needs no IServiceCollection at all.
The licence key is now part of the registration code
The README contains a section titled "How do I set the license key?" with a code example that assigns cfg.LicenseKey = "<license key here>"; inside the AddAutoMapper callback, and states that you can register for a key at AutoMapper.io. The repository licence field is NOASSERTION, which means GitHub could not classify the LICENSE.md file into a standard identifier. Read LICENSE.md yourself rather than assuming MIT.
This changes the evaluation. A library whose registration snippet includes a licence key is not the same procurement decision as one that does not, even when the code is otherwise identical. The README also says that paying customers can contact support via their account, which implies a tiered arrangement, but it does not enumerate tiers, prices, or what happens to an unlicensed mapper at runtime. Those gaps are in the documentation, not in your reading of it. If your organisation has rules about copyleft or commercial terms, the licence file is the artifact to hand to whoever reviews that, and this article is not legal advice.
Where AutoMapper is the wrong tool
The failure mode is silent and it is the one the README already warns about. A destination member with no matching source is not a compile error. Without AssertConfigurationIsValid in a DEBUG build, the plan can leave that member at its default, and a null string or zero int reaches your API response. The README's own framing ("You might want to know exactly what your mapping does at runtime") acknowledges that the mapping is not obvious from the call site.
There is a second cost: reflection-driven mapping is not free. The library builds plans, but the work still happens per call, and on a tight loop over a large collection the overhead is measurable against a hand-written assignment. If you are mapping millions of rows on a hot path, or you are in a trimming or ahead-of-time compilation scenario where reflection is restricted, this is the wrong tool. Neither the README nor the release list given here documents a source-generator mode, so do not assume one exists.
A third case: if you have exactly one type pair and it is used in one place, the configuration, the DI registration, and the validation call are more code than the assignment you were replacing.
AutoMapper alternatives and how they differ
The most common comparison in the search data is AutoMapper vs Mapperly. The difference in approach is where the mapping code lives. AutoMapper builds mapping plans at runtime from CreateMap declarations, and the mapper is resolved through DI or created from a MapperConfiguration. Mapperly is a source generator: it emits the mapping code at compile time, so the assignment statements end up in your assembly and there is no runtime plan to build. That removes the reflection cost and makes a missing member a compile-time or generated-code concern rather than a startup assertion. The trade-off is that you lose the runtime flexibility of changing configuration after startup.
Mapster is the other name that appears in the questions, and the question asked is whether it is faster. This article cannot answer that, because no benchmark is available here. What can be said is that the two libraries share the convention-based premise, so the migration is mostly mechanical, and the decision should rest on whether you need the AutoMapper extension packages (Collection, ExpressionMapping, EF6, Data, EnumMapping, all linked from the README) rather than on a speed claim you have not measured yourself.
Maintenance, upgrade cost, and what the release history shows
The repository is not archived, and the last push was on 2026-09-09. The release list shows v16.2.0 on 2026-07-02, v15.1.3 on 2026-03-18, and v16.1.1 on 2026-03-13. Two things follow. First, the 15.x line received a patch after 16.x was already out, so a major upgrade is not the only way to get fixes. Second, the gap between v16.1.1 and v16.2.0 is roughly four months, which is a normal cadence for a library of this age rather than a signal either way.
The upgrade cost is concentrated in major versions. The repository has a docs/ directory and a readthedocs configuration, and the README links a getting started guide and a wiki on readthedocs. That is where migration notes would live; the README itself does not document a rollback path or a breaking-change list, so check the documentation site for the version you are moving to. The repository also carries AutoMapper.slnx, a Build.ps1, a Setup.ps1, and a Push.ps1, which tells you the maintainers build and publish from scripts in the repo. That matters only if you intend to build from source rather than consume the NuGet package.
Editorial conclusion
Adopt AutoMapper if your codebase has many DTO conversions and you want mapping plans declared once and validated in DEBUG builds. Do not adopt it if you need zero-allocation mapping on a hot path, or if a paid licence is unacceptable for your project. Before committing, verify three things: that the AutoMapper package version you resolve on NuGet matches the licence terms you can accept, that every CreateMap you write passes AssertConfigurationIsValid in your own build, and that your DI registration path (AddAutoMapper with a configuration callback) is the one your version documents.
Frequently asked questions
What is AutoMapper?
It is a .NET library that maps one object to another using conventions you declare with CreateMap, so you do not write the property-copying code by hand. The README describes it as solving the problem of "getting rid of code that mapped one object to another".
Is AutoMapper still free?
The README documents a licence key that you set with cfg.LicenseKey inside the AddAutoMapper callback, and says you can register for a key at AutoMapper.io, which implies a paid option exists. The repository licence field is NOASSERTION, so read LICENSE.md for the actual terms.
How do I install AutoMapper?
Install it from NuGet. The README gives dotnet add package AutoMapper for the .NET CLI and Install-Package AutoMapper for the package manager console.
How do I use AutoMapper in .NET Core?
Register it on the service collection with services.AddAutoMapper(cfg => { cfg.CreateMap<Foo, FooDto>(); }), then resolve IMapper and call mapper.Map<FooDto>(foo). The README notes that this form also auto-registers IValueResolver, ITypeConverter, IValueConverter, ICondition, IPreCondition and IMappingAction implementations from the provided assemblies.
How do I use AutoMapper without dependency injection?
Build the configuration yourself with new MapperConfiguration(cfg => { ... }, loggerFactory) and call configuration.CreateMapper() to get the mapper. The README presents this as the alternative to the IServiceCollection registration.
What should I replace AutoMapper with?
The search data pairs it with Mapperly and Mapster. Mapperly takes a different approach: it generates the mapping code at compile time instead of building a plan at runtime, which removes the reflection cost but gives up runtime configuration. No benchmark comparing them is available here.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/luckypennysoftware-automapper)