如何通用自动映射器配置

本文关键字:配置 映射 何通用 | 更新日期: 2023-09-27 18:33:36

我使用自动映射器版本4.2.0,我都Action Methods我有这样的设置:

  var attributeGroups = _attributeGroupService.AttributeGroupDropdown();
        var mapconfiguration = new MapperConfiguration(cfg => cfg.CreateMap<AttributeGroup, AttributeGroupViewModel>());
        var mapper = mapconfiguration.CreateMapper();
        var result = mapper.Map(attributeGroups, new List<AttributeGroupViewModel>());

不会在所有动作中重复这些代码,我想创建一个泛型方法,只是将数据传递给它并映射它,为此,我创建一个这样的方法?

 public N mapping<T,K,M,N>(T resource, K destination,M model,N newModel) 
    {
        var mapconfiguration = new MapperConfiguration(cfg => cfg.CreateMap<T, K>());
        var mapper = mapconfiguration.CreateMapper();
        var result = mapper.Map<M,N>(model, newModel);
        return result;
    }

并像这样称呼它:

var ResultTest=mapping<AttributeGroup,AttributeGroupViewModel,attributeGroups,new List<AttributeGroupViewModel>()>();

但它不合规.

我该怎么做?

如何通用自动映射器配置

简短回答:您需要在泛型参数列表中提供类型,在函数调用的参数列表中提供变量。此外,您根本不需要T resource, K destination参数,因为它们未使用。

您的方法还有另一个问题,因为使用它并不方便。因此,我建议您提供两种降低复杂性的专用方法。

请参阅下面的完整示例。它包含方法 mapAnything<...> ,这是一个工作等效于您的mapping<...>方法。mapObject<...>mapCollection<...>的方法就是我所说的专业方法。

class TestResource
{
    public int Testnumber { get; set; }
    public string Testtext { get; set; }
}
class TestDestination
{
    public string Testtext { get; set; }
}
class Program
{
    // equivalent to what you tried to do - needs explicit generic parameters on call
    static N mapAnything<T, K, M, N>(M model, N newModel)
    {
        var mapconfiguration = new MapperConfiguration(cfg => cfg.CreateMap<T, K>());
        var mapper = mapconfiguration.CreateMapper();
        var result = mapper.Map<M, N>(model, newModel);
        return result;
    }
    // variant for object mapping, where generics can be implicitely inferred
    static N mapObject<M, N>(M model, N newModel)
    {
        var mapconfiguration = new MapperConfiguration(cfg => cfg.CreateMap<M, N>());
        var mapper = mapconfiguration.CreateMapper();
        var result = mapper.Map<M, N>(model, newModel);
        return result;
    }
    // variant for lists, where generics can be implicitely inferred
    static ICollection<N> mapCollection<M, N>(IEnumerable<M> model, ICollection<N> newModel)
    {
        var mapconfiguration = new MapperConfiguration(cfg => cfg.CreateMap<M, N>());
        var mapper = mapconfiguration.CreateMapper();
        var result = mapper.Map<IEnumerable<M>, ICollection<N>>(model, newModel);
        return result;
    }
    static void Main(string[] args)
    {
        var res1 = new TestResource() { Testnumber = 1, Testtext = "a" };
        var res2 = new List<TestResource>();
        for (int i = 0; i < 10; i++)
        {
            res2.Add(new TestResource() { Testnumber = i, Testtext = "test: " + i });
        }
        var mapped1 = mapObject(res1, new TestDestination());
        var mapped2 = mapCollection(res2, new HashSet<TestDestination>());
        var mapped3 = mapAnything<TestResource, TestDestination, TestResource, TestDestination>(res1, new TestDestination());
        var mapped4 = mapAnything<TestResource, TestDestination, IEnumerable<TestResource>, List<TestDestination>>(res2, new List<TestDestination>());
    }
}