Использование DI с общей библиотекой в ​​разных приложениях - PullRequest
8 голосов
/ 11 мая 2011

Я сталкиваюсь с проблемой дизайна, которую просто не могу решить удовлетворительным образом.У меня есть сборка библиотеки классов, которая содержит все мои общие объекты ORM (используя платформу EntitySpaces).Эти объекты используются в двух или более различных приложениях, поэтому они находятся в своей собственной сборке.Для меня эта установка работала уже более 4 лет.

У меня также есть пара приложений, созданных на основе составного блока приложений (CAB) из группы Microsoft Patterns & Practices (P & P).Да, я знаю, что это действительно старая версия, но я работаю неполный рабочий день, работаю в режиме одного человека и не могу позволить себе обновиться до текущей версии.

Вот моя проблема:Я использовал свои навыки проектирования ОО, и всякий раз, когда я делаю существенный рефакторинг, я стараюсь перейти от процедурного подхода к более ОО подходу.Конечно, основным аспектом проектирования ОО является размещение операций близко к данным, с которыми они работают, это означает, что мои объекты ORM должны иметь функциональность, добавленную к ним, где это необходимо.Это доказывает, что я не могу понять, что я использую DI-контейнер Object Builder от P & P в CAB и что большая часть функциональности, которую я перенесу в свои объекты ORM, будет нуждаться в доступе к службам, предоставляемым моими приложениями.

Другими словами, допустим, у меня есть общий бизнес-объект под названием «Персона» (я знаю, что он оригинальный), и у меня есть два приложения, которые ПОЛНОСТЬЮ разнятся с человеком.Приложение A предоставляет набор служб, которые объект Person должен иметь DI, чтобы он мог использовать некоторые из методов, которые в настоящее время засорены на всех уровнях моих служб.Приложение B также имеет другой набор сервисов, которые ИТ-специалистам необходимо добавить в объект person.

Учитывая, как конструктор объектов P & P разрешает зависимости с помощью декорации атрибутов и отражения типов, я не понимаю, как я могу это сделатьвыполнить это.Короче говоря, у меня есть общий объект, который при использовании в различных приложениях мне нужно будет вводить зависимости, чтобы он мог выполнять определенные операции, специфичные для этого приложения.

Единственный подход, который я могу придумать, - это наследоватьновый тип в приложении A & B от объекта Person.Затем я бы добавил свои не-общие функциональные возможности и код DI в этот специализированный объект Person для конкретного приложения.Теперь, когда я пишу, что это кажется настолько очевидным, однако это все еще мое единственное решение, которое я могу придумать, и я хотел бы спросить здесь, чтобы узнать, есть ли у кого-то еще другое решение, которое он хотел бы предложить?

Одна проблемаЯ бы решил, что мое решение заключается в том, что я вижу, как меня увлекают, когда я называю свой унаследованный тип - я имею в виду ... это человек, так как бы вы еще назвали это?В любом случае, надеюсь, у вас будут какие-то идеи для меня.

Кроме того, я не в восторге от современных технологий, которые существуют, и, честно говоря, я едва понимаю те технологии, которые я использую в настоящее время.Так что, если я сказал что-то противоречивое или запутанное, я надеюсь, что вы сможете понять достаточно из остальной части поста, чтобы понять, о чем я спрашиваю.

Ответы [ 3 ]

3 голосов
/ 11 мая 2011

Звучит так, как будто вы нарушаете Принцип единой ответственности .

Объект Person должен просто содержать данные для записи о человеке. Затем службы будут принимать объект Person и манипулировать им, а не иметь методы для объекта Person, который выполнял эту манипуляцию.

Классическим примером этого будет заполнение объекта Person. Допустим, приложение A получает данные из WebService, а приложение B получает их из базы данных. В этих случаях у меня будет какая-то служба Storage, которую вы вызываете, чтобы получить объект Person. Тогда реализация этого хранилища может быть специфичной для каждого приложения и быть добавлена ​​приложением в ваш IOC, а не пытаться иметь общий интерфейс в вашей общей сборке.

1 голос
/ 11 мая 2011

Я согласен с Кэмероном МакФарландом в этом: вы нарушаете SRP.

Конечно, главный аспект ОО дизайна размещает операции близко к данные, с которыми они работают, это означает, что мои объекты ORM должны иметь функциональность, добавленная к ним, где соответствующий

Размещение данных и функциональности из A И функциональность из B - это слишком много обязанностей. Присоединение к SRP почти всегда приводит к разделению данных и функциональности на отдельные классы (структуры данных и объекты). Таким образом, использование sugetion Камерона Макфарланда, вероятно, является лучшим способом.

0 голосов
/ 11 мая 2011

Я мог бы придумать пару подходов для решения этой проблемы.

  • Отделите поведение, характерное для каждого человека / приложения в отдельности. Выполните внедрение зависимостей, используя setter в самом приложении.

Apporach1


public interface IPerson 
{
 IPersonApp1 Person1 {get; set;}
 IPersonApp2 person2 {get; set;}
}

class Person : IPerson
{
 IPerson1 Person1 {get; set;}
 IPerson2 Person2 {get; set;}
}

   public interface IPerson1
  {
    // App1 specific behavior here
     void App1SpecificMethod1();
  }
  class Person1: IPerson1
   {
     void App1SpecificMethod1()
      {
       // implementation
      }
   }

class App1 
{
   IPerson objPerson;
   // Dependency injection using framework
   App1(IPerson objPerson)
  {
    this.objPerson = objPerson;
    // Dependency injection using setter
    this.objPerson.Person1 = new Person1();
  }
}

  • Отделите поведение, характерное для каждого человека / приложения в отдельности. Выполните внедрение зависимостей в конструкторе Person.

Apporach2


class Person : IPerson
{
 IPerson1 Person1 {get; private set;}
 IPerson2 Person2 {get; private set;}
 // DI through constructor. If the type IPerson1 or IPerson2 are not registered, it will be set to null.
 Person(IPerson1 objPerson1, IPerson2 objPerson2)
 {
   this.Person1 = objPerson1;
   this.Person2 = objPerson2;
 }
}

Проект интерфейса Person должен иметь ссылку на IPerson1 и IPerson2, или вы можете объявить IPerson1 и IPerson2 в самом проекте интерфейса Person.

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