20 зависимость, чтобы пройти через конструктор, чтобы сделать IOC - PullRequest
0 голосов
/ 28 апреля 2011

У меня есть класс под названием MessageService. Этот класс отвечает за получение электронной почты (на самом деле потоки). В зависимости от темы письма он определяет, какой поток поставлен на карту, и выполняет действие.

немного кода, чтобы объяснить мою проблему, может быть проще:

public class MessageService
{
    public void ReadEmail()
    {
      switch (subject)
         "1" :
          Myservice.action1(); break;
         "2" :
          Myservice.action2(); break;
         "qwwerty" :
          MyOtherservice.Querty(); break;
          etc...
    }
}

Чтобы сделать некоторую инверсию управления, я хотел передать ссылки на сервисы через конструктор моего класса MessageService.

public MessageService(IMyService myService,IMyOtherservice myOtherservice, ect....)
{
    Myservice=myService;
    MyOtherservice=myOtherservice;
}

Это отлично работает для нескольких ссылок, но класс MessageService может работать с разницей до 20, 30 или сорока потоков. И это сделало бы инициализацию моего класса немного тяжелой.

Есть ли какой-нибудь более хороший способ достичь этого? через какой-то шаблон дизайна? Должен ли я заботиться о МОК (хотя мне нравится проводить тесты в классе после ...)?

Спасибо за вашу помощь,

Ответы [ 2 ]

0 голосов
/ 28 апреля 2011

Лучшее предложение - разбить ваш класс на более мелкие.Наличие 30 или 40 зависимостей в одном классе является признаком того, что он делает слишком много.Попробуйте разбить каждый класс на что-то, что делает только одно, и тогда вы сможете начать объединять их в более крупные функциональные возможности.Поскольку вы используете контейнер IoC, это на самом деле не должно быть слишком сложным, и это облегчит тестирование вашего кода.Идеальная цель - стрелять по одной или двум зависимостям на класс, но на самом деле, я думаю, 4 или 5 - хорошая цель для начала.

Не зная точно, что делает ваш код, это сложнопредложить конкретные шаблоны проектирования.

0 голосов
/ 28 апреля 2011

Возможно, вы захотите использовать шаблон проектирования Chain-of-Responsibility.Создайте интерфейс, который знает, как работать с электронной почтой, и создайте отдельные классы для каждой задачи, которую вы хотите выполнить (примерно эквивалентно вашему выражению switch (switch, кстати, очень наивная реализация COR)).Каждый из этих классов будет получать только те услуги, которые им необходимы.Затем в MessageService возьмите список этих интерфейсов и обрабатывайте их по одному, пока один из них не покажет, что обработал его:

public interface IMessageReader
{
  /// <returns><c>true</c> if handled; otherwise false
  bool ReadEmail(Mail message);
}

public class QwertyMessageReader : IMessageReader
{
  public QwertyMessageReader(IMyOtherService otherService) {/*set*/}
  public bool ReadEmail(Mail message)
  {
     if(message.Subject.Equals("qwwerty"))
     {
       otherService.Querty();
       return true;
     }
     return false;
  }
}

public class MessageService
{
    public MessageService(IEnumerable<IMessageReader> readers) {/*set*/}
    public void ReadEmail()
    {
      var handled = readers.Select(reader => reader.ReadEmail(message))
                           .FirstOrDefault(result => result);
    }
}

Вам нужно настроить интерфейсы и код выше, чтобы соответствоватьчто вы делаете, но это основная концепция.

Большинство приличных контейнеров IOC автоматически сгенерируют IEnumerable <>, если вы зарегистрируете несколько одинаковых интерфейсов.

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