Как настроить Automapper в ASP.NET Керн
Я относительно новичок в .NET, и я решил заняться .NET Core вместо изучения "старых способов". Я нашел подробную статью о настройка AutoMapper для .NET Core здесь, но есть ли более простое пошаговое руководство для новичка?
7 ответов:
Я все понял! Вот подробности:
- добавьте основной пакет AutoMapper в свое решение через NuGet.
добавьте пакет инъекций зависимостей AutoMapper в свое решение через NuGet.
создайте новый класс для профиля сопоставления. (Я сделал класс в главном каталоге решения под названием
MappingProfile.csи добавьте следующий код.) Я буду использоватьUserиUserDtoобъект как образец.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>(); } }затем добавьте AutoMapperConfiguration в
Startup.csкак показано ниже:public void ConfigureServices(IServiceCollection services) { // .... Ignore code before this // Auto Mapper Configurations var mappingConfig = new MapperConfiguration(mc => { mc.AddProfile(new MappingProfile()); }); IMapper mapper = mappingConfig.CreateMapper(); services.AddSingleton(mapper); services.AddMvc(); }чтобы вызвать сопоставленный объект в коде, сделайте что-то вроде следующего:
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! } }Я надеюсь, что это поможет кому-то начать все заново ASP.NET ядро! Я приветствую любые отзывы или критику, поскольку я все еще новичок в мире .NET!
ответ theutz здесь очень хорош, я просто хочу добавить это:
Если вы позволите своему профилю отображения наследовать от
MapperConfigurationExpressionвместоProfile, вы можете очень просто добавить тест для проверки настройки отображения, что всегда удобно:[Fact] public void MappingProfile_VerifyMappings() { var mappingProfile = new MappingProfile(); var config = new MapperConfiguration(mappingProfile); var mapper = new Mapper(config); (mapper as IMapper).ConfigurationProvider.AssertConfigurationIsValid(); }
Я хочу расширить ответы @theutz-а именно эту строку:
// services.AddAutoMapper(typeof(Startup)); // <-- newer automapper version uses this signature.есть баг (наверное) в AutoMapper.Увеличение.Microsoft.DependencyInjection версии 3.2.0. (Я использую .NET Core 2.0)
это решается в этой проблема GitHub. Если ваши классы, наследующие класс профиля AutoMapper, существуют вне сборки, где вы запускаете класс, они, вероятно, не будут зарегистрированы, если ваша инъекция AutoMapper выглядит так это:
services.AddAutoMapper();если вы явно не укажете, какие сборки для поиска профилей AutoMapper.
Это можно сделать так в вашем запуске.ConfigureServices:
services.AddAutoMapper(<assembies> or <type_in_assemblies>);здесь "сборок" и "type_in_assemblies" укажите сборку, в которой указаны классы профилей в вашем приложении. Например:
services.AddAutoMapper(typeof(ProfileInOtherAssembly), typeof(ProfileInYetAnotherAssembly));Я предположим (и я сделал акцент на этом слове), что из-за следующего реализация параметрической перегрузки (исходный код от GitHub):
public static IServiceCollection AddAutoMapper(this IServiceCollection services) { return services.AddAutoMapper(null, AppDomain.CurrentDomain.GetAssemblies()); }мы полагаемся на то, что CLR уже имеет JITed сборку, содержащую профили AutoMapper, которые могут быть или не быть истинными, поскольку они только jitted при необходимости (больше deatils в этой и StackOverflow вопрос).
Я использую AutoMapper 6.1.1 и asp.net ядро 1.1.2. В первую очередь определить профиль класса наследуется класс профиль Automapper. Я создал интерфейс IProfile, который пуст, цель состоит только в том, чтобы найти классы этого типа
public class UserProfile : Profile, IProfile { public UserProfile() { CreateMap<User, UserModel>(); CreateMap<UserModel, User>(); } } Now Create a seperate class e.g 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 }); } } } }сейчас в MVC веб-проекта в стартап.cs файл, в конструкторе вызовите класс сопоставления, который инициализирует все сопоставления во время применения загрузка
Mappings.RegisterMappings();
услуги.AddAutoMapper (); не работает для меня. (Я использую Asp.Net Core 2.0)
после настройки, как показано ниже
var config = new AutoMapper.MapperConfiguration(cfg => { cfg.CreateMap<ClientCustomer, Models.Customer>(); });инициализировать маппера IMapper mapper = config.CreateMapper ();
и добавить объект mapper к сервисам в качестве синглтона сервисы.AddSingleton (mapper);
таким образом, я могу добавить DI к контроллеру
private IMapper autoMapper = null; public VerifyController(IMapper mapper) { autoMapper = mapper; }и я использовал как ниже в моих методах действий
ClientCustomer customerObj = autoMapper.Map<ClientCustomer>(customer);
об ответе theutz , нет необходимости указывать IMapper mapper парраметр в конструкторе контроллеров.
вы можете использовать Mapper как статический элемент в любом месте кода.
public class UserController : Controller { public someMethod() { Mapper.Map<User, UserDto>(user); } }
чтобы добавить к тому, что Arve Systad упомянул для тестирования. Если по какой-либо причине вы похожи на меня и хотите сохранить структуру наследования, представленную в решении theutz, вы можете настроить конфигурацию MapperConfiguration следующим образом:
var mappingProfile = new MappingProfile(); var config = new MapperConfiguration(cfg => { cfg.AddProfile(mappingProfile); }); var mapper = new Mapper(config);Я сделал это в Нанит.
Comments