Unity.MVC4惰性T在ASP.NET MVC应用程序中无法正常工作 [英] Unity.MVC4 lazy<T> is not working in ASP.NET MVC app

查看:108
本文介绍了Unity.MVC4惰性T在ASP.NET MVC应用程序中无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用ASP.NET MVC 4应用程序.

家用控制器的构造函数使用2个参数(Iservice1 service1,Iservice2 service2)进行了参数化 并非所有代码路径都使用任何服务(service1,service2),仅在某些代码路径中,我需要service1实例/对象或service2实例/对象.

我不想使用容器.解决< >();

通过此链接( http://msdn .microsoft.com/en-us/library/dn178463(v = pandp.30).aspx )我了解unity.mvc 4使用了具有惰性加载支持的unity 3,但是如何在ASP中做到这一点. NET MVC 4.

解决方案

通常,实例构造函数只应该执行适当的null检查并存储传入的引用.这样可以快速且可靠构造对象图.任何初始化都应推迟到组件首次使用的时间.

在大多数情况下,这将防止需要延迟创建组件来提高性能,并且如果这确实仍然是一个问题,则您可能要考虑使用具有泄漏抽象,就像IDisposable放在接口上一样.注入Lazy<T>会泄漏,因为从理论上讲,每个依赖关系可能都很慢,或者可能需要推迟.为了避免在引入较慢的服务实现时必须在整个应用程序中进行更改,我们最好预先将应用程序中的每个依赖项设为Lazy<IDependency>,因为这样可以避免我们日后进行更改. /p>

但这当然是愚蠢和丑陋的.但是,即使应用程序很小,以至于可以承受如此巨大的变化,为什么消费者仍应该知道或关心服务需要延迟初始化的事实?这不是实现细节吗?我们为什么将这种懒惰的行为纳入这项服务的合同中?这样做会使我们的代码和需要编写的测试变得更加复杂. 偶然的复杂性.

因此,您不必注入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);
    }
}
 

此代理可以按以下方式注册:

 container.Register<IService1>(new InjectionFactory(c => 
    new LazyService1Proxy(
        new Lazy<IService1>(
            () => c.Resolve<RealService1Impl>()))));
 

I am using ASP.NET MVC 4 application.

Home controller’s constructor is parameterized with 2 parameter(Iservice1 service1, Iservice2 service2) Not all the code path uses any of the Service (service1, service2), only in some code path I need service1 instance/object or service2 instance/object.

I don’t want to use container.Resolve<<Lazy<IService1>>();

From this link (http://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx) I understood that unity.mvc 4 use unity 3 which has Lazy loading support, but how to do this in ASP.NET MVC 4.

解决方案

In general, instance constructors should do nothing more than do the proper null checks and store the incoming references. This makes construction of object graphs fast and reliable. Any initialization should be postponed to a later moment in time, the time the component is used for the first time.

This will in -most cases- prevent the need from delaying creation of a component for performance and if this really still is a problem, you might want to consider a container that has better performance.

For those spare moments that you need to delay the creation, don't use a Lazy<T> for this. Injecting Lazy<T> is a leaky abstraction, just as IDisposable is when placed on interfaces. Injecting a Lazy<T> leaks, because in theory, every dependency could be slow or could need to be postponed. To prevent having to make sweeping changes throughout the applications when a slower implementation of a service is introduced, we'd better make every dependency in the application a Lazy<IDependency> up front, because this saves us from having to make changes later on.

But that's of course silly and ugly. But even when the application is small enough that such sweeping change is affordable, why should the consumer know or care about the fact that that service needs lazy initialization? Isn't that an implementation detail? Why are we baking this lazy behavior into the contract of this service? Doing so makes our code and the tests we need to write more complicated. That's unneeded accidental complexity.

So instead of injecting a Lazy<IService1>, you should simply inject an IService1 and implement and register a proxy that implements lazy behavior. That's actually really easy to do as follows:

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);
    }
}

This proxy can be registered as follows:

container.Register<IService1>(new InjectionFactory(c => 
    new LazyService1Proxy(
        new Lazy<IService1>(
            () => c.Resolve<RealService1Impl>()))));

这篇关于Unity.MVC4惰性T在ASP.NET MVC应用程序中无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆