Разрешить отображение динамических типов с использованием AutoMapper или аналогичного? - PullRequest
41 голосов
/ 15 октября 2011

Я начал использовать https://github.com/robconery/massive для проекта. Интересно, есть ли какой-нибудь инструмент сопоставления, который позволяет поддерживать динамическое сопоставление со статическим типом?

Ранее я использовал AutoMapper, поддерживает ли AutoMapper это?

Мне известна функция DynamicMap из AutoMapper, однако я считаю, что эта функция предназначена для запуска карт без предварительного создания карты.В моем примере ниже это не работает.

dynamic curUser = users.GetSingleUser(UserID);   
var retUser = Mapper.DynamicMap<UserModel>(curUser);
users.GetSingleUser(UserID); // returns a dynamic object

Ответы [ 4 ]

66 голосов
/ 15 октября 2011

AutoMapper 4.2.0 теперь поддерживает Динамическое / расширение / отображение словаря

С помощью этой функции вы можете отобразить ваши объекты расширения настатические типы:

dynamic CurUser = _users.GetSingleUser(UserID);   
var config = new MapperConfiguration(cfg => { });
var mapper = config.CreateMapper();

var retUser = mapper.Map<UserModel>(CurUser);

Старые версии AutoMapper не поддерживают это (Massive внутренне использует ExpandoObject, который не предоставляет какие свойства он имеет), и вы правы Mapper.DynamicMap для отображения без созданиякартографическая конфигурация.

На самом деле не сложно написать себе маппер, если вы просто хотите простое картирование:

public static class DynamicToStatic
{
    public static T ToStatic<T>(object expando)
    {
        var entity = Activator.CreateInstance<T>();

        //ExpandoObject implements dictionary
        var properties = expando as IDictionary<string, object>; 

        if (properties == null)
            return entity;

        foreach (var entry in properties)
        {
            var propertyInfo = entity.GetType().GetProperty(entry.Key);
            if(propertyInfo!=null)
                propertyInfo.SetValue(entity, entry.Value, null);
        }
        return entity;
    }
}

dynamic CurUser = _users.GetSingleUser(UserID);   
var retUser = DynamicToStatic.ToStatic<UserModel>(CurUser);
17 голосов
/ 06 марта 2013

Попробуйте Slapper.AutoMapper https://github.com/randyburden/Slapper.AutoMapper

Slapper.AutoMapper отображает динамические данные в статические типы

Работает как для dynamic, так и для Dictionary<A, B>, что потрясающе.

Вот пример (взятый из URL выше), показывающий, как легко он работает со словарем:

public class Person
{
    public int Id;
    public string FirstName;
    public string LastName;
}

[Test]
public void CanMapMatchingFieldNamesWithEase()
{
    // Arrange
    var dictionary = new Dictionary<string, object>
                            {
                                { "Id", 1 },
                                { "FirstName", "Clark" },
                                { "LastName", "Kent" }
                            };

    // Act
    var person = Slapper.AutoMapper.Map<Person>( dictionary );

    // Assert
    Assert.NotNull( person );
    Assert.That( person.Id == 1 );
    Assert.That( person.FirstName == "Clark" );
    Assert.That( person.LastName == "Kent" );
}
3 голосов
/ 03 июля 2015

Предполагая, что используемая вами структура возвращает ExpandoObject, вы можете добиться некоторого динамического отображения с помощью AutoMapper:

Mapper.CreateMap<ExpandoObject, UserModel>()
    .ForAllMembers((options) => options.ResolveUsing((resolution) =>
        {
            var dictionary =  (IDictionary<string, object>) resolution.Context.SourceValue;
            return dictionary[resolution.Context.MemberName];
        }));
...
dynamic CurUser = _users.GetSingleUser(UserID);   
var retUser = Mapper.Map<UserModel>(CurUser);

Вы можете создать любой вид сложного отображения, используя ConstructUsing методы ..

0 голосов
/ 30 января 2018

Один объект:

Mapper.Map<Product>(dynamicProduct);

Список:

Mapper.Map<List<Product>>(dynamicListOfProducts);

Пример (строка 71): https://github.com/AutoMapper/AutoMapper/blob/master/src/UnitTests/DynamicMapping.cs

...