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); |