如何向现有接口添加属性?

3
我有以下程序集层次结构:
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个回答

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,并在需要的地方进行转换以获取新属性。

MyApp已经在使用IMyContext了。如果我创建一个IMyContextTwo,那么将需要进行大量的重构...对吗?也许我没有理解清楚。 - 4thSpace
你所说的“然后使用IMyContext上的新属性传递它”这部分会对现有应用程序造成很多破坏。 - 4thSpace
@Chris:从你的代码示例中,你是说MyApp仍然会有对IMyContext和IMyContextEx的引用?新的代码将需要IMyContextEx,但我认为它仍然会破坏一些现有的用法。不过,我可能可以摆脱它,而不必进行太多的重构。哦,我看到了你的最后一篇帖子,我认为它会起作用。 - 4thSpace
@4thSpace:你不需要修改你的旧代码。甚至不必将IMyAdaptor包含在同一个库中。 - IAbstract
我认为如果MyApp没有已经在使用IMyService,那么这个方案本应能够奏效。但是要让MyApp切换到新接口需要进行过多的重构。我不得不使用MySingleton解决方案。 - 4thSpace
显示剩余3条评论

1

你需要考虑适配器模式...

你要做的事情类似于以下内容:

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

...然后...

public class MyAdapter : IMyAdapter
{
    //  fulfill contract
}

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

IMyAdapter adapter = new MyAdapter ();

...我认为你会想要隐式实现IMyAdapter,这样你就可以引用IMyContext的方法。


0

你想在IMyContext中包含的属性需要是抽象类型,也许是另一个接口。

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

你的问题并没有真正提到你的IMyContext接口的具体实现在哪里。MyRoot.General.MyApp可以实例化一个具体的实现,而不需要MyRoot.General引用它。


IMyContext 的具体实现在 MyRoot.General 中。 - 4thSpace

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接