Coder Perfect

In ASP.NET Core, how do you set up Automapper?

Problem

I’m new to.NET, so instead of learning the “old ways,” I decided to tackle.NET Core. I found a lengthy post here on how to set up AutoMapper for.NET Core, but is there a more basic tour for a newbie?

Asked by theutz

Solution #1

I was able to sort things out! Here are the specifics:

Answered by theutz

Solution #2

To use AutoMapper with ASP.NET Core, follow these steps.

Installing AutoMapper.Extensions is the first step. Microsoft. NuGet Package’s DependencyInjection.

Step 2: In Solution, create a folder called “Mappings” to store Mappings.

Step 3: After adding the Mapping folder, we created a class called “MappingProfile,” which can be anything distinctive and easy to remember.

All Mappings will be maintained in this class.

Step 4: Using Startup “ConfigureServices” to Initialize the Mapper

In the Startup Class, we must initialize the profile we built as well as register the AutoMapper Service.

  Mapper.Initialize(cfg => cfg.AddProfile<MappingProfile>());

  services.AddAutoMapper();

We need to Initialize and Register AutoMapper in the ConfigureServices method, as shown in the code snippet.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }


    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });


        // Start Registering and Initializing AutoMapper

        Mapper.Initialize(cfg => cfg.AddProfile<MappingProfile>());
        services.AddAutoMapper();

        // End Registering and Initializing AutoMapper

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    }}

Step 5: Collect data.

To obtain a mapped result, we must use AutoMapper. Mapper. Proper Destination and Source must be mapped and passed.

AutoMapper.Mapper.Map<Destination>(source);

CodeSnippet

    [HttpPost]
    public void Post([FromBody] SchemeMasterViewModel schemeMaster)
    {
        if (ModelState.IsValid)
        {
            var mappedresult = AutoMapper.Mapper.Map<SchemeMaster>(schemeMaster);
        }
    }

Answered by Saineshwar

Solution #3

I’d like to add to @theutz’s responses, specifically this line:

// services.AddAutoMapper(typeof(Startup));  // <-- newer automapper version uses this signature.

AutoMapper has a bug (most likely). Extensions. Microsoft. Version 3.2.0 of DependencyInjection. (I’m using the.NET Core 2.0 framework.)

This problem is addressed in this GitHub issue. If your AutoMapper injection looks like this: If your classes inheriting AutoMapper’s Profile class are outside of the assembly where your Startup class is, they will most likely not be registered.

services.AddAutoMapper();

Unless you expressly tell AutoMapper which assemblies to look for in profiles.

This is how it can be done in your startup. ConfigureServices:

services.AddAutoMapper(<assembies> or <type_in_assemblies>);

where “assemblies” and “type in assemblies” refer to the assembly in which your application’s Profile classes are defined. E.g:

services.AddAutoMapper(typeof(ProfileInOtherAssembly), typeof(ProfileInYetAnotherAssembly));

I believe (and I emphasize “believe”) that this is related to the implementation of parameterless overload as follows (source code from GitHub):

public static IServiceCollection AddAutoMapper(this IServiceCollection services)
{
     return services.AddAutoMapper(null, AppDomain.CurrentDomain.GetAssemblies());
}

We rely on CLR to have already JITed assemblies containing AutoMapper profiles, which may or may not be true because they are only jitted when needed (more details in this StackOverflow question).

Answered by GrayCat

Solution #4

I just want to add to theutz’s excellent response:

If you let your mapping profile inherit from MapperConfigurationExpression instead of Profile, you can very simply add a test to verify your mapping setup, which is always handy:

[Fact]
public void MappingProfile_VerifyMappings()
{
    var mappingProfile = new MappingProfile();

    var config = new MapperConfiguration(mappingProfile);
    var mapper = new Mapper(config);

    (mapper as IMapper).ConfigurationProvider.AssertConfigurationIsValid();
}

Answered by Arve Systad

Solution #5

This is how I fixed it (it’s similar to the above, but I think it’s a cleaner solution) It’s compatible with.NET Core 3.x.

Create the MappingProfile.cs class and add Maps to the constructor (I plan on using a single class to hold all my mappings)

    public class MappingProfile : Profile
    {
        public MappingProfile()
        {
            CreateMap<Source, Dest>().ReverseMap();
        }
    }

In Startup.cs, add below to add to DI (the assembly arg is for the class that holds your mapping configs, in my case, it’s the MappingProfile class).

//add automapper DI
services.AddAutoMapper(typeof(MappingProfile));

Use it in Controller just like any other DI object.

    [Route("api/[controller]")]
    [ApiController]
    public class AnyController : ControllerBase
    {
        private readonly IMapper _mapper;

        public AnyController(IMapper mapper)
        {
            _mapper = mapper;
        }

        public IActionResult Get(int id)
        {
            var entity = repository.Get(id);
            var dto = _mapper.Map<Dest>(entity);

            return Ok(dto);
        }
    }


Answered by Coy Meeks

Post is based on https://stackoverflow.com/questions/40275195/how-to-set-up-automapper-in-asp-net-core