Automapper instellen in ASP.NET Core

Ik ben relatief nieuw bij .NET en ik besloot .NET Core aan te pakken in plaats van de “oude manieren” te leren. Ik heb een gedetailleerd artikel gevonden over het instellen van AutoMapper voor .NET Core hier, maar is er een eenvoudigere oplossing voor een nieuweling?


Antwoord 1, autoriteit 100%

Ik heb het door! Dit zijn de details:

  1. Voeg het belangrijkste AutoMapper-pakket toe aan uw oplossing via NuGet.

  2. Voeg het AutoMapper Dependency Injection Package toe aan uw oplossing via NuGet.

  3. Maak een nieuwe klasse voor een kaartprofiel. (Ik heb een klasse gemaakt in de hoofdoplossingsmap met de naam MappingProfile.csen voeg de volgende code toe.) Ik gebruik een Useren UserDtoobject als voorbeeld.

    public class MappingProfile : Profile {
         public MappingProfile() {
             // Add as many of these lines as you need to map your objects
             CreateMap<User, UserDto>();
             CreateMap<UserDto, User>();
         }
     }
    
  4. Voeg vervolgens de AutoMapperConfiguration toe in de Startup.cszoals hieronder weergegeven:

    public void ConfigureServices(IServiceCollection services) {
         // .... Ignore code before this
        // Auto Mapper Configurations
         var mapperConfig = new MapperConfiguration(mc =>
         {
             mc.AddProfile(new MappingProfile());
         });
         IMapper mapper = mapperConfig.CreateMapper();
         services.AddSingleton(mapper);
         services.AddMvc();
     }
    
  5. Als u het toegewezen object in code wilt oproepen, doet u zoiets als het volgende:

    public class UserController : Controller {
         // Create a field to store the mapper object
         private readonly IMapper _mapper;
         // Assign the object in the constructor for dependency injection
         public UserController(IMapper mapper) {
             _mapper = mapper;
         }
         public async Task<IActionResult> Edit(string id) {
             // Instantiate source object
             // (Get it from the database or whatever your code calls for)
             var user = await _context.Users
                 .SingleOrDefaultAsync(u => u.Id == id);
             // Instantiate the mapped data transfer object
             // using the mapper you stored in the private field.
             // The type of the source object is the first type argument
             // and the type of the destination is the second.
             // Pass the source object you just instantiated above
             // as the argument to the _mapper.Map<>() method.
             var model = _mapper.Map<UserDto>(user);
             // .... Do whatever you want after that!
         }
     }
    

Antwoord 2, autoriteit 12%

Stap om AutoMapper te gebruiken met ASP.NET Core.

Stap 1. AutoMapper.Extensions.Microsoft.DependencyInjection installeren vanuit het NuGet-pakket.

voer hier de afbeeldingsbeschrijving in

Stap 2. Maak een map in de oplossing om toewijzingen met de naam “Mappings” te bewaren.

voer hier de afbeeldingsbeschrijving in

Stap 3. Na het toevoegen van de map Mapping hebben we een klasse toegevoegd met de naam “MappingProfile” deze naam kan iets unieks en goeds te begrijpen zijn.

In deze les gaan we alle toewijzingen onderhouden.

voer hier de afbeeldingsbeschrijving in

Stap 4. Mapper initialiseren in Startup “ConfigureServices”

In de opstartklasse moeten we het door ons gemaakte profiel initialiseren en ook de AutoMapper-service registreren.

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

Codefragment om de ConfigureServices-methode weer te geven waar we AutoMapper moeten initialiseren en registreren.

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);
    }}

Stap 5. Uitvoer verkrijgen.

Om het resultaat in kaart te brengen, moeten we AutoMapper.Mapper.Map bellen en de juiste bestemming en bron doorgeven.

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

CodeSnippet

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

Antwoord 3, autoriteit 7%

Ik wil de antwoorden van @theutz uitbreiden – namelijk deze regel :

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

Er is een bug (waarschijnlijk) in AutoMapper.Extensions.Microsoft.DependencyInjection versie 3.2.0. (Ik gebruik .NET Core 2.0)

Dit wordt aangepakt in ditGitHub-probleem. Als uw klassen die de AutoMapper-profielklasse overerven, bestaan ​​buiten de assembly waar uw opstartklasse is, zullen ze waarschijnlijk niet worden geregistreerd als uw AutoMapper-injectie er als volgt uitziet:

services.AddAutoMapper();

tenzij u expliciet specificeert naar welke samenstellingen u in AutoMapper-profielen wilt zoeken.

Het kan als volgt worden gedaan in uw Startup.ConfigureServices:

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

waar “assemblies”en “type_in_assemblies”verwijzen naar de assembly waar profielklassen in uw toepassing zijn opgegeven. Bijv.:

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

Ik veronderstel(en ik leg de nadruk op dit woord) dat als gevolg van de volgende implementatie van parameterloze overbelasting (broncode van GitHub) :

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

We vertrouwen op CLR die al is geïnteresseerd met een door Jites-montage met automatische profielen die kunnen zijn of niet waar zijn, omdat ze alleen worden gedrukt wanneer nodig is (meer details in deze stackoverflow vraag).


Antwoord 4

In mijn Startup.cs (Core 2.2, Automapper 8.1.1)

services.AddAutoMapper(new Type[] { typeof(DAL.MapperProfile) });            

In mijn gegevenstoegangsproject

namespace DAL
{
    public class MapperProfile : Profile
    {
        // place holder for AddAutoMapper (to bring in the DAL assembly)
    }
}

In mijn modeldefinitie

namespace DAL.Models
{
    public class PositionProfile : Profile
    {
        public PositionProfile()
        {
            CreateMap<Position, PositionDto_v1>();
        }
    }
    public class Position
    {
        ...
    }

Antwoord 5

Voor AutoMapper 9.0.0:

public static IEnumerable<Type> GetAutoMapperProfilesFromAllAssemblies()
    {
        foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            foreach (var aType in assembly.GetTypes())
            {
                if (aType.IsClass && !aType.IsAbstract && aType.IsSubclassOf(typeof(Profile)))
                    yield return aType;
            }
        }
    }

MapperProfiel:

public class OrganizationProfile : Profile
{
  public OrganizationProfile()
  {
    CreateMap<Foo, FooDto>();
    // Use CreateMap... Etc.. here (Profile methods are the same as configuration methods)
  }
}

In uw startup:

services.AddAutoMapper(GetAutoMapperProfilesFromAllAssemblies()
            .ToArray());

In controller of service:
Mapper injecteren:

private readonly IMapper _mapper;

Gebruik:

var obj = _mapper.Map<TDest>(sourceObject);

Antwoord 6

Je moet een pakket installeren om de automapper in te stellen.

dotnet add package AutoMapper.Extensions.Microsoft.DependencyInjection

Nadat de AddAutoMapper beschikbaar zal zijn in services.

public void ConfigureServices(IServiceCollection services)
{
     services.AddAutoMapper(typeof(Startup));
}

Maak mapper van Werknemersklasse naar WerknemersDTO.

using AutoMapper;
public class AutomapperProfile: Profile
{
    public AutomapperProfile()
    {
        //Source to destination.
        CreateMap<Employee,EmployeeDTO>();
    }
}

EmployeeController brengt in kaart van werknemer naar werknemerDTo

using System.Collections.Generic;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
[Route("api/[controller]")]
[ApiController()]
public class EmployeeController : ControllerBase
{
    private readonly IMapper _mapper;
    public EmployeeController(IMapper mapper)
    {
        _mapper = mapper;
    }
    [HttpGet]
    public IEnumerable<EmployeeDTO> GetEmployees()
    {
        /* 
        Assume it to be a  service call/database call
        it returns a list of employee, and now we will map it to EmployeeDTO
        */
        var employees = Employee.SetupEmployee();
        var employeeDTO = _mapper.Map<IEnumerable<EmployeeDTO>>(employees);
        return employeeDTO;
    }
}

Employee.cs ter referentie

using System.Collections.Generic;
public class Employee
{
    public int EmployeeId { get; set; }
    public string EmployeeName { get; set; }
    public int Salary { get; set; }
    public static IEnumerable<Employee> SetupEmployee()
    {
        return new List<Employee>()
        {
            new Employee(){EmployeeId = 1, EmployeeName ="First", Salary=10000},
            new Employee(){EmployeeId = 2, EmployeeName ="Second", Salary=20000},
            new Employee(){EmployeeId = 3, EmployeeName ="Third", Salary=30000},
            new Employee(){EmployeeId = 4, EmployeeName ="Fourth", Salary=40000},
            new Employee(){EmployeeId = 5, EmployeeName ="Fifth", Salary=50000}
        };
    }
}

EmployeeDTO.cs ter referentie

public class EmployeeDTO
{
    public int EmployeeId { get; set; }
    public string EmployeeName { get; set; }
}

Antwoord 7

Ik gebruik AutoMapper 6.1.1 en asp.net Core 1.1.2.

Definieer eerst de profielklassen die zijn overgenomen door de profielklasse van Automapper. Ik heb een IProfile-interface gemaakt die leeg is, het doel is alleen om de klassen van dit type te vinden.

public class UserProfile : Profile, IProfile
    {
        public UserProfile()
        {
            CreateMap<User, UserModel>();
            CreateMap<UserModel, User>();
        }
    }

Maak nu een aparte klasse, bijvoorbeeld Mappings

public class Mappings
    {
     public static void RegisterMappings()
     {            
       var all =
       Assembly
          .GetEntryAssembly()
          .GetReferencedAssemblies()
          .Select(Assembly.Load)
          .SelectMany(x => x.DefinedTypes)
          .Where(type => typeof(IProfile).GetTypeInfo().IsAssignableFrom(type.AsType()));
            foreach (var ti in all)
            {
                var t = ti.AsType();
                if (t.Equals(typeof(IProfile)))
                {
                    Mapper.Initialize(cfg =>
                    {
                        cfg.AddProfiles(t); // Initialise each Profile classe
                    });
                }
            }         
        }
    }

Nu in MVC Core webproject in Startup.cs-bestand, in de constructor, roept u de Mapping-klasse aan die alle toewijzingen initialiseert op het moment van toepassing
aan het laden.

Mappings.RegisterMappings();

Antwoord 8

Voor ASP.NET Core (getest met 2.0+ en 3.0), als u liever de brondocumentatie leest:
https://github.com/AutoMapper/AutoMapper. Extensions.Microsoft.DependencyInjection/blob/master/README.md

Anders werkt het volgen van deze 4 stappen:

  1. Installeer AutoMapper.Extensions.Microsoft.DependancyInjection van nuget.

  2. Voeg gewoon wat profielklassen toe.

  3. Voeg dan hieronder toe aan je startup.cs-klasse.
    services.AddAutoMapper(OneOfYourProfileClassNamesHere)

  4. Injecteer dan gewoon IMapper in uw controllers of waar u het ook nodig heeft:

public class EmployeesController {
    private readonly IMapper _mapper;
    public EmployeesController(IMapper mapper){
        _mapper = mapper;
    }

En als je ProjectTo wilt gebruiken, is dat nu eenvoudig:

var customers = await dbContext.Customers.ProjectTo<CustomerDto>(_mapper.ConfigurationProvider).ToListAsync()

Antwoord 9

Asp.Net Core 2.2 met AutoMapper.Extensions.Microsoft.DependencyInjection.

public class MappingProfile : Profile
{
  public MappingProfile()
  {
      CreateMap<Domain, DomainDto>();
  }
}

In Startup.cs

services.AddAutoMapper(typeof(List.Handler));

Antwoord 10

Laten we eens kijken hoe u Auto mapper kunt toevoegen aan onze .NET Core-toepassing.

stap: 1
De eerste stap is om het bijbehorende NuGet-pakket te installeren:

Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection

stap: 2

Na het installeren van het vereiste pakket, is de volgende stap het configureren van de services. Laten we het doen in de klasse Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAutoMapper(typeof(Startup));
    services.AddControllersWithViews();
}

stap: 3

Laten we beginnen met het gebruik, we hebben een domeinobject met de naam Gebruiker:

public class User
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Address { get; set; }
}

In de UI-laag zouden we een weergavemodel hebben om de gebruikersinformatie weer te geven:

public class UserViewModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
}

stap: 4

Een goede manier om onze kaartconfiguraties te ordenen is met Profielen. We moeten klassen maken die erven van de Profile-klasse en de configuratie in de constructor plaatsen:

public UserProfile()
{
    CreateMap<User, UserViewModel>();
}

stap: 5

Laten we nu een controller definiëren en de Auto-Mapping-mogelijkheden gebruiken die we zojuist hebben toegevoegd:

public class UserController : Controller
{
    private readonly IMapper _mapper;
    public UserController(IMapper mapper)
    {
        _mapper = mapper;
    }
    public IActionResult Index()
    {
        // Populate the user details from DB
        var user = GetUserDetails();
        UserViewModel userViewModel = _mapper.Map<UserViewModel>(user);
        return View(userViewModel);
    }
}

Eerst injecteren we het mapper-object in de controller. Vervolgens roepen we de methode Map() aan, die het User-object toewijst aan het UserViewModel-object. Let verder op een lokale methode GetUserDetails die wij gebruiken voor de lokale dataopslag.
Je kunt de implementatie ervan vinden in onze broncode.


Antwoord 11

services.AddAutoMapper(); werkte niet voor mij. (Ik gebruik Asp.Net Core 2.0)

Na configuratie zoals hieronder

  var config = new AutoMapper.MapperConfiguration(cfg =>
   {                 
       cfg.CreateMap<ClientCustomer, Models.Customer>();
   });

de mapper initialiseren
IMapper mapper = config.CreateMapper();

en voeg het mapper-object toe aan services als een singleton
services.AddSingleton(mapper);

op deze manier kan ik een DI toevoegen aan de controller

 private IMapper autoMapper = null;
  public VerifyController(IMapper mapper)
  {              
   autoMapper = mapper;  
  }

en ik heb gebruikt zoals hieronder in mijn actiemethoden

 ClientCustomer customerObj = autoMapper.Map<ClientCustomer>(customer);

Antwoord 12

Om toe te voegen aan wat Arve Systad noemde voor het testen. Als je om wat voor reden dan ook op mij lijkt en de overervingsstructuur van deutz-oplossing wilt behouden, kun je de MapperConfiguration als volgt instellen:

var mappingProfile = new MappingProfile();
var config = new MapperConfiguration(cfg =>
{
    cfg.AddProfile(mappingProfile);
});
var mapper = new Mapper(config);

Ik deed dit in NUnit.


Antwoord 13

In .NET 6 moet u het volgende toevoegen aan het bestand Program.cs:

builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

Antwoord 14

over het antwoord ,
het is niet nodig om de IMapper mapper-parameter op te geven bij de controllersconstructor.

u kunt de Mapper gebruiken omdat het een statisch lid is op elke plaats van de code.

public class UserController : Controller {
   public someMethod()
   {
      Mapper.Map<User, UserDto>(user);
   }
}

Other episodes