Autofac: как ограничить время жизни объекта IDisposable без обхода контейнера IoC
В настоящее время я изучаю, как использовать Autofac, и я застрял с утилизацииIDisposable
объекты детерминистически. Позвольте мне сначала представить ситуацию, прежде чем я изложу свою проблему.
Допустим, моя объектная модель определяется через следующие интерфейсы:
interface IApple : IDisposable
{
void Consume();
}
interface IHorse
{
void Eat(IApple apple); // is supposed to call apple.Consume()
}
interface IHorseKeeper
{
void FeedHorse(); // is supposed to call horse.Eat(apple)
// where 'horse' is injected into IHorseKeeper
// and 'apple' is generated by IHorseKeeper on-the-fly
}
Далее я определяю делегата, который будет использоваться какIApple
завод:
delegate IApple AppleFactory;
Конфигурация Autofac:Теперь я бы зарегистрировал перечисленные выше типы следующим образом - обратите внимание, что я опускаю код обоих классовApple
а такжеHorse
, поскольку они тривиальны для реализации:
var builder = new Autofac.ContainerBuilder();
builder.RegisterType<Apple>().As<IApple>();
builder.RegisterType<Horse>().As<IHorse>();
builder.RegisterType<HorseKeeper>().As<IHorseKeeper>();
builder.RegisterGeneratedFactory<AppleFactory>();
Моя проблема:Я не совсем знаю, как реализовать методIHorseKeeper.Feed
, Вот что у меня сейчас есть:
class HorseKeeper : IHorseKeeper
{
private readonly IHorse horse;
private readonly AppleFactory appleFactory;
public HorseKeeper(IHorse horse, AppleFactory appleFactory)
// ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
// constructor injection
{
this.horse = horse;
this.appleFactory = appleFactory;
}
public void FeedHorse()
{
using (var apple = appleFactory())
{
horse.Eat(apple);
} // <- Dispose() apple now (ASAP), as it's no longer needed!
}
}
Это тот код, который я хотел бы иметь, так как он полностью независим от автофака. Он также может работать с другим контейнером IoC, еслиAppleFactory
работает как положено.
Однако, поскольку Autofac обрабатываетAppleFactory
для меня это будет отслеживать всеIApple
объекты, которые он производит для меня, и поэтому захочетDispose
они сами в конце срока службы контейнера. Т.е. произведеноapple
будет утилизироваться дважды.
Я полагаю регистрацияIApple
как.ExternallyOwned()
не является жизнеспособным решением, так как могут быть случаи, когда Autofac легче обрабатыватьIApple
жизнь
Детерминированная утилизация с помощью Autofac требует создания вложенного контейнера с использованиемcontainer.BeginLifetimeScope()
Однако я не хочу использовать это внутриHorseKeeper.FeedHorse
потому что тогдаHorseKeeper
становится зависимым от Autofac, и я хотел бы сохранить свой код IoC-независимым.
Как мне реализоватьHorseKeeper.FeedHorse
в IoC (Autofac) -агностическом способе, гарантируя, что сгенерированные на лету объекты располагаются должным образом?