快速指导


public class A
{
    public string message;
}
public class B
{
    public string message = "Hello, world!!!";
}

 

现在,我们有一个实体类B,我们想把它转为实体类A,但是又不想手动字段赋值。可以用以下方式解决:
B b = new B();
A a = ObjectMapperManager.DefaultInstance.GetMapper<B, A>().Map(b);

 


这个类库最主要的类是ObjectMapperManager。这个类实现了对象映射(在IL运行时)和映射缓存

 

/// <summary>
/// 用于维护和生成映射的类
/// </summary>
public class ObjectMapperManager
{
    public static ObjectMapperManager DefaultInstance
    public ObjectMapperManager();
     
    /// <summary>
    /// 返回特定类型的映射实体
    /// </summary>
    /// <typeparam name="TFrom">来源类型</typeparam>
    /// <typeparam name="TTo">映射类型</typeparam>
    /// <returns></returns>
    public ObjectsMapper<TFrom, TTo> GetMapper<TFrom, TTo>();
 
    /// <summary>
    /// 返回特定类型的映射实体
    /// </summary>
    /// <typeparam name="TFrom">来源类型</typeparam>
    /// <typeparam name="TTo">映射类型</typeparam>
    /// <param name="ShallowCopy">True, 如果来源类型和映射类型中的某字段是引用类型,且类型相同,映射时,会直接引用而不会创建新的对象</param>
    /// <returns></returns>
    public ObjectsMapper<TFrom, TTo> GetMapper<TFrom, TTo>(bool ShallowCopy);
 
    /// <summary>
    /// 返回特定类型的映射实体
    /// </summary>
    /// <typeparam name="TFrom">来源类型</typeparam>
    /// <typeparam name="TTo">映射类型</typeparam>
    /// <param name="ShallowCopy">True, 如果来源类型和映射类型中的某字段是引用类型,且类型相同,映射时,会直接引用而不会创建新的对象</param>
    /// <param name="mappingConfigurator">映射配置委托</param>
    /// <param name="mapperName">映射实体的名称。如果两个映射实体有相同的参数,但是名称不一样,那么,将生成两个不同的映射实体</param>
    /// <returns></returns>
    public ObjectsMapper<TFrom, TTo> GetMapper<TFrom, TTo>(
        bool ShallowCopy,
        MappingConfigurator mappingConfigurator,
        string mapperName);
 
    /// <summary>
    /// 返回特定类型的映射实现实体
    /// </summary>
    /// <param name="from">来源类型</param>
    /// <param name="to">映射类型</param>
    /// <param name="ShallowCopy">True, 如果来源类型和映射类型中的某字段是引用类型,且类型相同,映射时,会直接引用而不会创建新的对象</param>
    /// <param name="mappingConfigurator">映射配置委托</param>
    /// <returns></returns>
    public ObjectsMapperBaseImpl GetMapperImpl(
        Type from,
        Type to,
        bool ShallowCopy,
        MappingConfigurator mappingConfigurator);
 
    /// <summary>
    /// 返回特定类型的映射实现实体
    /// </summary>
    /// <param name="from">来源类型</param>
    /// <param name="to">映射类型</param>
    /// <param name="ShallowCopy">True, 如果来源类型和映射类型中的某字段是引用类型,且类型相同,映射时,会直接引用而不会创建新的对象</param>
    /// <param name="mappingConfigurator">映射配置委托</param>
    /// <param name="mapperName">映射实现实体的名称。如果两个映射实现实体有相同的参数,但是名称不一样,那么,将生成两个不同的映射实现实体</param>
    /// <returns></returns>
    public ObjectsMapperBaseImpl GetMapperImpl(
        Type from,
        Type to,
        bool ShallowCopy,
        MappingConfigurator mappingConfigurator,
        string mapperName);
}

 


一般情况下,如果你不需要分离映射缓存,你能够使用线程安全的 ObjectMapperManager.DefaultInstance 对象,你不需要实例化ObjectMapperManager

使用类ObjectMapperManager你能够创建ObjectsMapper实体,用于实体映射操作

 

public class ObjectsMapper<TFrom, TTo>
{
    public TTo Map(TFrom from, TTo to);
    public TTo Map(TFrom from);
}

 


使用这种方案,需要以下两步:

Step 1: 使用类ObjectMapperManager创建一个ObjectsMapper:

 

var mapper = ObjectMapperManager.DefaultInstance.GetMapper<B, A>();

 



Step 2: 使用上一步创建的mapper来映射对象

 

A a = mapper.Map(new B());

 


比如,我们有两个类“A”和“B”,他们有相同的结构

 

public class A
{
    public enum En
    {
        En1,
        En2,
        En3
    }
    public class AInt
    {
        internal int intern = 13;
        public string str = "AInt";
 
        public AInt()
        {
            intern = 13;
        }
    }
 
    private string m_str1 = "A::str1";
 
    public string str1
    {
        get
        {
            return m_str1;
        }
        set
        {
            m_str1 = value;
        }
    }
 
    public string str2 = "A::str2";
    public AInt obj;
    public En en = En.En3;
 
    int[] m_arr;
 
    public int[] arr
    {
        set
        {
            m_arr = value;
        }
        get
        {
            return m_arr;
        }
    }
 
    public AInt[] objArr;
 
    public string str3 = "A::str3";
 
    public A()
    {
        Console.WriteLine("A::A()");
    }
}
 
public class B
{
    public enum En
    {
        En1,
        En2,
        En3
    }
    public class BInt
    {
        public string str = "BInt";
    }
 
    public string str1 = "B::str1";
    public string str2
    {
        get
        {
            return "B::str2";
        }
 
    }
    public BInt obj = new BInt();
    public En en = En.En2;
 
    public BInt[] objArr;
 
    public int[] arr
    {
        get
        {
            return new int[] { 1, 5, 9 };
        }
    }
 
    public object str3 = null;
 
 
    public B()
    {
        Console.WriteLine("B::B()");
 
        objArr = new BInt[2];
        objArr[0] = new BInt();
        objArr[0].str = "b objArr 1";
        objArr[1] = new BInt();
        objArr[1].str = "b objArr 2";
    }
}

 


将类B映射到类A:

 

A a = new A();
B b = new B();
ObjectMapperManager.DefaultInstance.GetMapper<B, A>().Map(b, a);
 
Assert.AreEqual(a.en, A.En.En2);
Assert.AreEqual(a.str1, b.str1);
Assert.AreEqual(a.str2, b.str2);
Assert.AreEqual(a.obj.str, b.obj.str);
Assert.AreEqual(a.obj.intern, 13);
Assert.AreEqual(a.arr.Length, b.arr.Length);
Assert.AreEqual(a.arr[0], b.arr[0]);
Assert.AreEqual(a.arr[1], b.arr[1]);
Assert.AreEqual(a.arr[2], b.arr[2]);
Assert.AreEqual(a.objArr.Length, b.objArr.Length);
Assert.AreEqual(a.objArr[0].str, b.objArr[0].str);
Assert.AreEqual(a.objArr[1].str, b.objArr[1].str);
Assert.IsNull(a.str3);

 

 

posted @ 2014-11-05 16:57  争世不悔  阅读(168)  评论(0编辑  收藏  举报