Коллекции объектов AutoMapper не отображаются - PullRequest
2 голосов
/ 22 марта 2012

Я пытаюсь сопоставить класс, который имеет макет, идентичный классу, которому я пытаюсь сопоставить. Все идет хорошо, кроме случаев, когда я пытаюсь отобразить коллекции объектов. Например, когда я пытаюсь отобразить это свойство, определенное в исходном классе:

[System.Xml.Serialization.XmlElementAttribute("trust", typeof(Trust))]
[System.Xml.Serialization.XmlElementAttribute("valuation", typeof(Valuation))]
[System.Xml.Serialization.XmlElementAttribute("waiver_of_premium_ind", typeof(YesNo))]
[System.Xml.Serialization.XmlElementAttribute("written_under_trust_ind", typeof(YesNo), IsNullable = true)]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")]
public object[] Items
{
    get { return this.itemsField; }
    set { this.itemsField = value; }
}

Я считаю, что он не отображается, но остается в том же пространстве имен, что и исходный объект, даже если он является коллекцией в целевом объекте.

Интересно, есть ли у вас идеи по этому поводу?

EDIT: Более подробная информация в качестве примера - исходный класс:

namespace Namespace1
{
public class Person
{
    public int PersonID { get; set; }
    public List<Arm> Arms { get; set; }

    [System.Xml.Serialization.XmlElementAttribute("_arms", typeof(Arm))]
    [System.Xml.Serialization.XmlElementAttribute("_hand", typeof(Hand))]
    public object[] Items { get; set; }
}

public class Arm
{
    public Hand Hand { get; set; }
}

public class Hand
{
    public int HandID { get; set; }
    public string HandSide { get; set; }
    public List<Fingers> Fingers { get; set; }
}

public class Fingers
{
    public int FingerNumber { get; set; }
}
}

Класс назначения:

namespace Namespace2
{
public class Person
{
    public int PersonID { get; set; }
    public List<Arm> Arms { get; set; }

    [System.Xml.Serialization.XmlElementAttribute("_arms", typeof(Arm))]
    [System.Xml.Serialization.XmlElementAttribute("_hand", typeof(Hand))]
    public object[] Items { get; set; }
}

public class Arm
{
    public Hand Hand { get; set; }
}

public class Hand
{
    public int HandID { get; set; }
    public string HandSide { get; set; }
    public List<Fingers> Fingers { get; set; }
}

public class Fingers
{
    public int FingerNumber { get; set; }
}
}

Код для сопоставления двух типов и всех вложенных типов в двух пространствах имен:

public static void CreateMappings(string nsFrom, string nsTo, Type typeFrom)
{
    Assembly assembly = Assembly.GetAssembly(typeFrom);
    var TypesInNamespace = assembly.GetTypes().Where(type => type.Namespace == nsFrom);
    foreach (var sourceType in TypesInNamespace)
    {
        Type destinationType = Type.GetType(sourceType.FullName.Replace(nsFrom, nsTo));
        Mapper.CreateMap(sourceType, destinationType);
    }
}

Затем я создаю свой объект person из Namespace1 и создаю сопоставления, используя приведенную выше функцию, например:

CreateMappings("Namespace1", "Namespace2", typeof(Namespace1.Person));

После этого я вызываю функцию карты следующим образом:

var result = Mapper.Map<Namespace2.Person>(person);

Это отображает все свойства класса Person просто отлично, КРОМЕ для массива объектов Items. Он передает объекты через, но они по-прежнему принадлежат пространству имен1 вместо пространства имен2.

Изображение проблемы из окна часов можно найти здесь

Вы можете скачать консольное приложение, если вам нравится здесь

Спасибо за любую помощь, которую вы можете оказать. M

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Я знаю, что это действительно старый, но я нашел ответ (по крайней мере, для последней версии AutoMapper (8.0 на момент ответа). Вам нужно написать пользовательский ITypeConverter для Person, который выполняет отображение объект [].

В моем случае у меня был такой объект (атрибуты xml удалены):

namespace bob {
    public class sally 
    {
        public bob.MyEnum[] SomeVarName {get;set;}
        public object[] SomeValueVar {get;set;}
    }
}

namespace martin {
    public class sally 
    {
        public martin.MyEnum[] SomeVarName {get;set;}
        public object[] SomeValueVar {get;set;}
    }
}

Конвертер пользовательских типов выглядел так:

public class LocationTypeResolver : ITypeConverter<bob.sally,martin.sally>
{
    public martin.sally Convert(bob.sally source, martin.sally destination, ResolutionContext context)
    {
        var retVal = new martin.sally
                     {
                         SomeValueVar = new object[source.SomeVarName.Length],
                         SomeVarName  = new martin.MyEnum[source.SomeVarName.Length]
                     };

        for (int i = 0; i < source.Items.Length; i++)
        {
            retVal.SomeVarName[i] = (martin.MyEnum)Enum.Parse(typeof(martin.MyEnum), source.SomeVarName[i].ToString());

            switch (source.ItemsElementName[i])
            {
                //map any custom types
                default:
                    retVal.SomeValueVar[i] = source.SomeValueVar[i]
            }
        }

        return retVal;
    }
}
0 голосов
/ 22 марта 2012

Я попробовал следующее, и, кажется, работает;

public class Tester
{
    public void Test()
    {
        AutoMapper.Mapper.CreateMap<FirstObject, SecondObject>();


        FirstObject t = new FirstObject();
        t.Items = new object[] { new Item() { Id = 1 }, new Item() { Id = 2 } };

        SecondObject result = AutoMapper.Mapper.Map<SecondObject>(t);
    }
}



public class FirstObject
{
    public object[] Items { get; set; }

}

public class SecondObject
{
    public object[] Items { get; set; }
}

public class Item
{
    public int Id { get; set; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...