在不编写大量样板代码的前提下, [英] Facade a class without writing lots of boilerplate code?

查看:306
本文介绍了在不编写大量样板代码的前提下,的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个来自第三方的课程,这是一个数据模型。它可能有100个属性(一些与公共设置者和吸烟者,其他公共吸烟者,但私人设置者)。我们来调用这个类ContosoEmployeeModel



我想用一个接口(INavigationItem,它有Name和DBID属性)来设计这个类,以允许它在我的应用程序中使用(它是一个PowerShell提供程序,但现在不重要)。但是,它也需要用作ContosoEmployeeModel。



我的初始实现如下所示:

  public class ContosoEmployeeModel 
{
//注意这个类不在我的控制之下。我提供了
//一个我必须使用的实例。

public DateTime EmployeeDateOfBirth {get;组; }
//和其他99个属性。
}

public class FacadedEmployeeModel:ContosoEmployeeModel,INavigationItem
{
private ContosoEmployeeModel model;
public FacadedEmployeeModel(ContosoEmployeeModel model)
{
this.model = model;
}

// INavigationItem属性
string INavigationItem.Name {get; set;}

int INavigationItem.DBID {get; set;}

// ContosoEmployeeModel属性
public DateTime EmployeeDateOfBirth
{
get {return this.model.EmployeeDateOfBirth; }
set {this.model.EmployeeDateOfBirth = value; }
}
//现在再写99个属性,如下所示:-(
}

然而,很明显,这将涉及编写大量的样板代码来公开所有的属性,我宁愿避免这一点,如果可以的话,我可以T4代码生成这个代码一个部分课程,如果没有更好的想法,会做,但我虽然在这里请问有没有人有任何更好的想法使用一些 super wizzy 位于C#请注意 - 我用于获取ContosoEmployeeModel的API只能返回一个ContosoEmployeeModel - 我无法扩展它以返回FacededEmployeeModel,因此包装模型是只有我能想到的解决方案 - 我是很高兴得到纠正:)

另一种方法可能适合您使用AutoMapper将基类映射到这里的门面是示例代码:

  class Program 
{
static void Main(string [] args)
{
var model = new Model {Count = 123,Date = DateTime.Now,Name =Some name};

Mapper.CreateMap< Model,FacadeForModel>();
var mappedObject = AutoMapper.Mapper.Map&FacadeForModel>(model);

Console.WriteLine(mappedObject);

Console.ReadLine();
}

class模型
{
public string Name {get;组; }

public DateTime Date {get;组; }

public int Count {get;组; }
}

接口INavigationItem
{
int Id {get;组; }

string OtherProp {get;组; }
}

class FacadeForModel:Model,INavigationItem
{
public int Id {get;组; }

public string OtherProp {get;组; }
}
}


Let's say I have a class from a 3rd-party, which is a data-model. It has perhaps 100 properties (some with public setters and getters, others with public getters but private setters). Let's call this class ContosoEmployeeModel

I want to facade this class with an interface (INavigationItem, which has Name and DBID properties) to allow it to be used in my application (it's a PowerShell provider, but that's not important right now). However, it also needs to be usable as a ContosoEmployeeModel.

My initial implementation looked like this:

public class ContosoEmployeeModel
{
    // Note this class is not under my control. I'm supplied
    // an instance of it that I have to work with.

    public DateTime EmployeeDateOfBirth { get; set; }
    // and 99 other properties.
}

public class FacadedEmployeeModel : ContosoEmployeeModel, INavigationItem
{
    private ContosoEmployeeModel model;
    public FacadedEmployeeModel(ContosoEmployeeModel model)
    {
        this.model = model;
    }

    // INavigationItem properties
    string INavigationItem.Name { get; set;}

    int INavigationItem.DBID { get; set;}

    // ContosoEmployeeModel properties
    public DateTime EmployeeDateOfBirth
    {
        get { return this.model.EmployeeDateOfBirth; }
        set { this.model.EmployeeDateOfBirth = value; }
    }
    // And now write 99 more properties that look like this :-(
}

However, it's clear that this will involve writing a huge amount of boilerplate code to expose all the properties , and I'd rather avoid this if I can. I can T4 code-generate this code in a partial class, and will do if there aren't any better ideas, but I though I'd ask here to see if anyone had any better ideas using some super wizzy bit of C# magic

Please note - the API I use to obtain the ContosoEmployeeModel can only return a ContosoEmployeeModel - I can't extend it to return a FacededEmployeeModel, so wrapping the model is the only solution I can think of - I'm happy to be corrected though :)

解决方案

The other approach may be suitable for you is to use AutoMapper to map base class to your facade here is sample code:

class Program
    {
        static void Main(string[] args)
        {
            var model = new Model { Count = 123, Date = DateTime.Now, Name = "Some name" };

            Mapper.CreateMap<Model, FacadeForModel>();
            var mappedObject = AutoMapper.Mapper.Map<FacadeForModel>(model);

            Console.WriteLine(mappedObject);

            Console.ReadLine();
        }

        class Model
        {
            public string Name { get; set; }

            public DateTime Date { get; set; }

            public int Count { get; set; }
        }

        interface INavigationItem
        {
            int Id { get; set; }

            string OtherProp { get; set; }
        }

        class FacadeForModel : Model, INavigationItem
        {
            public int Id { get; set; }

            public string OtherProp { get; set; }
        }
    }

这篇关于在不编写大量样板代码的前提下,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆