N.B。,这都是C#4.0
这可能看起来像一个奇怪的问题,让我们说我的所有业务对象绑定到基类,让我们称之为BaseObject
,所以我会让我的类继承它:
public class CashRegister : BaseObject { }
现在大多数时候我在我的项目中使用NHibernate。其他一些项目出现了,我想使用CouchDb。我不想为这些技术中的每一种创建新的BaseObject
,而是想以某种方式将CouchDbObject
之类的东西“绑定”到BaseObject
......这可能吗?更好的是,如果我有一个属性,它将基于属性绑定:
[CouchDb]
public class CashRegister : BaseObject { }
这可能很疯狂,但有可能吗?鉴于上面的例子,我会说谎:
var cashRegister = new CashRegister();
cashRegister.SomeGenericBaseObjectMethod();
cashRegister.SomeCouchDbSpecificMethod();
似乎Ninject“上下文绑定”做了我需要的,是吗?我现在正在集思广益,但如果在我的代码中我可以做这样的事情来做实际的绑定会很棒:
Bind<ICouchDbObject>.To<BaseObject>();
我甚至会努力使BaseObject
动态,或任何其他可能使这成为可能的前沿功能。如果这是不可能的或“不要”,请告诉我!试图跳出框框思考。
答案 0 :(得分:1)
不,出于几个原因,你所要求的是不可能的。
通常情况下,当您遇到想要执行所描述内容的情况时,这是因为您使用的架构不能很好地区分问题。我只是在这里猜测,但如果你使用这样的方法,你可能会更灵活:
public interface IBaseObject
{
int ObjectId {get;}
}
public class CashRegister : IBaseObject
{
int IBaseObject.ObjectId { get {return CashRegisterId;} }
public int CashRegisterId {get;set;}
}
public class BaseObjectUtil
{
public void SomeGenericBaseObjectMethod(IBaseObject baseObject)
{
var objectId = baseObject.ObjectId;
// Do something with the object ID.
}
}
public class SomeUtility
{
private BaseObjectUtil _baseObjectUtil;
public SomeUtility(BaseObjectUtil baseObjectUtil)
{
_baseObjectUtil = baseObjectUtil;
}
public void DoSomethingImportant(CashRegister register)
{
_baseObjectUtil.SomeGenericBaseObjectMethod(register);
}
}
您会注意到到目前为止我们还没有任何依赖CouchDb的代码。现在,假设还有另一个项目希望能够使用上述项目,但希望能够根据CouchDb信息执行其他操作。你可能会这样做:
public interface ICouchDbObject
{
string TableName {get;}
}
public class CouchDbUtil
{
public void SomeCouchDbSpecificMethod(ICouchDbObject couchDbObject)
{
var tableName = couchDbObject.TableName;
// Do something with the table name.
}
}
public class CouchDbCashRegister : CashRegister, ICouchDbObject
{
string ICouchDbObject.TableName {get{return "CashRegisters";}}
}
在这个项目中,当你需要一个收银机时,你会使用一个CouchDbCashRegister
,它可以让你在CouchDbUtil
课程上调用特定于CouchDb的方法,同时仍允许你打电话BaseObjectUtil
类中的基线实用程序方法。
此外,如果您利用像Ninject这样的DI框架来创建对象,您实际上可以使其在第二个项目中创建的所有CashRegisters实际上都是CouchDbCashRegisters。
Bind<CashRegister>.To<CouchDbCashRegister>();
答案 1 :(得分:1)
虽然您的问题讨论了“绑定”到另一个基类,但您没有显示任何可以利用多态性的示例用法。相反,您的示例显示了调用其他方法的有希望的能力:
var cashRegister = new CashRegister();
cashRegister.SomeGenericBaseObjectMethod();
cashRegister.SomeCouchDbSpecificMethod();
你大多希望得到一些语法糖吗?如果是,请考虑extension methods。这是一个例子:
// Declaration
namespace ExtensionMethods {
public static class CashRegisterExtensions {
public static void SomeCouchDbSpecificMethod(this CashRegister cashRegister) {
// do stuff with CashRegister instance
}
}
}
然后你可以cashRegister.SomeCouchDbSpecificMethod();
。否则,如果你不仅仅是在寻找语法糖,你可以考虑使用dynamic - 但是你可以发布一些实际用法来解决你想要利用多态性的想法吗?
答案 2 :(得分:0)
从广义上讲,要使您的类在不同的上下文中可重用,您需要将其与所述上下文分离。然后,您必须为要支持的每个上下文创建适配器或代理。
在C#中,您可以将对象创建为一种mixin对象,然后在目标类中使用它们:
public interface MBaseObject { }
public static class BaseObjectCode {
public static void SomeGenericBaseObjectMethod(this MBaseObject self) {
// ...
}
}
public interface MCouchDbObject { }
public static class CouchDbObjectCode {
public static void SomeCouchDbSpecificMethod(this MCouchDbObject self) {
// ...
}
}
public class CashRegister : MBaseObject, MCouchDbObject {
// ...
}