Как настроить Automapper в ASP.NET Керн

Я относительно новичок в .NET, и я решил заняться .NET Core вместо того, чтобы изучать "старые способы". Я нашел подробную статью о настройка AutoMapper для .NET Core здесь, но есть ли более простое пошаговое руководство для новичка?

7 ответов


Я все понял! Вот подробности:

  1. добавьте основной пакет AutoMapper в свое решение через NuGet для.
  2. добавьте пакет инъекций зависимостей AutoMapper в свое решение через NuGet.

  3. создайте новый класс для профиля сопоставления. (Я сделал класс в главном каталоге решений под названием 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>();
        }
    }
    
  4. затем добавьте 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();
    
    }
    
  5. чтобы вызвать сопоставленный объект в коде, сделайте что-то вроде следующего:

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

Я сделал это в Нанит.