## File: README.md

# Mapster - The Mapper of Your Domain

Writing mapping methods is a machine job. Do not waste your time, let Mapster do it.

## NuGet Sources

### NuGet Packages

| Package | Stable | Pre-release |
|---------|--------|-------------|
| **Mapster** | [](https://www.nuget.org/packages/Mapster/latest) | [](https://www.nuget.org/packages/Mapster) |
| **Mapster.Core** | [](https://www.nuget.org/packages/Mapster.Core/latest) | [](https://www.nuget.org/packages/Mapster.Core) |
| **Mapster.DependencyInjection** | [](https://www.nuget.org/packages/Mapster.DependencyInjection/latest) | [](https://www.nuget.org/packages/Mapster.DependencyInjection) |
| **Mapster.EFCore** | [](https://www.nuget.org/packages/Mapster.EFCore/latest) | [](https://www.nuget.org/packages/Mapster.EFCore) |
| **Mapster.EF6** | [](https://www.nuget.org/packages/Mapster.EF6/latest) | [](https://www.nuget.org/packages/Mapster.EF6) |
| **Mapster.JsonNet** | [](https://www.nuget.org/packages/Mapster.JsonNet/latest) | [](https://www.nuget.org/packages/Mapster.JsonNet) |
| **Mapster.Immutable** | [](https://www.nuget.org/packages/Mapster.Immutable/latest) | [](https://www.nuget.org/packages/Mapster.Immutable) |
| **Mapster.Diagnostics** | [](https://www.nuget.org/packages/Mapster.Diagnostics/latest) |  |
| **ExpressionDebugger** | [](https://www.nuget.org/packages/ExpressionDebugger/latest) |  |

### DotNet Tools

| Tool | Stable | Pre-release |
|------|--------|-------------|
| **Mapster.Tool** | [](https://www.nuget.org/packages/Mapster.Tool/latest) | [](https://www.nuget.org/packages/Mapster.Tool) |


## Installation

Install Mapster with the NuGet CLI:

```Powershell
Install-Package Mapster
```

Or use the .NET core CLI to install Mapster:

```bash
dotnet add package Mapster --project 
```

## Basic usage

### Mapping to a new object

Mapster creates the destination object and maps values to it.

```csharp
var destObject = sourceObject.Adapt<Destination>();
```

### Mapping to an existing object

You create the object, Mapster maps to the object.

```csharp
sourceObject.Adapt(destObject);
```

### Use Mapster with Dependency Injection

You can get your `IMapper` instance via dependency injection, so you do not have to change code, when migrating to mapster from automapper!

**Just add Mapster to service collection:**

```csharp
services.AddMapster();
```

**And use it with DI in your Project:**

```csharp
public class Test
{
    public Test(IMapper mapper)
    {
        var sourceObject = mapper.Adapt<Destination>();
    }
}
```

### Queryable Extensions

Mapster also provides extensions to map queryables.

```csharp
using (MyDbContext context = new MyDbContext())
{
    // Build a Select Expression from DTO
    var destinations = context.Sources.ProjectToType<Destination>().ToList();

    // Versus creating by hand:
    var destinations = context.Sources.Select(c => new Destination {
        Id = c.Id,
        Name = c.Name,
        Surname = c.Surname,
        ....
    })
    .ToList();
}
```

### Generating models & mappers

No need to write your own DTO classes. Mapster provides [Mapster.Tool](https://mapstermapper.github.io/Mapster/articles/tools/mapster-tool/Mapster-Tool-Overview.html) to help you generating models. And if you would like to have explicit mapping, Mapster also generates mapper class for you.

```csharp
[AdaptTo("[name]Dto"), GenerateMapper]
public class Student {
    ...
}
```

Then Mapster will generate for you:

```csharp
public class StudentDto {
    ...
}
public static class StudentMapper {
    public static StudentDto AdaptToDto(this Student poco) { ... }
    public static StudentDto AdaptTo(this Student poco, StudentDto dto) { ... }
    public static Expression<Func<Student, StudentDto>> ProjectToDto => ...
}
```

## What's new

- [Fluent API for code generation](https://mapstermapper.github.io/Mapster/articles/tools/mapster-tool/Fluent-API-Code-generation.html)
- [Automatically generate mapping code on build](https://mapstermapper.github.io/Mapster/articles/tools/mapster-tool/Mapster-Tool-Overview.html)
- [Define setting to nested mapping](https://mapstermapper.github.io/Mapster/articles/configuration/Config-for-nested-mapping.html)
- [`ISet`, `IDictionary`, `IReadOnlyDictionary` support](https://mapstermapper.github.io/Mapster/articles/mapping/Data-types.html#collections)
- [`EmptyCollectionIfNull`, `CreateNewIfNull` DestinationTransform](https://mapstermapper.github.io/Mapster/articles/settings/Setting-values.html#transform-value)
- [Several fixes](https://github.com/MapsterMapper/Mapster/releases/)
- New plugins
  - [Immutable collection support](https://mapstermapper.github.io/Mapster/articles/packages/Immutable.html)

## Why Mapster?

### Performance & Memory efficient

Mapster was designed to be efficient on both speed and memory. The repository includes a benchmark project in [`src/Benchmark`](https://github.com/MapsterMapper/Mapster/tree/master/src/Benchmark) that compares the local Mapster build, its compiler variants, and other modern mapping libraries like AutoMapper, Mapperly, and Facet.

- [Roslyn Compiler](https://mapstermapper.github.io/Mapster/articles/packages/ExpressionDebugging.html)
- [FEC](https://mapstermapper.github.io/Mapster/articles/packages/FastExpressionCompiler.html)
- Code generation
- Facet
- Mapperly

The snapshot below shows the `FlatTypes` scenario (`Person -> PersonDTO`), a best-case DTO with simple property-to-property mapping and no nested objects or collections.

> [!NOTE]
> More complex object shapes can change the relative results. See the [complete benchmark results](https://mapstermapper.github.io/Mapster/articles/benchmarks.html) for `ComplexTypes`, `RecursiveTypes`, and `TotalAllTypes`.

| Method                              | MapOperations | Mean      | StdDev    | Error     | Ns/Map | Ratio | Gen0 | Allocated | Alloc Ratio | Bytes/Map |
|------------------------------------ |-------------- |----------:|----------:|----------:|-------:|------:|-----:|----------:|------------:|----------:|
| `Mapster 10.0.8`                    | 1000000       |  6.849 ms | 0.6851 ms | 1.0358 ms |  6.849 |  1.01 | 4781 |  76.29 MB |        1.00 |        80 |
| `Mapster 10.0.8 (Roslyn)`           | 1000000       |  6.579 ms | 0.2782 ms | 0.4206 ms |  6.579 |  0.97 | 4781 |  76.29 MB |        1.00 |        80 |
| `Mapster 10.0.8 (FEC)`              | 1000000       |  6.549 ms | 0.9130 ms | 1.3803 ms |  6.549 |  0.97 | 4781 |  76.29 MB |        1.00 |        80 |
| `Mapster 10.0.8 (Codegen)`          | 1000000       |  5.868 ms | 0.3266 ms | 0.5488 ms |  5.868 |  0.86 | 4781 |  76.29 MB |        1.00 |        80 |
| `AutoMapper 14.0.0`                 | 1000000       | 29.645 ms | 0.8963 ms | 1.5062 ms | 29.645 |  4.37 | 4750 |  76.29 MB |        1.00 |        80 |
| `Facet 6.5.5`                       | 1000000       |  7.801 ms | 1.0231 ms | 1.5467 ms |  7.801 |  1.15 | 8601 | 137.33 MB |        1.80 |       144 |
| `Facet 6.5.5 (Compiled Projection)` | 1000000       |  5.508 ms | 0.7064 ms | 1.0679 ms |  5.508 |  0.81 | 4781 |  76.29 MB |        1.00 |        80 |
| `Mapperly 4.3.1`                    | 1000000       |  6.521 ms | 0.8369 ms | 1.2652 ms |  6.521 |  0.96 | 4781 |  76.29 MB |        1.00 |        80 |

### Step into debugging

[Step-into debugging](https://mapstermapper.github.io/docs/packages/Diagnostics.html) lets you debug your mapping and inspect values just like your code.



### Code Generation

Code generation allows you to

- Validate mapping at compile time
- Getting raw performance
- Seeing your mapping code & debugging
- Finding usage of your models' properties

There are currently two tools which you can choose based on your preferences.

- [Mapster.Tool](https://mapstermapper.github.io/Mapster/articles/tools/mapster-tool/Mapster-Tool-Overview.html) _**NEW!**_
- [TextTemplate](https://mapstermapper.github.io/Mapster/articles/tools/TextTemplate.html)

## Change logs

https://github.com/MapsterMapper/Mapster/releases

## Usage Guides with Translations

- [English](https://github.com/MapsterMapper/Mapster/wiki)
- [中文文档](https://github.com/rivenfx/Mapster-docs) (sp thx to [@staneee](https://github.com/staneee))

## Acknowledgements

[JetBrains](https://www.jetbrains.com/?from=Mapster) kindly provides Mapster with a free open-source licence for their Resharper and Rider.

- **Resharper** makes Visual Studio a much better IDE
- **Rider** is fast & powerful cross platform .NET IDE

---

## File: docs/api/index.md

# MapsterMapper Mapster API Documentation

Welcome in the Mapster API documentation!

Use the table of contents to browse API documentation for the `MapsterMapper.Mapster` Package.

---

## File: docs/api/Reference.md

---
uid: Mapster.References
---

# References

## Basic

| Method       | Description           | Link  |
| -------------|-----------------------| ----- |
| `src.Adapt<Dest>()`     | Mapping to new type | [basic](xref:Mapster.Mapping.BasicUsages) |
| `src.Adapt(dest)`       | Mapping to existing object      | [basic](xref:Mapster.Mapping.BasicUsages) |
| `query.ProjectToType<Dest>()` | Mapping from queryable     | [basic](xref:Mapster.Mapping.BasicUsages) |
| | Convention & Data type support | [data types](xref:Mapster.Mapping.DataTypes.Overview) |

### Mapper instance (for dependency injection)

| Method       | Description          | Link  |
| -------------|----------------------| ----- |
| `IMapper mapper = new Mapper()`| Create mapper instance | [mappers](xref:Mapster.Mapping.Mappers) |
| `mapper.Map<Dest>(src)`        | Mapping to new type |  |
| `mapper.Map(src, dest)`       | Mapping to existing object      |  |

### Builder (for complex mapping)

| Method        | Description           | Link  |
| ------------- |-----------------------| ----- |
| `src.BuildAdapter()`  `mapper.From(src)`     | Create builder | [mappers](xref:Mapster.Mapping.Mappers) |
| `.ForkConfig(config => ...)`     | Inline configuration | [config location](xref:Mapster.Configuration.Location) |
| `.AddParameters(name, value)`       | Passing runtime value      | [setting values](xref:Mapster.Settings.SettingValues) |
| `.AdaptToType<Dest>()`     | Mapping to new type |  |
| `.AdaptTo(dest)`       | Mapping to existing object      |  |
| `.CreateMapExpression<Dest>()`     | Get mapping expression |  |
| `.CreateMapToTargetExpression<Dest>()`       | Get mapping to existing object expression |  |
| `.CreateProjectionExpression<Dest>()`     | Get mapping from queryable expression |  |

## Config

| Method                                       | Description                             | Link  |
|----------------------------------------------|-----------------------------------------| ----- |
| `TypeAdapterConfig.GlobalSettings`           | Global config                           | [config](xref:Mapster.Configuration.Overview) |
| `var config = new TypeAdapterConfig()`       | Create new config instance              | [config instance](xref:Mapster.Configuration.Instance) |
| `src.Adapt<Dest>(config)`                    | Passing config to mapping               |  |
| `new Mapper(config)`                         | Passing config to mapper instance       |  |
| `src.BuildAdapter(config)`                   | Passing config to builder               |  |
| `config.RequireDestinationMemberSource`      | Validate all properties are mapped      | [config validation](xref:Mapster.Configuration.ValidationAndCompilation) |
| `config.RequireExplicitMapping`              | Validate all type pairs are defined     | [config validation](xref:Mapster.Configuration.ValidationAndCompilation) |
| `config.AllowImplicitDestinationInheritance` | Use config from destination based class | [inheritance](xref:Mapster.Configuration.Inheritance) |
| `config.AllowImplicitSourceInheritance`      | Use config from source based class      | [inheritance](xref:Mapster.Configuration.Inheritance) |
| `config.SelfContainedCodeGeneration`         | Generate all nested mapping in 1 method | [TextTemplate](xref:Mapster.Tools.TextTemplate) |
| `config.Compile()`                           | Validate mapping instruction & cache    | [config validation](xref:Mapster.Configuration.ValidationAndCompilation) |
| `config.CompileProjection()`                 | Validate mapping instruction & cache for queryable |  |
| `config.Clone()`                             | Copy config | [config instance](xref:Mapster.Configuration.Instance) |
| `config.Fork(forked => ...)`                 | Inline configuration | [config location](xref:Mapster.Configuration.Location) |

### Config scanning

| Method                       | Description                   | Link  |
|------------------------------|-------------------------------| ----- |
| `IRegister`                  | Interface for config scanning | [config location](xref:Mapster.Configuration.Location) |
| `config.Scan(...assemblies)` | Scan for config in assemblies | [config location](xref:Mapster.Configuration.Location) |
| `config.Apply(...registers)` | Apply registers directly      | [config location](xref:Mapster.Configuration.Location) |


### Declare settings

| Method        | Description           | Link  |
| ------------- |-----------------------| ----- |
| `config.Default` | Get setting applied to all type pairs | [config](xref:Mapster.Configuration.Overview) |
| `TypeAdapterConfig<Src, Dest>.NewConfig()`  `config.NewConfig<Src, Dest>()` | Create setting applied to specific type pairs | [config](xref:Mapster.Configuration.Overview) |
| `TypeAdapterConfig<Src, Dest>.ForType()`  `config.ForType<Src, Dest>()` | Get setting applied to specific type pairs | [config](xref:Mapster.Configuration.Overview) |
| `config.ForType(typeof(GenericPoco<>),typeof(GenericDto<>))` | Get setting applied to generic type pairs | [config](xref:Mapster.Configuration.Overview) |
| `config.When((src, dest, mapType) => ...)` | Get setting that applied conditionally | [config](xref:Mapster.Configuration.Overview) |
| `config.ForDestinationType<Dest>()` | Get setting that applied to specific destination type | [config](xref:Mapster.Configuration.Overview) |
|  | Configuration for nested mapping | [nested mapping](xref:Mapster.Configuration.NestedMapping) |

## Settings

| Method        | Description           | Apply to queryable | Link  |
| ------------- |-----------------------| ------------ | ----- |
| `AddDestinationTransform` | Clean up data for a specific type | x | [setting values](xref:Mapster.Settings.SettingValues) |
| `AfterMapping` | Add steps after mapping done |  | [before-after](xref:Mapster.Settings.BeforeAfterMapping) |
| `AvoidInlineMapping` | Skip inline process for large type mapping |  | [object reference](xref:Mapster.Settings.ObjectReferences) |
| `BeforeMapping` | Add steps before mapping start |  | [before-after](xref:Mapster.Settings.BeforeAfterMapping) |
| `ConstructUsing` | Define how to create object | x | [constructor](xref:Mapster.Settings.ConstructorMapping) |
| `EnableNonPublicMembers` | Mapping non-public properties |  | [non-public](xref:Mapster.Settings.Custom.NonPublicMembers) |
| `EnumMappingStrategy` | Choose whether mapping enum by value or by name |  | [data types](xref:Mapster.Mapping.DataTypes.Primitives) |
| `Fork` | Add new settings without side effect on main config | x | [nested mapping](xref:Mapster.Configuration.NestedMapping) |
| `GetMemberName` | Define how to resolve property name | x | [custom naming](xref:Mapster.Settings.Custom.NamingConvention) |
| `Ignore` | Ignore specific properties | x | [ignore](xref:Mapster.Settings.Custom.IgnoringMembers) |
| `IgnoreAttribute` | Ignore specific attributes annotated on properties | x | [attribute](xref:Mapster.Settings.Custom.Attributes) |
| `IgnoreIf` | Ignore conditionally | x | [ignore](xref:Mapster.Settings.Custom.IgnoringMembers) |
| `IgnoreMember` | Setup rules to ignore | x | [rule based](xref:Mapster.Settings.Custom.RuleBasedMapping) |
| `IgnoreNonMapped` | Ignore all properties not defined in `Map` | x | [ignore](xref:Mapster.Settings.Custom.IgnoringMembers) |
| `IgnoreNullValues` | Not map if src property is null |  | [shallow & merge](xref:Mapster.Settings.ShallowMerge) |
| `Include` | Include derived types on mapping |  | [inheritance](xref:Mapster.Configuration.Inheritance) |
| `IncludeAttribute` | Include specific attributes annotated on properties | x | [attribute](xref:Mapster.Settings.Custom.Attributes) |
| `IncludeMember` | Setup rules to include | x | [rule based](xref:Mapster.Settings.Custom.RuleBasedMapping) |
| `Inherits` | Copy setting from based type | x | [inheritance](xref:Mapster.Configuration.Inheritance) |
| `Map` | Define property pairs | x | [custom mapping](xref:Mapster.Settings.Custom.Mapping) |
| `MapToConstructor` | Mapping to constructor | x | [constructor](xref:Mapster.Settings.ConstructorMapping) |
| `MapToTargetWith` | Define how to map to existing object between type pair |  | [custom conversion](xref:Mapster.Settings.CustomConversionLogic) |
| `MapWith` | Define how to map between type pair | x | [custom conversion](xref:Mapster.Settings.CustomConversionLogic) |
| `MaxDepth` | Limit depth of nested mapping | x | [object reference](xref:Mapster.Settings.ObjectReferences) |
| `NameMatchingStrategy` | Define how to resolve property's name | x | [custom naming](xref:Mapster.Settings.Custom.NamingConvention) |
| `PreserveReference` | Tracking reference when mapping |  | [object reference](xref:Mapster.Settings.ObjectReferences) |
| `ShallowCopyForSameType` | Direct assign rather than deep clone if type pairs are the same |  | [shallow & merge](xref:Mapster.Settings.ShallowMerge) |
| `TwoWays` | Define type mapping are 2 ways | x | [2-ways & unflattening](xref:Mapster.Settings.Custom.TwoWaysMapping) |
| `Unflattening` | Allow unflatten mapping | x |[2-ways & unflattening](xref:Mapster.Settings.Custom.TwoWaysMapping) |
| `UseDestinationValue` | Use existing property object to map data |  |[readonly-prop](xref:Mapster.Settings.Custom.ReadonlyProperty) |

## Attributes

| Annotation        | Description           | Link  |
| ------------- |-----------------------| ----- |
| `[AdaptMember(name)]` | Mapping property to different name | [attribute](xref:Mapster.Settings.Custom.Attributes) |
| `[AdaptIgnore(side)]` | Ignore property from mapping | [attribute](xref:Mapster.Settings.Custom.Attributes) |
| `[UseDestinationValue]` | Use existing property object to map data | [attribute](xref:Mapster.Settings.Custom.Attributes) |
| `[AdaptTo]` `[AdaptFrom]` `[AdaptTwoWays]` | Add setting on POCO class | [location](xref:Mapster.Configuration.Location#attributes) |
| `[Mapper]` `[GenerateMapper]` `[PropertyType]` | Define setting for code generation | [Mapster.Tool](xref:Mapster.Tools.MapsterTool.Overview) |

## Packages

| Packages | Method        | Description           |
| ------ | ------------- |-----------------------|
| [Async](xref:Mapster.Packages.Async) | `setting.AfterMappingAsync`  `builder.AdaptToTypeAsync` | perform async operation on mapping |
| [Debugging](xref:Mapster.Packages.ExpressionDebugging) | `config.Compiler = exp => exp.CompileWithDebugInfo()` | compile to allow step into debugging |
| [Dependency Injection](xref:Mapster.Packages.DependencyInjection) | `MapContext.Current.GetService()` | Inject service into mapping logic |
| [EF 6 & EF Core](xref:Mapster.Packages.EntityFramework) | `builder.EntityFromContext` | Copy data to tracked EF entity |
| [FEC](xref:Mapster.Packages.FastExpressionCompiler) | `config.Compiler = exp => exp.CompileFast()` | compile using FastExpressionCompiler |
| [Immutable](xref:Mapster.Packages.Immutable) | `config.EnableImmutableMapping()` | mapping to immutable collection |
| [Json.net](xref:Mapster.Packages.JsonNet) | `config.EnableJsonMapping()` | map json from/to poco and string |

## Code Generation Tools

| Plugin | Tool          | Description           |
| ------ | ------------- |-----------------------|
| [Mapster.Tool](xref:Mapster.Tools.MapsterTool.Overview) | `dotnet mapster` | generate DTOs and mapping codes on build |
| [TextTemplate](xref:Mapster.Tools.TextTemplate) | `t4` | generate mapping codes using t4 |

---

## File: docs/articles/configuration/Config-for-nested-mapping.md

---
uid: Mapster.Configuration.NestedMapping
title: "Configuration - Config for nested mapping"
---

For example if you have parent and child classes.

```csharp
class ParentPoco
{
    public string Id { get; set; }
    public List<ChildPoco> Children { get; set; }
    public string Name { get; set; }
}

class ChildPoco
{
    public string Id { get; set; }
    public List<GrandChildPoco> GrandChildren { get; set; }
}

class GrandChildPoco
{
    public string Id { get; set; }
}
```

And if you have setting on parent type.

```csharp
TypeAdapterConfig.NewConfig()
    .PreserveReference(true);
```

By default, children types will not get effect from `PreserveReference`.

To do so, you must specify all type pairs inside `ParentPoco`.

```csharp
TypeAdapterConfig.NewConfig()
    .PreserveReference(true);
TypeAdapterConfig<ChildPoco, ChildDto>.NewConfig()
    .PreserveReference(true);
TypeAdapterConfig<GrandChildPoco, GrandChildDto>.NewConfig()
    .PreserveReference(true);
```

Or you can set `PreserveReference` in global setting.

```csharp
TypeAdapterConfig.GlobalSettings.Default.PreserveReference(true);
```

## Fork

You can use `Fork` command to define config that applies only specified mapping down to nested mapping without polluting global setting.

```csharp
TypeAdapterConfig.NewConfig()
    .Fork(config => config.Default.PreserveReference(true));
```

**Ignore if string is null or empty**

Another example, Mapster only can ignore null value ([IgnoreNullValues](xref:Mapster.Settings.ShallowMerge#copy-vs-merge)), however, you use `Fork` to ignore null or empty.

```csharp
TypeAdapterConfig.NewConfig()
    .Fork(config => config.ForType<string, string>()
        .MapToTargetWith((src, dest) => string.IsNullOrEmpty(src) ? dest : src)
    );
```

---

## File: docs/articles/configuration/Config-inheritance.md

---
uid: Mapster.Configuration.Inheritance
title: "Configuration - Inheritance"
---

## Implicit inheritance

Type mappings will automatically inherit for source types. Ie. if you set up following config.

```csharp
TypeAdapterConfig<SimplePoco, SimpleDto>.NewConfig()
    .Map(dest => dest.Name, src => src.Name + "_Suffix");
```

A derived type of `SimplePoco` will automatically apply the base mapping config.

```csharp
var dest = TypeAdapter.Adapt<DerivedPoco, SimpleDto>(src);
//dest.Name = src.Name + "_Suffix"
```

If you don't wish for a derived type to use the base mapping, you can turn it off by using `AllowImplicitSourceInheritance`

```csharp
TypeAdapterConfig.GlobalSettings.AllowImplicitSourceInheritance = false;
```

And by default, Mapster will not inherit destination type mappings. You can turn it on by `AllowImplicitDestinationInheritance`.

```csharp
TypeAdapterConfig.GlobalSettings.AllowImplicitDestinationInheritance = true;
```

## Explicit inheritance

You can copy setting from based type explicitly.

```csharp
TypeAdapterConfig<DerivedPoco, DerivedDto>.NewConfig()
        .Inherits<SimplePoco, SimpleDto>();
```

## Include derived types

You can also include derived type to the based type declaration. For example:

```csharp
TypeAdapterConfig<Vehicle, VehicleDto>.NewConfig()
    .Include<Car, CarDto>();

Vehicle vehicle = new Car { Id = 1, Name = "Car", Make = "Toyota" };
var dto = vehicle.Adapt<Vehicle, VehicleDto>();

dto.ShouldBeOfType<CarDto>();
((CarDto)dto).Make.ShouldBe("Toyota"); //The 'Make' property doesn't exist in Vehicle
```

---

## File: docs/articles/configuration/Config-instance.md

---
uid: Mapster.Configuration.Instance
title: "Configuration - Config Instance"
---

## Creating `Config` Instance with `TypeAdapterConfig`

You may wish to have different settings in different scenarios.
If you would not like to apply setting at a static level, Mapster also provides setting instance configurations.

```csharp
var config = new TypeAdapterConfig();
config.Default.Ignore("Id");
```

### `ForType` Configuration Methods

For instance configurations, you can use the same `NewConfig` and `ForType` methods that are used at the global level with
the same behavior: `NewConfig` drops any existing configuration and `ForType` creates or enhances a configuration.

```csharp
config.NewConfig<TSource, TDestination>()
        .Map(dest => dest.FullName,
            src => string.Format("{0} {1}", src.FirstName, src.LastName));

config.ForType<TSource, TDestination>()
        .Map(dest => dest.FullName,
            src => string.Format("{0} {1}", src.FirstName, src.LastName));
```

### `Adapt` Configuration Methods

You can apply a specific config instance by passing it to the `Adapt` method. (NOTE: please reuse your config instance to prevent recompilation)

```csharp
var result = src.Adapt(config);
```

### `Map` Configuration Methods

Or to a Mapper instance.

```csharp
var mapper = new Mapper(config);
var result = mapper.Map(src);
```

## Cloning `Config` Instance

If you would like to create configuration instance from existing configuration, you can use `Clone` method. For example, if you would like to clone from global setting.

```csharp
var newConfig = TypeAdapterConfig.GlobalSettings.Clone();
```

Or clone from existing configuration instance

```csharp
var newConfig = oldConfig.Clone();
```

### `Fork` Configuration

`Fork` is similar to `Clone`, but `Fork` will allow you to keep configuration and mapping in the same location. See [Config Location](xref:Mapster.Configuration.Location) for more info.

```csharp
var forked = mainConfig.Fork(config => 
    config.ForType()
            .Map(dest => dest.code, src => src.Id));

var dto = poco.Adapt<Dto>(forked);
```

---

## File: docs/articles/configuration/Config-location.md

---
uid: Mapster.Configuration.Location
title: "Configuration - Location"
---

## Entry point for configuration

Configuration should be set only once and reuse for mapping. Therefore, we should not keep configuration and mapping in the same location. For example:

```csharp
config.ForType().Ignore("Id");
var dto1 = poco1.Adapt<Dto>(config);

config.ForType().Ignore("Id"); //<--- Exception occurred here, because config was already compiled
var dto2 = poco2.Adapt<Dto>(config);
```

Therefore, you should separate configuration and mapping. Configuration should keep in entry point such as `Main` function or `Global.asax.cs` or `Program.cs` / `Startup.cs`.

```csharp
// Application_Start in Global.asax.cs
config.ForType().Ignore("Id");
```

```csharp
// in Controller class
var dto1 = poco1.Adapt<Dto>(config);
var dto2 = poco2.Adapt<Dto>(config);
```

### Keep together with mapping

A potential problem with separating configuration and mapping is that the code will be separated into 2 locations. You might remove or alter mapping, and you can forget to update the configuration. `Fork` method allow you to keep config and mapping inline.

```csharp
var dto = poco.Adapt<Dto>(config.Fork(forked => forked.ForType().Ignore("Id"));
```

Don't worry about performance, forked config will be compiled only once. When mapping occurs for the second time, `Fork` function will return config from cache.

#### Using Fork in generic class or method

`Fork` method uses filename and line number and the key. But if you use `Fork` method inside generic class or method, you must specify your own key (with all type names) to prevent `Fork` to return invalid config from different type arguments.

```csharp
IQueryable GetItems<TPoco, TDto>()
{
    var forked = config.Fork(
        f => f.ForType<TPoco, TDto>().Ignore("Id"), 
        $"MyKey|{typeof(TPoco).FullName}|{typeof(TDto).FullName}");
    return db.Set<TPoco>().ProjectToType(forked);
}
```

### In separated assemblies

It's relatively common to have mapping configurations spread across a number of different assemblies.
Perhaps your domain assembly has some rules to map to domain objects and your web api has some specific rules to map to your api contracts.

#### Scan method

It can be helpful to allow assemblies to be scanned for these rules so you have some basic method of organizing your rules and not forgetting to have the registration code called. In some cases, it may even be necessary to register the assemblies in a particular order, so that some rules override others. Assembly scanning helps with this.

Assembly scanning is simple, just create any number of `IRegister` implementations in your assembly, then call `Scan` from your `TypeAdapterConfig` class:

```csharp
public class MyRegister : IRegister
{
   public void Register(TypeAdapterConfig config)
   {
      config.NewConfig<TSource, TDestination>();

      //OR to create or enhance an existing configuration
      config.ForType<TSource, TDestination>();
   }
}
```

To scan and register at the Global level:

```csharp
TypeAdapterConfig.GlobalSettings.Scan(assembly1, assembly2, assemblyN)
```

For a specific config instance:

```csharp
var config = new TypeAdapterConfig();
config.Scan(assembly1, assembly2, assemblyN);
```

#### Apply method

If you use other assembly scanning library such as MEF, you can easily apply registration with `Apply` method.

```csharp
var registers = container.GetExports();
config.Apply(registers);
```

`Apply` method also allows you to selectively pick from one or more `IRegister` rather than every `IRegister` in assembly.

```csharp
var register = new MockingRegister();
config.Apply(register);
```

### Attributes

You can also set config together with your POCO classes. For example:

```csharp
[AdaptTo(typeof(StudentDto), PreserveReference = true)]
public class Student {
    ...
}
```

---

## File: docs/articles/configuration/Config-validation-and-compilation.md

---
uid: Mapster.Configuration.ValidationAndCompilation
title: "Configuration - Validation and Compilation"
---

To validate your mapping in unit tests and in order to help with "Fail Fast" situations, the following strict mapping modes have been added.

## Explicit Mapping

Forcing all classes to be explicitly mapped:

```csharp
//Default is "false"
TypeAdapterConfig.GlobalSettings.RequireExplicitMapping = true;
//This means you have to have an explicit configuration for each class, even if it's just:
TypeAdapterConfig.NewConfig();
```

## Checking Destination Member

Forcing all destination properties to have a corresponding source member or explicit mapping/ignore:

```csharp
//Default is "false"
TypeAdapterConfig.GlobalSettings.RequireDestinationMemberSource = true;
```

## Validating Mappings

Both a specific TypeAdapterConfig or all current configurations can be validated. In addition, if Explicit Mappings (above) are enabled, it will also include errors for classes that are not registered at all with the mapper.

```csharp
//Validate a specific config
var config = TypeAdapterConfig.NewConfig();
config.Compile();

//Validate globally
TypeAdapterConfig.NewConfig();
TypeAdapterConfig.NewConfig();
TypeAdapterConfig.GlobalSettings.Compile();
```

## Config Compilation

Mapster will automatically compile mapping for first time usage.

```csharp
var result = poco.Adapt<Dto>();
```

However, you can explicitly compile mapping by `Compile` method.

```csharp
//Global config
TypeAdapterConfig.GlobalSettings.Compile();

//Config instance
var config = new TypeAdapterConfig();
config.Compile();
```

Calling `Compile` method on start up helps you validate mapping and detect problem on start-up time, not on run-time.

NOTE: After compile, when you change setting in config, it will generate errors. Therefore, make sure you finish configuration before calling `Compile`.

---

## File: docs/articles/configuration/Configuration.md

---
uid: Mapster.Configuration.Overview
title: "Configuration - Overview"
---


## Setting per type pair

You can easily create settings for a type mapping by using: `TypeAdapterConfig<TSource, TDestination>.NewConfig()`.
When `NewConfig` is called, any previous configuration for this particular TSource => TDestination mapping is dropped.

```csharp
TypeAdapterConfig<TSource, TDestination>
    .NewConfig()
    .Ignore(dest => dest.Age)
    .Map(dest => dest.FullName,
          src => string.Format("{0} {1}", src.FirstName, src.LastName));
```

As an alternative to `NewConfig`, you can use `ForType` in the same way:

```csharp
TypeAdapterConfig<TSource, TDestination>
    .ForType()
    .Ignore(dest => dest.Age)
    .Map(dest => dest.FullName,
         src => string.Format("{0} {1}", src.FirstName, src.LastName));
```

`ForType` differs in that it will create a new mapping if one doesn't exist, but if the specified TSource => TDestination
mapping does already exist, it will enhance the existing mapping instead of dropping and replacing it.  

## Global setting

Use global settings to apply policies to all mappings.

```csharp
TypeAdapterConfig.GlobalSettings.Default.PreserveReference(true);
```

Then for individual type mappings, you can easily override the global setting(s).

```csharp
TypeAdapterConfig<SimplePoco, SimpleDto>.NewConfig().PreserveReference(false);
```

## Rule based settings

To set the setting at a more granular level. You can use the `When` method in global settings.
In the example below, when any source type and destination type are the same, we will not the copy the `Id` property.

```csharp
TypeAdapterConfig.GlobalSettings.When((srcType, destType, mapType) => srcType == destType)
                               .Ignore("Id");
```

In this example, the config would only apply to Query Expressions (projections).

```csharp
TypeAdapterConfig.GlobalSettings.When((srcType, destType, mapType) => mapType == MapType.Projection)
                                .IgnoreAttribute(typeof(NotMapAttribute));
```

## Destination type only

A setting can also be created without knowing the source type, by using `ForDestinationType`. For example, you can do `AfterMapping` setting to validate after mapping.

```csharp
TypeAdapterConfig.GlobalSettings.ForDestinationType()
                                .AfterMapping(dest => dest.Validate());
```

>[!NOTE] 
>`ForDestinationType` above will always apply to all types assignable to `IValidator`. If destination class implements `IValidator`, it will also apply the `AfterMapping` config.

## Open generics

If the mapping type is generic, you can create a setting by passing generic type definition to `ForType`.

```csharp
TypeAdapterConfig.GlobalSettings.ForType(typeof(GenericPoco<>), typeof(GenericDto<>))
                                .Map("value", "Value");
```
>[!Note]
> Starting with Mapster version 10.0.8, [validation](xref:Mapster.Configuration.ValidationAndCompilation#validating-mappings) for type pairs settings containing open generic type is disabled.
>If you require validation of such settings, you must register the configuration for at least one pair of closed generic types:
>```csharp
>TypeAdapterConfig.GlobalSettings.RequireDestinationMemberSource = true; // check all destination member mapping
>TypeAdapterConfig.GlobalSettings.ForType(typeof(GenericPoco<>), typeof(GenericDto<>))
>                                .Map("value", "Value");
>
> TypeAdapterConfig<GenericPoco, GenericDto<string>>.NewConfig();
> TypeAdapterConfig.GlobalSettings.Compile(); // validate
>```

---

## File: docs/articles/mapping/data-types/Collections.md

---
uid: Mapster.Mapping.DataTypes.Collections
title: "Mapping - Collections"
---

## Collections

This includes mapping among lists, arrays, collections, dictionary including various interfaces: `IList<T>`, `ICollection<T>`, `IEnumerable<T>`, `ISet<T>`, `IDictionary<TKey, TValue>` etc...

```csharp
var list = db.Pocos.ToList();
var target = list.Adapt>();
```