在没有编写大量样板代码的情况下立面上课?

时间:2013-07-02 09:45:14

标签: c# design-patterns adapter .net-4.5 facade

假设我有一个来自第三方的课程,这是一个数据模型。它可能有100个属性(一些具有公共设置者和吸气剂,另一些具有公共吸气剂但是私人制定者)。我们称这个类为ContosoEmployeeModel

我希望使用一个接口(INavigationItem,它具有Name和DBID属性)来覆盖这个类,以允许它在我的应用程序中使用(它是一个PowerShell提供者,但现在这并不重要)。但是,它还需要可用作ContosoEmployeeModel。

我的初步实施如下:

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 :-(
}

然而,很明显,这将涉及编写大量的样板代码来公开所有属性,如果可以的话,我宁愿避免这种情况。我可以在部分类中使用T4代码生成此代码,如果没有任何更好的想法,我会这样做,但我会在这里询问是否有人使用某些super {{ 3}} wizzy C#magic

请注意 - 我用来获取ContosoEmployeeModel的API只能返回一个ContosoEmployeeModel - 我无法扩展它以返回一个FacededEmployeeModel,所以包装模型是我能想到的唯一解决方案 - 我很高兴成为尽管如此纠正:)

2 个答案:

答案 0 :(得分:1)

另一种方法可能适合您使用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 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; }
        }
    }

答案 1 :(得分:1)

Resharper允许创建“委托成员”,它将包含对象的接口复制到包含对象上,并将方法调用/属性访问隧道传递给包含的对象。

http://www.jetbrains.com/resharper/webhelp/Code_Generation__Delegating_Members.html

完成后,您可以在代理类中提取接口。