Allow mapping of dynamic types using AutoMapper or similar?

前端 未结 4 1121
攒了一身酷
攒了一身酷 2020-12-02 05:46

I\'ve started to use https://github.com/robconery/massive for a project, I wonder if there is any mapping tool that allows support for Dynamic to static type mapping?

相关标签:
4条回答
  • 2020-12-02 06:07

    Try Slapper.AutoMapper https://github.com/randyburden/Slapper.AutoMapper

    Slapper.AutoMapper maps dynamic data to static types

    It works for both dynamic and Dictionary<A, B> which is awesome.

    Here's an example (taken from the URL above) showing how easily it works with Dictionary:

    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" );
    }
    
    0 讨论(0)
  • 2020-12-02 06:23

    Assuming framework you use returns ExpandoObject you can achieve some sort of dynamic mapping using 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);
    

    You can create any sort of complex mapping using ConstructUsing methods..

    0 讨论(0)
  • 2020-12-02 06:24

    AutoMapper 4.2.0 now supports Dynamic/expando/dictionary mapping

    With this feature you can map to your expando objects to static types:

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

    Old versions of AutoMapper do not support this (Massive internally uses ExpandoObject which doesn't provide which properties it has), and you are right Mapper.DynamicMap is for mapping without creating mapping configuration.

    Actually it's not hard to write yourself a mapper if you just want simple mapping:

    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);
    
    0 讨论(0)
  • 2020-12-02 06:25

    Single object:

    Mapper.Map<Product>(dynamicProduct);
    

    List:

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

    Example (line 71): https://github.com/AutoMapper/AutoMapper/blob/master/src/UnitTests/DynamicMapping.cs

    0 讨论(0)
提交回复
热议问题