如何向现有界面添加属性?

时间:2011-08-24 22:26:41

标签: c# .net design-patterns composition

我有以下程序集层次结构:

MyRoot
MyRoot.General
MyRoot.General.Model
MyRoot.General.MyApp

每个程序集都应该引用从MyApp到MyRoot。换句话说,MyRoot不应该引用任何这些程序集。 MyApp可以参考所有这些内容。

MyRoot.General包含一个名为IMyContext的接口。 IMyContext在Model和MyApp命名空间中用于在应用程序实例的生命周期中提供实例数据。问题是我需要向IMyContext添加另一个属性,因此Model命名空间中的类实例可以通过Model和MyApp命名空间获得(就像IMyContext实例一样)。但是MyRoot.General必须引用MyRoot.General.Model程序集。我可以在Model中为这一个类创建一个单例,但是我基本上有两个上下文可以跟上 - IMyContext和MyRoot.General.Model.MySingleton。

有更好的方法吗?我认为它可能是某种类型的组合。

此外,现有应用程序正在使用MyRoot.General.IMyContext。向IMyContext添加新属性将会有太多的重构和风险。

3 个答案:

答案 0 :(得分:2)

为什么不在MyRoot.General中定义所需类的接口,然后在MyRoot.General.Model中提供该接口的实现。您可能已经传递了IMyContext - 取决于需要新类的位置,您可以将其附加到您的模型或附加为您解析它的服务。

假设存在:

namespace MyRoot.General {
   public interface IMyContext {
       /// Some irrelevant stuff here
   }
}

为什么不定义:

namespace MyRoot.General {
   public interface IMyOtherThing {
       /// Some new stuff here
   }
}

并在MyRoot.General.Model:

中实现它
namespace MyRoot.General.Model {
   public class MyOtherThing : MyRoot.General.IMyOtherThing  {
       /// Some new stuff here
   }
}
<德尔> 然后使用IMyContext上的新属性传递它

然后添加一个新界面,IMyContextEx:

namespace MyRoot.General {
   public interface IMyContextEx : IMyContext {
       IMyOtherThing MyOtherThing { get; set; }
   }
}

最后,在实现IMyContext的同一个类上实现IMyContextEx,并在需要获取新属性的地方进行转换。

答案 1 :(得分:1)

您需要考虑Adapter Pattern ...

您所做的事情如下:

public interface IMyAdapter : IMyContext
{
    //  additional contract requirements
    string MyProperty { get; }
}

......然后......

public class MyAdapter : IMyAdapter
{
    //  fulfill contract
}

完成后,您将对此特定适配器有新的要求。当由要适应您的工作流程的类型继承时,它必须遵循两个合同。如果你要创建类似的东西:

IMyAdapter adapter = new MyAdapter ();

...我想你会隐含地实现IMyAdapter,所以你可以引用IMyContext方法。

答案 2 :(得分:0)

要包含在IMyContext中的属性需要是抽象类型,可能是另一个接口。

MyRoot.General.Model程序集可以包含此接口的实现,甚至可能包含整个IMyContext接口本身的实现。

您的问题并未真正提及IMyContext接口的具体实现。 MyRoot.General.MyApp可以在不使用MyRoot.General的情况下实现具体实现 提到它。