【问题标题】:Automapper - Pluggable mappingAutomapper - 可插拔映射
【发布时间】:2017-07-10 08:25:01
【问题描述】:

我需要实现一个可插入系统,其中 Automapper 配置文件可以由许多 DLL 提供。

要映射的对象有一个人员列表:

public class CompanySrc
{
    public List<PersonSrc> Persons {get;set;}
}

public class CompanyDest
{
    public List<PersonDest> Persons {get;set;}
}

PersonSrc 和 PersonDest 是可以在每个 DLL 中扩展的抽象类:

DLL1:

public class EmployeeSrc : PersonSrc
{
    ...
}


public class EmployeeDest : PersonDest
{
    ...
}

DLL2:

public class ManagerSrc : PersonSrc
{
    ...
}


public class ManagerDest : PersonDest
{
    ...
}

这个想法是实现类似的东西:

public class DLL1Profile : Profile
{
    public DLL1Profile()
    {
        CreateMap<PersonSrc, PersonDest>()
               .Include<EmployeeSrc, EmployeeDest>();
        CreateMap<EmployeeSrc, EmployeeDest>();
    }
}


public class DLL2Profile : Profile
{
    public DLL2Profile()
    {
        CreateMap<PersonSrc, PersonDest>()
                .Include<ManagerSrc, ManagerDest>();
        CreateMap<ManagerSrc, ManagerDest>();
    }
}

映射是通过以下方式完成的

var mc = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<CompanySrc, CompanyDest>()
                cfg.AddProfile(new DLL1Profile());
                cfg.AddProfile(new DLL2Profile ());
            });

            IMapper sut = mc.CreateMapper();
            var result = sut.Map<CompanyDest>(companySrc);

但这种方法不起作用。当“人员”列表包含员工和经理时,我尝试映射整个列表时出现异常。 有什么建议吗?

【问题讨论】:

  • 你的意思是因为多态性?所以你有一个包含People 的列表,其中一些列表可能是Manager,一些可能是Employee?如果是这种情况,那么应用您的Profile 之一会导致异常是有道理的,因为当列表包含两种类型时,它将尝试映射到Manager 或Employee...话虽如此,我认为 Automapper 不会映射 Dest 上不存在的道具,而不是抛出异常。也许问题缺少一些信息(即异常消息是什么?)
  • 我用更多信息编辑了这个问题。抛出的异常具有误导性,因为映射器似乎无法映射字段,但内部存在未设置的对象引用,因为自动映射器可能会尝试创建“Person”的实例,但由于它是抽象的,所以它不能。

标签: c# .net automapper automapper-5


【解决方案1】:

您看到此问题是因为您多次调用 CreateMap&lt;PersonSrc, PersonDest&gt;() - 只能存在一个映射。

在不同的 DLL 中扩展基类时,不要使用 .Include,而是使用 .IncludeBase。 Include 要求包含您的基类的配置文件能够引用派生类,这很可能不是您想要发生的。

您应该在某个共同的地方定义您的基本映射,大概是定义 Person 的地方:

CreateMap<PersonSrc, PersonDest>();

在您的 DLL1 配置文件等中,请改用 IncludeBase:

CreateMap<ManagerSrc, ManagerDest>()
    .IncludeBase<PersonSrc, PersonDest>();

【讨论】:

  • 感谢您的回答。在双重映射声明之后,如果我尝试使用 cm.AssertConfigurationIsValid(); 检查配置,则会收到双重配置导致的错误,但错误消息的文本包含使用 AllowAdditiveTypeMapCreation 的建议。如果我在双重映射之前将该属性设置为 true,则断言不会触发任何异常,但映射仍然无法正常工作。但是,我尝试以您的方式声明映射并且似乎工作正常。谢谢
猜你喜欢
  • 2022-01-26
  • 2014-06-30
  • 1970-01-01
  • 2020-07-17
  • 2012-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多