如何使用AutoMapper 映射以下类,而不显式指示所有成员映射:
onError
上课:
public class Source
{
public string FirstName { get; set; }
public string LastName { get; set; }
... (huge amount of other properties)
}
使用翻译课程:
public class Destination
{
public string Imie { get; set; }
public string Nazwisko { get; set; }
... (huge amount of other properties)
}
答案 0 :(得分:2)
以下是如何做到这一点。
考虑以下方法:
public void CreateMapBasedOnDictionary<TSource, TDestination>(IDictionary<string, string> mapping_dictionary)
{
var mapping_expression = AutoMapper.Mapper.CreateMap<TSource, TDestination>();
foreach (var kvp in mapping_dictionary)
{
string source_property_name = kvp.Key;
string destination_property_name = kvp.Value;
Type member_type = typeof (TSource).GetProperty(source_property_name).PropertyType;
mapping_expression = mapping_expression.ForMember(destination_property_name, x =>
{
typeof (IMemberConfigurationExpression<TSource>)
.GetMethod("MapFrom", new []{typeof(string)})
.MakeGenericMethod(member_type)
.Invoke(x, new[] { source_property_name });
});
}
}
然后你可以像这样使用它:
var translations = new Dictionary<string, string>()
{
{"FirstName", "Imie"},
{"LastName", "Nazwisko"},
};
CreateMapBasedOnDictionary<Source, Destination>(translations);
Source src = new Source()
{
FirstName = "My first name",
LastName = "My last name"
};
var dst = AutoMapper.Mapper.Map<Destination>(src);
以下是CreateMapBasedOnDictionary
方法的解释:
AutoMapper已经超载ForMember
,允许您按名称指定目标属性。我们在这里很好。
它还具有MapFrom
的重载,允许您按名称指定源属性。但是,此重载的问题是它需要属性类型的通用参数(TMember
)。
我们可以通过使用反射来获取属性的类型,然后使用适当的MapFrom
类型参数动态调用TMember
方法来解决此问题。
答案 1 :(得分:0)
一种方法是使用Reflection:
$scope.showModal = function(param) {
ngDialog.open({
template: 'app/biography/bioModal' + param + ".html",
className: 'ngdialog-theme-plain',
showClose: true,
scope: $scope
});
};
你会这样称呼:
private TDestination Map<TSource, TDestination>(TSource source, Dictionary<string, string> mapData)
where TSource : class
where TDestination : class, new()
{
if (source == null) return null;
if (mapData == null) mapData = new Dictionary<string, string>();
TDestination destination = new TDestination();
PropertyInfo[] sourceProperties = typeof(TSource).GetProperties();
foreach (PropertyInfo property in sourceProperties)
{
string destPropertyName = mapData.ContainsKey(property.Name) ? mapData[property.Name] : property.Name;
PropertyInfo destProperty = typeof(TDestination).GetProperty(destPropertyName);
if (destProperty == null) continue;
destProperty.SetValue(destination, property.GetValue(source));
}
return destination;
}
答案 2 :(得分:0)
感谢@ yacoub-massad回答,我已经提出了这个解决方案:
var map = Mapper.CreateMap<Source, Destination>();
var sourceProperties = typeof(Source).GetProperties();
foreach (var sourceProperty in sourceProperties)
{
var sourcePropertyName = sourceProperty.Name;
var destinationPropertyName = translations[sourceProperty.Name];
map.ForMember(destinationPropertyName, mo => mo.MapFrom<string>(sourcePropertyName));
}
var src = new Source() { FirstName = "Maciej", LastName = "Lis" };
var dest = Mapper.DynamicMap<Destination>(src);