我已经开始在项目中使用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
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 不支持此功能(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);
尝试Slapper.AutoMapperhttps://github.com/randyburden/Slapper.AutoMapper
Slapper.AutoMapper 将动态数据映射到静态类型
它适用于
dynamic
和 Dictionary<A, B>
,这太棒了。
这里有一个示例(取自上面的 URL),展示了它与 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" );
}
假设您使用的框架返回
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
方法创建任何类型的复杂映射..
单个对象:
Mapper.Map<Product>(dynamicProduct);
列表:
Mapper.Map<List<Product>>(dynamicListOfProducts);
示例(第 71 行):https://github.com/AutoMapper/AutoMapper/blob/master/src/UnitTests/DynamicMapping.cs