无论如何,当我的应用程序启动时,是否将基础对象绑定到另一个类?

时间:2011-04-19 15:57:28

标签: c#

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动态,或任何其他可能使这成为可能的前沿功能。如果这是不可能的或“不要”,请告诉我!试图跳出框框思考。

3 个答案:

答案 0 :(得分:1)

不,出于几个原因,你所要求的是不可能的。

  1. .NET不允许一个类直接从多个类继承。
  2. 项目在编译时需要引用父类的库,因此不能在运行时为其分配新的父类。
  3. 通常情况下,当您遇到想要执行所描述内容的情况时,这是因为您使用的架构不能很好地区分问题。我只是在这里猜测,但如果你使用这样的方法,你可能会更灵活:

    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 { 
  // ...
}

这使用接口继承和扩展方法的组合来创建一种mixin。我已经更好地描述了herehere