Mic*_*hel 30 c# ioc-container inversion-of-control unity-container
我们想使用Unity for IOC.我所看到的是有一个全局静态服务(我们称之为IOCService)的实现,它包含对Unity容器的引用,该容器注册所有接口/类组合,每个类都询问该对象:给我一个实现为Ithis或IThat.
我经常看到这种模式不好的响应,因为它导致从ALL类到IOCService的依赖(而不是Unity容器,因为它只在IOCService内部知道).
但我经常看不到的是:替代方式是什么?
米歇尔
编辑:发现全局静态服务被称为服务定位器,将其添加到标题中.
Jef*_*nal 11
另一种方法是仅在最高应用程序级别拥有容器的单个实例,然后使用该容器来解析需要在该层中创建的每个对象实例.
例如,大多数可执行文件的主要方法看起来像这样(减去异常处理):
private static void main(string[] args) {
Container container = new Container();
// Configure the container - by hand or via file
IProgramLogic logic = container.Resolve<IProgramLogic>();
logic.Run();
}
Run Code Online (Sandbox Code Playgroud)
你的程序(在这里由IProgramLogic
实例表示)不需要知道你的容器,因为container.Resolve
它将创建它的所有依赖项 - 及其依赖项的依赖项,而不是它们自己的依赖项.
ASP.NET是一个更难的案例,因为Web表单不支持构造函数注入.我通常在我的Web表单应用程序中使用Model-View-Presenter,因此我的Page
类实际上只有一个依赖项 - 在他们的演示者上.我不单元测试他们(一切有趣和可测试的是在我的演讲,这是我做的测试),并且我从来没有替代主持人.所以我不打击框架 - 我只是在我的HttpApplication
类(在global.asax.cs中)公开一个容器属性,并直接从我的Page
文件中使用它:
protected void Page_Load(object sender, EventArgs args) {
ICustomerPresenter presenter = Global.Container.Resolve<ICustomerPresenter>();
presenter.Load();
}
Run Code Online (Sandbox Code Playgroud)
那当然是服务定位器 - 虽然Page
类是唯一与定位器耦合的东西:您的演示者及其所有依赖项仍然与您的IoC容器实现完全分离.
如果你的文件中有很多依赖项Page
(也就是说,如果你不使用Model-View-Presenter),或者你的Page
类与Global
应用程序类分离很重要,你应该尝试找到一个集成的框架进入Web表单请求管道并使用属性注入(如Nicholas在下面的评论中所建议的) - 或者自己编写并自己IHttpModule
执行属性注入.
知道服务定位器是坏事的 +1 .
问题是 - Unity不是很复杂,所以我不知道用它做正确的IoC是多么容易/多难.
我最近写了几篇博文,你可能会发现它很有用.
而不是显式使用容器,而是通过利用构造函数/属性注入隐式使用它.创建依赖于应用程序所有主要部分的核心类(或核心类集).
大多数容器都会让你ISomething[]
输入构造函数,它会将所有实例注入ISomething
到你的类中.
这样,当您引导应用程序时:
现在,根据您编写的应用程序类型,有不同的策略可以避免将IoC容器标记为"静态".
对于ASP.NET Web应用程序,您可能最终将容器存储在Application State中.对于ASP.NET MVC应用程序,您需要更改Controller Factory.
对于桌面应用程序,事情变得更加复杂. Caliburn使用IResult构造对此问题使用了一个有趣的解决方案(这适用于WPF应用程序,但也可以适用于Windows窗体.
归档时间: |
|
查看次数: |
7174 次 |
最近记录: |