AutoMapper:将接口映射到抽象类 - 是否可能?

5

我正在使用AutoMapper来在我的应用程序的不同层之间映射对象。 一方面,我有一个接口,它看起来像这样:

public interface MyRepo 
{
    IEnumerable<IRootObject> GetItems(param);
}

IRootObject的样子如下:

public interface IRootObject
{
    int Id { get; set; }
    DateTime? Date { get; set; }
}

public interface IFirstSubObject : IRootObject 
{
    string MyFirstProp { get; set; }
}

public interface ISecondSubObject : IRootObject 
{
    string MySecondProp { get; set; }
}

因此,GetItems()调用实际上返回一个仅包含IxxxSubObjectItems的数组。另一方面,结构看起来像这样:

public abstract class MyCustomRoot
{
    protected MyCustomRoot(){}
    public int Id { get; set; }
    public DateTime? Date { get; set; }
}

public class MyCustomFirstSub : MyCustomRoot
{
    public MyCustomFirstSub() : base() {} 
    public string MyFirstProp { get; set; }
}

public class MyCustomSecondSub : MyCustomRoot
{
    public MyCustomSecondSub () : base() {} 
    public string MySecondProp { get; set; }
}

现在我已经设置了类似这样的映射器。
AutoMapper.Mapper.CreateMap<IRootObject, MyCustomRoot>
    .Include<IFirstSubObject, MyCustomFirstSub>
    .Include<ISecondSubObject, MyCustomSecondSub>();

AutoMapper.Mapper.CreateMap<IFirstSubObject, MyCustomFirstSub>();
AutoMapper.Mapper.CreateMap<ISecondSubObject, MyCustomSecondSub>();

但我一直收到 MapperExceptions(“无法构造抽象类”,在某种程度上说是有道理的)。我还调用 AssertConfigurationIsValid,对于这段代码来说,它是通过的。
如果我不将 MyCustomRoot 类设为抽象类,则映射可以工作,但我会得到一个 MyCustomRoot 对象列表,而实际上我想要的是 MyCustomxxxSub 的列表,因为稍后有一个工厂会使用这个类型生成正确的 UI...

希望有人能指导我正确的方向!
谢谢!

2个回答

8

我找到了一种实现这个的方法! 使用上面提供的接口和类,你可以像这样做:
(记住:MyCustomRoot类是抽象的)

AutoMapper.Mapper.CreateMap<IRootObject, MyCustomRoot>
    .Include<IFirstSubObject, MyCustomFirstSub>
    .Include<ISecondSubObject, MyCustomSecondSub>();

然后使用以下Map调用来映射对象:
public List<MyCustomRoot> PerformMapping(List<IRootObject> rootObjects)
{
    var returnList = new List<CustomRoot>();
    foreach(var rootObject in rootObjects)
    {
        var abstractObject = (MyCustomRoot)Mapper.Map(rootObject, rootObject.GetType(), typeof(MyCustomRoot));
        returnList.Add(abstractObject);
    }
    return returnList;
}

现在我实际上得到了一个MyCustomRoot对象数组,它们都是具体的实现。这正是我所期望的!

2
你能更具体地说明它与你问题中的代码有何不同吗?我尝试了这个方法,但仍然出现“无法创建抽象类”的异常... - guillaume31
好的,看起来版本4.x不起作用,但3.2可以。很奇怪。 - guillaume31

0
如果是这样,那么你想要映射到该工厂,注入它并让它在适当的时间创建正确的实例,因为显然是工厂知道要实例化什么。

不是很准确。工厂在另一层中,它的输入是抽象的 MyCustomRoot 对象。无论如何,感谢您的帮助! - RoelF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接