在不编写大量样板代码的前提下, [英] Facade a class without writing lots of boilerplate code?
问题描述
我想用一个接口(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屋!