Как добавить свойство в существующий интерфейс? - PullRequest
3 голосов
/ 25 августа 2011

У меня есть следующая иерархия сборок:

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 голосов
/ 25 августа 2011

Почему бы не определить интерфейс к классу, который вам нужен в 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; }
   }
}

Наконец, реализуйте IMyContextEx в том же классе, который реализует IMyContext, и приведите, где необходимо, чтобы получить новое свойство.

1 голос
/ 25 августа 2011

Вам нужно подумать о шаблоне адаптера ...

То, что вы делаете, выглядит примерно так:

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

... then ...

public class MyAdapter : IMyAdapter
{
    //  fulfill contract
}

Когда вы закончите, у вас будут новые требования для этого конкретного Адаптера .При наследовании по типу, который будет адаптирован к вашему рабочему процессу, он должен следовать обоим контрактам.Если вы создаете что-то вроде:

IMyAdapter adapter = new MyAdapter ();

... Я думаю, вы захотите неявно реализовать IMyAdapter, чтобы вы могли ссылаться на методы IMyContext.

0 голосов
/ 25 августа 2011

Свойство, которое вы хотите включить в IMyContext, должно быть абстрактного типа, возможно, другого интерфейса.

Сборка MyRoot.General.Model может содержать реализацию этого интерфейса или, возможно, даже реализацию всего интерфейса IMyContext.

Ваш вопрос на самом деле не упоминает, где конкретная реализация вашего интерфейса IMyContext. MyRoot.General.MyApp может создать конкретную реализацию без MyRoot.General имея ссылку на него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...