Как мне управлять временем жизни пользовательского IResourceProvider?

Я использовал этот подход для добавления собственного поставщика ресурсов в мое приложение 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 Кажется, я зарегистрировался в контейнере, и его время жизни не было правильно настроено. У него есть некоторые другие собственные зависимости, некоторые из которых имеют несколько сложный образ жизни (на веб-запрос или на транзакцию), поэтому я зарегистрировал IResourceProvider как переходный, чтобы гарантировать, что его зависимости всегда действительны. Но структура MVC наступает на мои пальцы, сохраняя ссылку на IResourceProvider через веб-запросы, что вызывает ObjectDisposedExceptions когда его зависимости были признаны недействительными при следующем запросе.

Что я хотел бы сделать, так это заставить MVC-фреймворк использовать фабрику каждый раз, когда ему нужен экземпляр моего IResourceProviderи - если возможно - также вызывать IoC.Release(provider) или что-то подобное, когда это сделано с этим.

Как мне микро-управлять образом жизни обычая IResourceProvider таким образом, что фреймворк MVC будет уважать?

1 ответ

Решение

После поиска вокруг различных способов контролировать время жизни IResourceProvider Сам я решил, что лучше было бы реорганизовать мою реализацию, чтобы использовать Средство Typed Factory.

мой 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 был подвергнут рефакторингу до трех операторов: получить экземпляр репо с фабрики, использовать экземпляр репо для извлечения / сохранения чего-либо, выпустить экземпляр через фабрику.

Я зарегистрировал их так:

container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IResourceRecordRepositoryFactory>().AsFactory());

Теперь, несмотря на то, что MVC хранит ссылку на моего провайдера ресурсов через веб-запросы, используемые им сервисы повторно выбираются из контейнера Windsor при каждом их использовании, поэтому контейнер полностью контролирует их время жизни.

Другие вопросы по тегам