开发者

How to add property to existing interface?

开发者 https://www.devze.com 2023-03-30 06:39 出处:网络
I have the following hierarchy of assemblies: MyRoot MyRoot.General MyRoot.General.Model MyRoot.General.MyApp

I have the following hierarchy of assemblies:

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

Each assembly should reference going from MyApp down to MyRoot. In other words, MyRoot should not reference any of these assemblies. MyApp can reference all of them.

MyRoot.General includes an interface named IMyContext. IMyContext is used in Model and MyApp namespaces to supply instance data during the life of the app instance. The problem is I need to add another property to IMyContext so a class instance in the Model namespace is available through out Model and MyApp namespaces (just like IMyContext instance is). But then MyRoot.General would have to reference the MyRoot.General.Model assembly. I could create a singleton for this one class inside of Model but then I basically have two contexts to keep up with - IMyContext and MyRoot.General.Model.MySingleton.

Is there a be开发者_开发问答tter way to do this? I'm thinking it is probably some type of composition.

Also, existing applications are using MyRoot.General.IMyContext. It will be too much refactoring and risk to add a new property to IMyContext.


Why not define the interface to the class that you need in MyRoot.General, and then provide the implementation of that interface in MyRoot.General.Model. You are presumably passing the IMyContext around already- depending on where the new class is needed, you can attach it to your model or attach a service that resolves it for you.

Assuming this exists:

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

why not define:

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

and implement it inside of MyRoot.General.Model:

namespace MyRoot.General.Model {
   public class MyOtherThing : MyRoot.General.IMyOtherThing  {
       /// Some new stuff here
   }
}
and then pass it around using a new property on IMyContext

and then add a new interface, IMyContextEx:

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

Finally, implement IMyContextEx on the same class that implements IMyContext, and cast where needed to get the new property.


You need to think about the Adapter Pattern ...

What you do is something like the following:

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

... then...

public class MyAdapter : IMyAdapter
{
    //  fulfill contract
}

When done, you will have new requirements for this specific Adapter. When inherited by the type to be adapted to your workflow, it must follow both contracts. If you are creating something like:

IMyAdapter adapter = new MyAdapter ();

... I think you will want to implicitly implement IMyAdapter so you can have reference to the IMyContext methods.


The property you want to include on the IMyContext needs to be of an abstract type, perhaps another interface.

The MyRoot.General.Model assembly could contain the implementation of this interface, or perhaps even an implementation of the entire IMyContext interface itself.

Your question doesn't really mention where the concrete implementation is of your IMyContext interface. MyRoot.General.MyApp can instanciate a concrete implementation without MyRoot.General having a reference to it.

0

精彩评论

暂无评论...
验证码 换一张
取 消