Unity.MVC4 lazy<T> 在 MVC 应用程序中不起作用 ASP.NET



我使用的是ASP.NET MVC 4应用程序。

主控制器的构造函数是用2个参数参数化的(Iservice1 service1,Iservice2 service2)并不是所有的代码路径都使用任何服务(service1、service2),只是在某些代码路径中我需要service1实例/对象或service2实例/对象。

我不想使用集装箱。解决<<Lazy<IService1>>();

从此链接(http://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx)我知道unity.mvc 4使用了支持Lazy加载的unity 3,但如何在ASP.NET mvc 4中做到这一点。

通常,实例构造函数只应执行正确的null检查并存储传入引用。这使得对象图的构建快速而可靠。任何初始化都应该推迟到稍后的时间,即组件首次使用的时间。

在大多数情况下,这将防止为了性能而延迟创建组件的需要,如果这仍然是一个问题,您可能需要考虑具有更好性能的容器。

对于那些需要延迟创建的空闲时间,不要使用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) => this.service.Value.Method2(foo);
}

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

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

由于我不知道如何在DI注册级别上实现延迟加载,我经常使用这种方式来延迟加载服务。我会和你分享我的方法。

每个服务接口都将继承IService接口,该接口是所有服务接口的基础。

public interface IService
{
// I just want to be sure I'm instantiating ONLY services types.
// This is my base interface 
}
public interface IMyService : IService
{
void DoSomeWork();
}

然后,每个服务都将实现自己的接口:

public class MyService : IMyService
{
public void DoSomeWork()
{
// Some action performed.
}
}

我的抽象BaseController类实现了这个逻辑

public abstract class BaseController : Controller
{
public T LoadService<T>() where T : IService
{
return (T)System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(T));
}
}

最后,在继承BaseController的控制器中,我可以做到这一点:

public class TestController : BaseController
{
// Only parameterless constructor exists created by the compiler.
[HttpPost]
public ActionResult PerformWork()
{
var testService = LoadService<IMyService>();
testService.DoSomeWork();
return View();
}
}

我很想看看延迟加载服务的更好实现,或者了解如何使用Unity或Ninject在类型注册级别上实现延迟加载。

最新更新