20依赖于通过构造函数来做IOC

时间:2011-04-28 15:35:43

标签: architecture

我有一个名为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或40个不同的流。这会使我的班级的初始化有点沉重。

有没有更好的方法来实现它?通过一些设计模式?我应该关心IOC(不过,我喜欢在课后运行我的测试......)?

感谢您的帮助,

2 个答案:

答案 0 :(得分:0)

您可能希望使用责任链设计模式。创建一个知道如何处理电子邮件的接口,并为你想要做的每个任务构建单独的类(大致相当于你的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&lt;&gt;如果您注册了多个相同的界面,请为您服务。

答案 1 :(得分:0)

最好的建议是将你的班级分成更小的班级。在一个类中有30或40个依赖关系表明它做得太多了。尝试将每个类分解成只做一件事的事情,然后你可以开始将它们组合成更大的功能。由于您使用的是IoC容器,因此实际上这应该不会太难,并且会使您的代码更容易测试。理想的目标是为每个班级拍摄一两个依赖项,但实际上,我认为4或5是一个很好的目标。

不知道您的代码到底在做什么,很难建议具体的设计模式。