Visual Studio 2008.NET 3.0Visual Studio 2005Visual Studio 2010.NET4.NET 3.5C# 3.0C# 4.0中级开发Visual Studio.NETC#
通用映射器






2.88/5 (5投票s)
本文展示了一种简单且可重用的解决方案,用于在两个实体对象之间创建通用映射器。
引言
在很多情况下,我需要定义某种映射,稍后希望修改它。 在我最近的一个项目中,我正在使用领域驱动设计,并且我需要一个映射器类来将我的实体映射到通过 WCF 暴露的 POCO 对象,所以我考虑了这种简单的解决方案,它可以使任何类都可以映射到另一种类型,即使您只需要将某些对象的属性映射到另一个对象。
使用代码
首先,我们需要实现一些将在本文中使用的类
public class FirstType : GenericMapper<secondtype>
{
public string FirstName { get; set; }
public string Surname { get; set; }
}
public class SecondType
{
public string Name { get; set; }
public string Surname { get; set; }
}
现在,假设我们希望能够将 FirstType
映射到第二种类型,并且我们希望使用“友好”的语法来定义映射,以使代码更具可读性和易于理解。 解决方案是下面显示的映射器
Public delegate void MappingRules<d>(D To);
public abstract class GenericMapper<d> where D : new()
{
private D toObj;
public List<MappingRules<D>> MappingRule =
new List<MappingRules<D>>();
public void SetMapping(params MappingRules<d>[] mappingList)
{
MappingRule = mappingList.ToList();
}
public D GetMappedObject()
{
toObj = (D)Activator.CreateInstance(typeof(D));
foreach (var action in MappingRule)
{
action.Invoke(toObj);
}
return toObj;
}
}
我将映射器类设为抽象类,以便仅将其用作基类型。 我还定义了一个泛型委托,它将用于存储所有映射规则。 映射器的核心是 GetMappedObject()
,它返回我们想要映射的对象,并且所有属性都已初始化。
通过一个例子更容易理解。 在这种情况下,我想将 FirstType
映射到 SecondType
,因此我必须使 FirstType
能够映射到 SecondType
。 我可以通过让 FirstType
扩展映射器类来轻松地做到这一点。 映射器类是泛型的,因此我们必须指定我们想要返回的类型,在这种情况下,SecondType
。
public class FirstType : GenericMapper<secondtype>
{
public string FirstName { get; set; }
public string Surname { get; set; }
public FirstType()
{
this.SetMapping(x => x.Surname = this.Surname,
x => x.Name = this.FirstName);
}
}
现在,我们只需要定义一个构造函数,在其中使用 Lambda 表达式指定对象之间的映射:这使得映射易于理解且非常易读。
现在,我们只需要调用 FirstType
的 GetMappedObjecton
就可以获得已经初始化的 SecondType
对象,如我们在构造函数中定义的。
static void Main(string[] args)
{
FirstType f = new FirstType();
f.FirstName = "Peluso";
f.Surname = "Massimiliano";
// result is gonna be a secondType object already
// initialized as we defined into the FirstType contructor.
SecondType result = f.GetMappedObject();
Console.WriteLine(result.Name);
Console.WriteLine(result.Surname);
}
如本文所示,此映射器非常灵活,并且可以在我们需要在实体对象之间进行映射的任何地方使用。