我已经this approach在我的ASP.NET MVC应用程序中注入自定义资源提供程序,但是我在对象生存期管理方面遇到了一些问题。
我正在使用Castle Windsor,所以我有以下工厂实施:
public class DefaultResourceProviderFactory : ResourceProviderFactory
{
public override IResourceProvider CreateGlobalResourceProvider(string classKey)
{
// IoC is a static helper class that gives me static access to the
// container. IoC.Resolve<T>(args...) simply calls container.Resolve<T>(args...).
return IoC.Resolve<IResourceProvider>(new { resourceType = "Global" });
}
public override IResourceProvider CreateLocalResourceProvider(string virtualPath)
{
// resourceType
return IoC.Resolve<IResourceProvider>(new { ResourceType = virtualPath });
}
}
但是,我在容器中注册的IResourceProvider
似乎没有正确管理其生命周期。它有自己的一些其他依赖项,其中一些有一些复杂的生活方式(每个Web请求或每个事务),所以我已将IResourceProvider
注册为瞬态,以确保其依赖项始终有效。但是MVC框架正在踩着我的脚趾,在Web请求中保留对IResourceProvider
的引用,这会导致ObjectDisposedExceptions
在下一个请求时其依赖关系失效。
我想做的是让MVC框架每次使用工厂 它需要我IResourceProvider
的一个实例,并且 - 如果可能的话 - 也调用{ {1}}或类似的东西。完成它。
如何以MVC框架将尊重的方式微观管理自定义IoC.Release(provider)
的生活方式?
答案 0 :(得分:1)
在搜索了控制IResourceProvider
本身生命周期的各种方法之后,我认为最好重构我的实现以利用Typed Factory Facility。
我的IResourceProvider
实现以前看起来像这样:
public class CachedResourceProvider : IResourceProvider {
CachedResourceProvider(IResourceRecordRepository repo) { /* ... */ }
// other members...
}
现在,我将其更改为:
public class CachedResourceProvider : IResourceProvider {
CachedResourceProvider(IResourceRecordRepositoryFactory repo) { /* ... */ }
// other members...
}
工厂界面是新界面,定义为
public interface IResourceRecordRepositoryFactory {
IResourceRecord NewInstance();
void Release(IResourceRecord instance);
}
并且_repo
中私有CachedResourceProvider
实例的每次使用都被重构为三个语句:从工厂获取repo实例,使用repo实例获取/保存某些内容,通过工厂。
我是这样注册的:
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IResourceRecordRepositoryFactory>().AsFactory());
现在,即使MVC在Web请求中保留对我的资源提供程序的引用,它使用的服务也会在每次使用时从Windsor容器中重新获取,因此容器可以完全控制它们的生命周期。