AutoMapper: сопоставить интерфейс с абстрактным классом - возможно ли это? - PullRequest
5 голосов
/ 07 апреля 2011

Я использую 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, потому что позже есть Фабрика, которая использует этот тип для генерации правильного интерфейса ...

Я надеюсь, что кто-то может указать мне правильное направление для этого!
Спасибо!

Ответы [ 2 ]

7 голосов
/ 08 апреля 2011

Хорошо, я нашел способ сделать это!Таким образом, с помощью интерфейсов и классов, представленных выше, вы можете сделать что-то вроде
(помните: класс MyCustomRoot является абстрактным)

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

, а затем использовать вызов Map followig для отображения объектов:

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 объектов, которые представляют собой все конкретные реализации.

Это именно то, что я искал!

0 голосов
/ 07 апреля 2011

Если это так, то вы хотите отобразить на эту фабрику, внедрить ее и позволить ей в нужное время создать правильный экземпляр, поскольку именно фабрика, очевидно, знает, что нужно создать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...