在解析公共类时注入内部帮助器类

时间:2011-01-23 17:44:10

标签: architecture dependency-injection inversion-of-control autofac

我有以下架构,其中引用内部Helper类的公共服务类存在于另一个程序集中:

ApplicationAssembly {
  public class Widget {
    public Widget(ReferencedAssembly.Service service) { ... }
  }
}

ReferencedAssembly {
  public class Service {
    public Service(Helper helper) { ... }
  }
  class Helper { ... }
}

(我意识到我不能在公共类的构造函数的参数中加入内部类 - 我只是想说明我正在追求的IoC模式。)

问题是ApplicationAssembly无法看到ReferencedAssembly.Helper,因此无法在我的IoC容器中注册(在本例中为Autofac)。因此,当我尝试解析Helper时无法解析Service。我最好的选择是什么?

  • 选项1:从Helper的构造函数中删除Service并在构造函数中明确地将其新建。我不喜欢这个选项,因为它打破了IoC范式。

  • 选项2:让Helper实施公开IHelper界面,然后在ReferencedAssembly中添加一个将Helper注册为IHelper的公共模块。我不喜欢这个选项,因为它需要ApplicationAssembly知道关于Service的太多实现细节,如果用户忘记在启动时注册该模块,那么一切都会中断。

  • 选项3:在Service上创建一个公共静态构造函数,专门为ReferencedAssembly构建第二个IoC容器,并在其中注册Helper。从Helper的构造函数中删除Service,并使用第二个IoC容器在构造函数中解析它。这似乎是我最好的选择,但需要比其他代码更多的“管道”代码。我也不是公共静态构造函数的忠实粉丝。

  • 选项4.将我的架构改为其他内容。

1 个答案:

答案 0 :(得分:12)

使用Autofac注册内部类型的方法是在程序集内部包含Autofac Module和内部类型,并使用容器注册模块。由于模块位于同一个程序集中,因此可以使用内部类型配置ContainerBuilder

我认为最好的选择是让Service实现一个公共接口,然后创建当前内部的Service类。 Autofac将愉快地实例化一个内部类以提供公共接口。

另一个选项(允许Service对内部类型采用构造函数依赖)是使Service的构造函数内部,然后在Service中使用构造函数查找器类型注册:

builder.RegisterType<Service>()
  .FindConstructorsWith(new BindingFlagsConstructorFinder(BindingFlags.NonPublic));