Подтвердить что ты не робот

AutoMapper Миграция из статического API

https://github.com/AutoMapper/AutoMapper/wiki/Migrating-from-static-API

это изменение разбивает мою систему.

Перед обновлением я использую:

=== > Startup.cs

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
    ...
        MyAutoMapperConfiguration.Configure();
    }
}

=== > MyAutoMapperConfiguration.cs

public class MyAutoMapperConfiguration
{
    public static void Configure()
    {
        Mapper.Initialize(a =>
        {
            a.AddProfile<AbcMappingProfile>();
            a.AddProfile<XyzMappingProfile>();
            a.AddProfile<QweMappingProfile>();
        });
    }
}

=== > AbcMappingProfile.cs

public class AbcMappingProfile : Profile
{
    protected override void Configure()
    {
        Mapper.CreateMap<AbcEditViewModel, Abc>();
        Mapper.CreateMap<Abc, AbcEditViewModel>();
        ...
    }
}

ERROR:

'Mapper.CreateMap()' устарел: 'Статический API будет удален в версии 5.0. Используйте экземпляр MapperConfiguration и статически статируйте по мере необходимости. Используйте CreateMapper для создания инсталлятора mapper. '

Я могу использовать Mapper.Map. Теперь, как я могу использовать его

4b9b3361

Ответ 1

Вместо:

Mapper.CreateMap<AbcEditViewModel, Abc>();

Новый синтаксис:

var config = new MapperConfiguration(cfg => {
  cfg.CreateMap<AbcEditViewModel, Abc>();
});

Тогда:

IMapper mapper = config.CreateMapper();
var source = new AbcEditViewModel();
var dest = mapper.Map<AbcEditViewModel, Abct>(source);

(Источник с большим количеством примеров)

Ответ 2

Вместо профиля Automapper Profile используйте расширение IMapperConfigurationExpression:

Конфигурация отображения:

public static class AutoMapperConfig
{
    public static IMapperConfigurationExpression AddAdminMapping(
        this IMapperConfigurationExpression configurationExpression)
    {
        configurationExpression.CreateMap<Job, JobRow>()
            .ForMember(x => x.StartedOnDateTime, o => o.PreCondition(p => p.StartedOnDateTimeUtc.HasValue))
            .ForMember(x => x.StartedOnDateTime, o => o.MapFrom(p => p.StartedOnDateTimeUtc.Value.DateTime.ToLocalTime()))
            .ForMember(x => x.FinishedOnDateTime, o => o.PreCondition(p => p.FinishedOnDateTimeUtc.HasValue))
            .ForMember(x => x.FinishedOnDateTime, o => o.MapFrom(p => p.FinishedOnDateTimeUtc.Value.DateTime.ToLocalTime()));

        return configurationExpression;
    }
}

Интеграция (Startup.cs и т.д.):

        var mappingConfig = new AutoMapper.MapperConfiguration(cfg =>
        {
            cfg.AddAdminMapping();
        });

        services.AddSingleton(x => mappingConfig.CreateMapper());

Ответ 3

Внедрение зависимостей добавило целый уровень сложности моему устаревшему проекту, с которым я просто не хотел иметь дело. Поскольку одна и та же библиотека вызывается с использованием различных технологий, веб-форм, MVC, службы Azure и т.д....

Также внедрение зависимостей заставило бы меня переписать несколько методов или передать IMapper.

Поэтому я просто пересмотрел то, что делал в 8.0, и написал для него оболочку.

public static class MapperWrapper 
{
    private const string InvalidOperationMessage = "Mapper not initialized. Call Initialize with appropriate configuration. If you are trying to use mapper instances through a container or otherwise, make sure you do not have any calls to the static Mapper.Map methods, and if you're using ProjectTo or UseAsDataSource extension methods, make sure you pass in the appropriate IConfigurationProvider instance.";
    private const string AlreadyInitialized = "Mapper already initialized. You must call Initialize once per application domain/process.";

    private static IConfigurationProvider _configuration;
    private static IMapper _instance;

    private static IConfigurationProvider Configuration
    {
        get => _configuration ?? throw new InvalidOperationException(InvalidOperationMessage);
        set => _configuration = (_configuration == null) ? value : throw new InvalidOperationException(AlreadyInitialized);
    }

    public static IMapper Mapper
    {
        get => _instance ?? throw new InvalidOperationException(InvalidOperationMessage);
        private set => _instance = value;
    }

    public static void Initialize(Action<IMapperConfigurationExpression> config)
    {
        Initialize(new MapperConfiguration(config));
    }

    public static void Initialize(MapperConfiguration config)
    {
        Configuration = config;
        Mapper = Configuration.CreateMapper();
    }

    public static void AssertConfigurationIsValid() => Configuration.AssertConfigurationIsValid();
}

Инициализируйте его так же, как в предыдущих версиях

public static class AutoMapperConfig
{
    public static void Configure()
    {
        MapperWrapper.Initialize(cfg =>
        {
            cfg.CreateMap<Foo1, Foo2>();              
        });

        MapperWrapper.AssertConfigurationIsValid();
    }
}

И просто позвоните в свой стартап (Global.asax и т.д.)

AutoMapperConfig.Configure();

Тогда все, что вам нужно сделать, это добавить MapperWrapper перед всеми вашими статическими вызовами. И все работает как раньше.

 MapperWrapper.Mapper.Map<Foo2>(Foo1);