谁应该负责在IoC容器中注册类型?

3
假设我有一个包含许多程序集的ASP.NET MVC Web应用程序。这是一个非常简单的例子:
- MyApp.Web:Web应用程序 - MyApp.Services:包含域服务的接口和实现,例如IOrderProcessor、DefaultOrderProcessor - MyApp.DAL:包含存储库的接口和实现,例如IOrderRepository、SqlOrderRepository
Web应用程序将在启动期间初始化IoC容器(例如注册控制器等)。我不确定谁应该负责注册域服务和存储库。
现在我所做的是,在每个程序集中创建一个静态类,每个类都包含一个负责注册程序集中包含类型的方法。例如,对于DAL程序集:
namespace MyApp.DAL
{
  public static class AssemblyInitialization
  {
    public static void RegisterTypes(IUnityContainer container)
    {
      var lm = new TransientLifestyleManager();
      container.RegisterType<IOrderRepository, SqlOrderRepository>(lm);
      ...
    }
  }
}

这些方法随后在 Web 应用程序启动期间被调用(在单元测试项目中,我当然无法使用这些方法,但必须在测试项目中注册所有测试实现)。
我不确定这是否是一种好的做法。例如,此解决方案将两个程序集绑定到特定的 IoC 容器(在上面显示的示例中为 Unity)。这似乎是可能的反模式(类似于使用服务定位器模式)。
因此,我想听听您对如何处理这个问题的意见,例如:
- 所有注册事项是否应由主应用程序(Web 应用程序)处理? - 这是否会使主应用程序过多地了解独立(自包含)程序集的内容? - 我是否应该使用自制接口来抽象特定的 IoC 容器? - 还有其他需要考虑的事情吗?
3个回答

1

入口点的责任通常落在MyApp.Web上,这里是指你的全局.asax文件中的代码。它通常会被“调用/引用”。


1

在你的入口点开始“引导”。但是,你可以通过在这些程序集中使用实现IRegistration的类来委托注册。

这就是你现在正在做的事情。但是,你可以通过在初始化时反射查找IRegistration实现,而不是使用静态类。

由于你正在使用MVC,请看看Turbine,它在这方面做得很好。或者更好的是,在你的应用程序中使用它 :)


IRegistration是什么,它在哪里定义的?我找不到它。如果这是来自特定IoC容器的内容,那么我猜它对我的当前解决方案不会有太大的改进。 - M4N
不,这只是一个示例。您可以随意命名, IRegistration 可以是您应用程序中的接口。当应用程序初始化时,所有实现 IRegistrations 的类都将被加载和执行。这样,您可以避免使用静态类,并将注册放在逻辑位置(例如,而不是全局.asax 中的数十个注册...)。 - Bertvan
好的,你仍然需要自己寻找这些实现。但是说真的,在ASP.NET MVC环境中,看一下MVC Turbine,它可以做到这一点(除其他功能外)。 - Bertvan

0

在我看来,你的代码应该尽可能地推迟做出这个选择,直到最后一个负责的时刻。我使用Unity,所以我可以等到web.config被加载后再声明我想要注入的类型。

我认为,如果你不使用配置文件来完成这个任务,那么你就做错了什么。使用DI框架的目的是减少和/或消除这些编译时依赖关系。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接