Как настроить 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));
Я предположим (и я делаю ударение на этом слове), что из-за следующего выполнения параметров overaload (исходный код 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 маппер = конфиг.CreateMapper ();
и добавьте объект mapper в службы как одноэлементный сервисы.AddSingleton (картограф);
таким образом, я могу добавить DI в контроллер
private IMapper autoMapper = null;
public VerifyController(IMapper mapper)
{
autoMapper = mapper;
}
и я использовал как ниже в моих методах действий
ClientCustomer customerObj = autoMapper.Map<ClientCustomer>(customer);
об ответе theutz , нет необходимости указывать IMapper картографа parrameter в конструкторе контроллеров.
вы можете использовать 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);
Я сделал это в Нанит.