我目前正在学习如何使用 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!
}
}
这是我想要的那种代码,因为它完全与 Autofac 无关。只要AppleFactory
按预期工作,它也可以与另一个 IoC 容器一起工作。
然而,因为 AutofacAppleFactory
为我处理,它会跟踪它为我生成的所有对象,因此在容器的生命周期结束时会自己IApple
想要它们。Dispose
即,生产的产品apple
将被处理两次。
我认为注册IApple
为.ExternallyOwned()
不是可行的解决方案,因为在某些情况下,让 Autofac 处理IApple
s 的生命周期可能更容易。
使用 Autofac 进行确定性处理需要使用创建嵌套容器container.BeginLifetimeScope()
,但是我不想在内部使用它,HorseKeeper.FeedHorse
因为那样HorseKeeper
会依赖于 Autofac,并且我想保持我的代码与 IoC 无关。
问题:
如何HorseKeeper.FeedHorse
以与 IoC (Autofac) 无关的方式实现,同时确保正确处理动态生成的对象?