65.9K
CodeProject 正在变化。 阅读更多。
Home

通用映射器

2010年2月27日

CPOL

2分钟阅读

viewsIcon

31285

downloadIcon

179

本文展示了一种简单且可重用的解决方案,用于在两个实体对象之间创建通用映射器。

引言

在很多情况下,我需要定义某种映射,稍后希望修改它。 在我最近的一个项目中,我正在使用领域驱动设计,并且我需要一个映射器类来将我的实体映射到通过 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 表达式指定对象之间的映射:这使得映射易于理解且非常易读。

现在,我们只需要调用 FirstTypeGetMappedObjecton 就可以获得已经初始化的 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);
}

如本文所示,此映射器非常灵活,并且可以在我们需要在实体对象之间进行映射的任何地方使用。

© . All rights reserved.