Autofac: como limitar a vida útil de um objeto IDisposable sem passar pelo contêiner de IoC
No momento, estou aprendendo a usar o Autofac e estou preso ao descarteIDisposable
objetos deterministicamente. Deixe-me apresentar a situação antes de expor meu problema.
Digamos que meu modelo de objeto seja definido através das seguintes interfaces:
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
}
Além disso, defino um delegado que será usado como umIApple
fábrica:
delegate IApple AppleFactory;
Configuração de autofac:Agora, eu registraria os tipos acima da seguinte maneira - observe que estou omitindo o código das duas classesApple
eHorse
, uma vez que são triviais de implementar:
var builder = new Autofac.ContainerBuilder();
builder.RegisterType<Apple>().As<IApple>();
builder.RegisterType<Horse>().As<IHorse>();
builder.RegisterType<HorseKeeper>().As<IHorseKeeper>();
builder.RegisterGeneratedFactory<AppleFactory>();
Meu problema:Eu não sei muito bem como implementar métodoIHorseKeeper.Feed
. Aqui está o que eu tenho atualmente:
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!
}
}
Esse é o tipo de código que eu gostaria de ter, pois é completamente independente do Autofac. Também poderia funcionar com outro contêiner de IoC, desde queAppleFactory
funciona como esperado.
No entanto, como o Autofac lida com oAppleFactory
para mim, ele vai acompanhar tudoIApple
objetos que produz para mim e, portanto, desejaráDispose
eles no final da vida útil do contêiner. Ou seja, o produzidoapple
será descartado duas vezes.
Eu suponho registrarIApple
Como.ExternallyOwned()
não é uma solução viável, pois pode haver casos em que é mais fácil deixar o Autofac lidar comIApple
a vida inteira.
Eliminação determinística com Autofac requer a criação de um contêiner aninhado usandocontainer.BeginLifetimeScope()
, no entanto, eu não quero usar isso dentroHorseKeeper.FeedHorse
porque entãoHorseKeeper
torna-se dependente do Autofac e eu gostaria de manter meu código independente de IoC.
Como faço para implementarHorseKeeper.FeedHorse
de uma maneira magnética de IoC (Autofac), garantindo ao mesmo tempo que os objetos gerados em tempo real sejam descartados corretamente?