我需要在 MVC 应用程序中声明一个对象。这个对象消耗内存,所以我需要在应用程序启动时创建一次,并且在回收之前不会被销毁。对象的相同实例也应该能够跨控制器内的应用程序访问。
我通过使用 InstanceContextMode.Single 在 WCF 服务中使用了这个对象并且效果很好。但是如何使用 MVC?
我需要在 MVC 应用程序中声明一个对象。这个对象消耗内存,所以我需要在应用程序启动时创建一次,并且在回收之前不会被销毁。对象的相同实例也应该能够跨控制器内的应用程序访问。
我通过使用 InstanceContextMode.Single 在 WCF 服务中使用了这个对象并且效果很好。但是如何使用 MVC?
我会实现一个单例模式https://msdn.microsoft.com/en-us/library/ff650316.aspx
如果您使用任何依赖注入容器,那么它们都支持单例实例
因为单例在很大程度上被认为是一种反模式。它们使您的代码难以测试(使用模拟和存根)并创建紧密耦合的代码。
由于这是非常糟糕的做法,因此最好使用 IoC 容器(Unity、SimpleIoC、Autofac 等)来管理容器的生命周期。Unity 3 IoC 容器有一个ContainerControlledLifetimeManager
生命周期管理器,其中对象被创建一次,并且在容器的生命周期内返回相同的实例。
在您的组合根中,您可以这样做(使用IMemoryConsumingService
接口来避免紧密耦合)。然后只需将其注入您的控制器和服务中。Unity 3 的示例(其他 IoC 有类似的程序)。
MemoryConsumingService service = new MemoryConsumingService();
container.RegisterInstance<IMemoryConsumingService>(service);
或者
container.RegisterType<IMemoryConsumingService, MemoryConsumingService(new ContainerControlledLifetimeManager());
编辑:
当你安装 Unity 3.5 + Unity MVC Bootstraper 时,你基本上已经准备好了。
public class UnityConfig
{
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IDriver, Driver>(new ContainerControlledLifetimeManager());
// OR
IDriver driver = new Driver();
container.RegisterInstance<IDriver>(driver);
}
}
在RegisterType
您进行注册的方法中(请查看下面的文档链接,IoC 很难用一个简单的答案来解释它)。较新的 nugetpackages 让您准备就绪,无需任何进一步的更改(添加注册除外)。无需像 Unity 早期那样更改 Global.asax。