允许使用AutoMapper或类似的动态类型的映射?允许使用AutoMapper或类似的动态类型的映

2019-05-13 10:16发布

我已经开始使用https://github.com/robconery/massive一个项目,我不知道是否有任何映射工具,允许动态支持静态类型映射?

我使用AutoMapper之前,不AutoMapper支持呢?

我知道从AutoMapper的DynamicMap功能的,但是我相信这个功能是用于运行图不首先创建地图。 在我下面的例子这是行不通的。

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

Answer 1:

AutoMapper 4.2.0现在支持动态/的expando /字典映射

有了这个功能,您可以映射到你的expando对象的静态类型:

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

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

AutoMapper的旧版本不支持这个(大规模内部使用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);


Answer 2:

尝试Slapper.AutoMapper https://github.com/randyburden/Slapper.AutoMapper

Slapper.AutoMapper映射动态数据静态类型

它适用于两个dynamicDictionary<A, B>这是真棒。

这里有一个例子展示它是如何工作的轻松与词典(从上面的网址采取的):

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" );
}


Answer 3:

假设你使用的回报框架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方法..



Answer 4:

单个对象:

Mapper.Map<Product>(dynamicProduct);

列表:

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

实施例(线71): https://github.com/AutoMapper/AutoMapper/blob/master/src/UnitTests/DynamicMapping.cs



文章来源: Allow mapping of dynamic types using AutoMapper or similar?