sud*_*tti 4 asp.net-mvc lazy-loading inversion-of-control unity-container deferred-loading
我正在使用ASP.NET MVC 4应用程序.
家庭控制器的构造函数参数化为2参数(Iservice1 service1,Iservice2 service2)并非所有代码路径都使用任何Service(service1,service2),只在某些代码路径中我需要service1 instance/object或service2 instance/object.
我不想使用container.Resolve < <Lazy<IService1>>();
从这个链接(http://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx)我明白unity.mvc 4使用unity 3,它具有Lazy loading支持,但是如何在ASP.NET MVC 4中执行此操作.
Ste*_*ven 10
通常,实例构造函数除了执行正确的空检查并存储传入的引用之外,应该做什么.这使得对象图的构造快速且可靠.任何初始化都应该推迟到稍后的时间,即第一次使用组件的时间.
这将是最常见的情况 - 防止延迟创建组件以提高性能,如果这仍然是一个问题,您可能需要考虑具有更好性能的容器.
对于那些需要延迟创建的空闲时刻,请不要使用Lazy<T>.注入Lazy<T>是一个漏洞抽象,就像IDisposable放在接口上一样.注入Lazy<T>泄漏,因为从理论上讲,每个依赖都可能很慢或者可能需要推迟.为了防止在引入较慢的服务实现时在整个应用程序中进行彻底的更改,我们最好先预先确定应用程序中的每个依赖项Lazy<IDependency>,因为这样我们就不必在以后进行更改.
但这当然是愚蠢和丑陋的.但是,即使应用程序足够小,以至于可以负担得起这种彻底的变化,为什么消费者应该知道或关心该服务需要延迟初始化的事实?这不是一个实现细节吗?为什么我们将这种懒惰的行为加入到这项服务的合同中?这样做会使我们的代码和我们需要编写的测试更加复杂.这是不必要的偶然复杂性.
因此Lazy<IService1>,您应该只注入IService1并实现并注册实现惰性行为的代理,而不是注入.这实际上很容易做到如下:
public class LazyService1Proxy : IService1
{
private Lazy<IService1> service;
public LazyService1Proxy(Lazy<IService1> service) {
this.service = service;
}
void IService1.Method1() {
this.service.Value.Method1();
}
object IService1.Method2(string foo) {
return this.service.Value.Method2(foo);
}
}
Run Code Online (Sandbox Code Playgroud)
该代理可以注册如下:
container.Register<IService1>(new InjectionFactory(c =>
new LazyService1Proxy(
new Lazy<IService1>(
() => c.Resolve<RealService1Impl>()))));
Run Code Online (Sandbox Code Playgroud)