0

我已经采用这种方法在我的 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 框架踩到了我的脚,保持对IResourceProvider跨 Web 请求的引用,这会导致ObjectDisposedExceptions它的依赖关系在下一个请求时失效。

我想做的是让 MVC 框架在每次需要 my 的实例时都使用工厂IResourceProvider,并且 - 如果可能的话 - 也可以在完成时调用IoC.Release(provider)或类似的东西。

如何IResourceProvider以 MVC 框架尊重的方式对自定义的生活方式进行微观管理?

4

1 回答 1

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 容器中重新获取,因此容器可以完全控制它们的生命周期。

于 2014-11-03T12:24:18.993 回答