我有2个对象, BusinessCustomer 和 ORMCustomer
我希望能够在我的业务层活动中将一个映射到另一个,例如
在我的业务层中,我希望能够像:
Mapper.MapCustomer( src , target )
然后,MapCustomer方法可以决定映射的方向 BusinessCustomer-> ORMCustomer 或 ORMCustomer-> BusinessCustomer
我一直在修补Generics,但我似乎无法找到一个合适的解决方案,如何在 Mapper 类中实现它。
internal void MapCustomer<T, K>(T src, K target)
{
if (src.GetType() == typeof(BusinessCustomer))
{
MapBusinessCustomerToORMCustomer(src, target);
}
else if (src.GetType() == typeof(ORMCustomer))
{
MapORMCustomerToBusinessCustomer(src, target);
}
}
有关如何最好地实现这一点的想法吗?
答案 0 :(得分:1)
这是我为这样的任务写的简单的事情。属性名称必须相同。
public static class TypeConverter
{
/// <summary>
/// Instantiates a new DestinationType copying all public properties with the same type and name from the SourceType.
/// The destination object must have a parameter less constructor.
/// </summary>
/// <param name="sourceObject">The source object.</param>
/// <param name="destinationType">Type of the destination object.</param>
public static DestinationType Convert<SourceType, DestinationType>(SourceType sourceObject, Type destinationType)
{
if (destinationType.GetConstructors().Where(x => x.GetParameters().Count() == 0).Count() == 0)
throw new Exception("A parameter less constructor is required for the destination type.");
// instantiate the destination object
DestinationType destinationObject = Activator.CreateInstance<DestinationType>();
// get all public properties from the source and destination object
IEnumerable<PropertyInfo> sourceProps = sourceObject.GetType().GetProperties().Where(x => x.PropertyType.IsPublic);
IEnumerable<PropertyInfo> destinationProps = destinationType.GetProperties().Where(x => x.PropertyType.IsPublic || x.PropertyType.IsEnum);
// copy the public properties that exist in both the source type and destination type
foreach (PropertyInfo prop in destinationProps)
{
PropertyInfo sourceProp = sourceProps.SingleOrDefault(x => x.Name == prop.Name);
if (sourceProp != null)
{
try
{
object propValue = new object();
if (prop.PropertyType.IsEnum)
{
propValue = Enum.Parse(prop.PropertyType, sourceProp.GetValue(sourceObject, null).ToString());
}
else
{
propValue = System.Convert.ChangeType(sourceProp.GetValue(sourceObject, null), prop.PropertyType);
}
prop.SetValue(destinationObject, propValue, null);
}
catch { }
}
}
return destinationObject;
}
/// <summary>
/// Instantiates a new DestinationType copying all public properties with the same type and name from the SourceType.
/// The destination object must have a parameter less constructor.
/// </summary>
/// <param name="sourceObject">The collection of source objects.</param>
/// <param name="destinationType">Type of the destination object.</param>
public static IEnumerable<DestinationType> Convert<SourceType, DestinationType>(IEnumerable<SourceType> sourceObjects, Type destinationType)
{
List<DestinationType> convertedObjecs = new List<DestinationType>();
List<SourceType> sourceObjectList = sourceObjects.ToList();
foreach (SourceType item in sourceObjectList)
convertedObjecs.Add(Convert<SourceType, DestinationType>(item, destinationType));
return convertedObjecs;
}
}
答案 1 :(得分:1)
您无需重新发明轮子。 AutoMapper这样做。
答案 2 :(得分:0)
我过去曾经用过这个。它很简单,非常快,因为它只反映一次类型,然后发出从那一点开始使用的get / set代码。