我想知道是否有人可以推荐一种可以在.NET2.0中使用的Automapper替代方案。
我有一个dll描述了一个相当复杂的结构。 dll位于webservice的两端,但是当通过webservice检索数据时,命名空间会阻止对象的直接映射,因此我不得不求助于编写映射类。
我合并了Automapper,它完全符合我的要求,但它不适用于.NET2.0。我需要使用.NET2.0,因为有几百台远程机器将运行客户端软件,它们仅限于.NET2.0。
任何帮助都将不胜感激。
答案 0 :(得分:1)
由于这是2.0,我猜这是一个基于wsdl的常规Web服务,通过XmlSerializer
工作(与WCF默认使用DataContractSerializer
不同)。如果是这种情况,那么应该能够使用XmlSerializer
两次:
FromType fromObj = ...;
ToType toObj;
using(var ms = new MemoryStream())
{
new XmlSerializer(typeof(FromType)).Serialize(ms, fromObj);
ms.Position = 0;
toObj = (ToType) new XmlSerializer(typeof(ToType)).Deserialize(ms);
}
也许并不理想,但只要类型兼容,它就应该有效。
令人沮丧的是,WCF工具内置了对重用现有类型定义的支持,以避免像这样重复。但显然是3.0。
答案 1 :(得分:0)
根据结构复杂性,可以使用反射来获取第一个对象的属性列表,并将相关值设置为具有相同名称的第二个对象属性。
如果您的结构只有简单的属性,那么效率会很高。
答案 2 :(得分:0)
在这种情况下,反射是你最好的朋友。
以下是属性复印机的粗略实现。您只需要新建一个目标类型的实例,并将其与设置了所有属性值的源实例一起传递给它。
编辑:正如Marc所说,这只会在简单的属性映射方面发挥作用。拿一粒盐。
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace StackOverflow
{
public static class ReflectionHelper
{
public static void CopyPropertyValues(object source, object target)
{
if (source == null) throw new ArgumentNullException("source");
if (target == null) throw new ArgumentNullException("target");
var sourceType = source.GetType();
var targetType = target.GetType();
var sourceProperties = sourceType.GetProperties();
foreach (var sourceProperty in sourceProperties)
{
if (sourceProperty.CanRead)
{
var targetProperties = targetType.GetProperties();
foreach (var targetProperty in targetProperties)
{
if (targetProperty.Name == sourceProperty.Name &&
targetProperty.PropertyType == sourceProperty.PropertyType)
{
if (targetProperty.CanWrite)
{
var value = sourceProperty.GetValue(source, null);
targetProperty.SetValue(target, value, null);
}
break;
}
}
}
}
}
}
}