.Net 2.0中的对象到对象的映射

时间:2013-01-04 10:53:25

标签: .net

我想知道是否有人可以推荐一种可以在.NET2.0中使用的Automapper替代方案。

我有一个dll描述了一个相当复杂的结构。 dll位于webservice的两端,但是当通过webservice检索数据时,命名空间会阻止对象的直接映射,因此我不得不求助于编写映射类。

我合并了Automapper,它完全符合我的要求,但它不适用于.NET2.0。我需要使用.NET2.0,因为有几百台远程机器将运行客户端软件,它们仅限于.NET2.0。

任何帮助都将不胜感激。

3 个答案:

答案 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;
                        }
                    }
                }
            }
        }
    }
}