在调用Initialize后,如何在AutoMapper中添加映射?

时间:2016-08-21 23:40:18

标签: automapper

我有几个共享映射代码的ASP.Net应用程序,所以我创建了一个通用的自动化初始化类。

但是,在我的一个应用程序中,我有一些特定的类要添加到配置中。

我有以下代码:

public class AutoMapperMappings
{
    public static void Init()
    {
        AutoMapper.Mapper.Initialize(cfg =>
        {
            ... A whole bunch of mappings here ...
        }
    }
}

// Call into the global mapping class
AutoMapperMappings.Init();

// This erases everything
AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<CustomerModel, CustomerInfoModel>());

如何在不破坏已初始化的内容的情况下添加此唯一映射?

5 个答案:

答案 0 :(得分:9)

一个快速示例,允许您多次初始化AutoMapper 5.x ... 好吧,这不是很好;)

public static class MapperInitializer
{
    /// <summary>
    /// Initialize mapper
    /// </summary>
    public static void Init()
    {
        // Static mapper
        Mapper.Initialize(Configuration);

        // ...Or instance mapper
        var mapperConfiguration = new MapperConfiguration(Configuration);
        var mapper = mapperConfiguration.CreateMapper();
        // ...
    }

    /// <summary>
    /// Mapper configuration
    /// </summary>
    public static MapperConfigurationExpression Configuration { get; } = new MapperConfigurationExpression();
}

// First config 
MapperInitializer.Configuration.CreateMap(...);
MapperInitializer.Init(); // or not

//...
MapperInitializer.Configuration.CreateMap(...);
MapperInitializer.Init();

我们的想法是存储MapperConfigurationExpression而不是MapperConfiguration实例。

答案 1 :(得分:2)

如果您使用AutoMapper提供的实例API而不是静态API,则应该可以这样做。 This wiki page详细说明了两者之间的差异。

基本上不是再次调用AutoMapper.Mapper.Initialize(cfg => ...)来进行额外的映射,而是使用该单一映射覆盖整个全局映射器配置,您需要使用实例API创建另一个映射器对象:

var config = new MapperConfiguration(cfg =>
    cfg.CreateMap<CustomerModel, CustomerInfoModel>()
);
var mapper = config.CreateMapper();

当然,为了使用这个新的映射器,在使用附加映射配置映射对象时,必须特别执行var mappedModel = mapper.Map<CustomerInfoModel>(new CustomerModel());之类的操作。在你的情况下,这是否实用,我不知道,但我相信这是你做所需的唯一方法。

答案 2 :(得分:1)

你不能,但是你可以让它返回一个可以在Mapper.Initialize()调用中调用的函数,而不是从你的Init方法初始化Mappings。

因此,您的Init方法如下所示:

public static Action<IMapperConfigurationExpression> Init()
{
    return (cfg) => {
        ... A whole bunch of mappings here ...
    };
}

然后从您想要额外映射的应用中获取:

var mappingsFunc = MyClass.Init();

Mapper.Initialize((cfg) => {
    mappingsFunc(cfg);
    ... Extra mappings here ...
});

或者你可以减少一点......

Mapper.Initialize((cfg) => {
    MyClass.Init()(cfg);
    ... Extra mappings here ...
});

希望这有帮助。

答案 3 :(得分:0)

Automapper 5 +

我的主程序集中有一个初始化类

    public static class Mapping
{
    public static void Initialize()
    {
        // Or marker types for assemblies:
        Mapper.Initialize(cfg =>
            cfg.AddProfiles(new[] {
                typeof(MapperFromImportedAssemblyA),
                typeof(MapperFromImportedAssemblyB),
                typeof(MapperFromImportedAssemblyC)
            })
            );
    }
}

然后在每个需要Mapper的程序集中

public class MapperFromImportedAssemblyA : Profile
{
    public MapperFromImportedAssemblyA()
    {
        // Use CreateMap here (Profile methods are the same as configuration methods)
    }
}

答案 4 :(得分:0)

这是我为自己的要求而奋斗的东西。

实际配置器

public static void Configure(params Action<MapperConfigurationExpression>[] registerCallbacks)
{
        MapperConfigurationExpression configuration = new MapperConfigurationExpression();

        foreach (Action<MapperConfigurationExpression> regCallBack in registerCallbacks)
        {
            regCallBack.Invoke(configuration);
        }

        AutoMapper.Mapper.Initialize(configuration);
}

映射组1

public class AutoMapperConfigSet1
{
    public static void RegisterTypes(MapperConfigurationExpression configuration)
    {
         configuration.CreateMap<Foo, Bar>();
    }
}

映射组2

public class AutoMapperConfigSet2
{
    public static void RegisterTypes(MapperConfigurationExpression configuration)
    {
         configuration.CreateMap<Foo1, Bar1>();
    }
}

初始化时

Configure(AutoMapperConfigSet1.RegisterTypes,AutoMapperConfigSet2.RegisterTypes);