繁体   English   中英

AutoMapper 从静态 API 迁移

[英]AutoMapper Migrating from static API

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

这个改变打破了我的系统。

在更新之前,我使用:

===> 启动.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>();
        ...
    }
}

错误:

'Mapper.CreateMap()' 已过时:'静态 API 将在 5.0 版中删除。 使用 MapperConfiguration 实例并根据需要静态存储。 使用 CreateMapper 创建映射器实例。

我可以使用 Mapper.Map。 现在我该如何使用它

代替:

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

来源有更多例子

而不是 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());

依赖注入给我的遗留项目增加了一个我不想处理的复杂程度。 由于使用许多不同的技术调用同一个库,Webforms、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);

Ben Walters:依赖注入给我的遗留项目增加了一层复杂性,我只是不想处理......

你好

此外,您可以应用类别名 using 语句,无需更改代码,只需更改 using 语句即可。

为类定义 using 指令和 using 别名: https : //docs.microsoft.com/zh-tw/dotnet/csharp/language-reference/keywords/using-directive#example-2

——

.你的类实现兼容性。

 namespace AutoMappers { public class Mapper { public static void Initialize(Action<AutoMapper.IMapperConfigurationExpression> config) { ... } } }

.将“使用 AutoMapper”更改为“使用 Mapper = AutoMappers.Mapper”。

 using Mapper = AutoMappers.Mapper; <-- using statement changed namespace ... { public class ... { public ...(...) { Mapper.Initialize(cfg => cfg.CreateMap<TSource1, TDestination1>()); <-- other code line kept originally

——

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM