c# – Autofac:如何限制IDisposable对象的生命周期,而不会绕过I
我正在学习如何使用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; 自动配置配置: 现在,我将注册以上类型如下 – 请注意,我省略了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-agnostic.只要AppleFactory可以按预期工作,它可以与另一个IoC容器一起工作. 然而,由于Autofac为我处理AppleFactory,它将跟踪它为我生成的所有IApple对象,因此将在容器的生命周期结束时自己处理它们.也就是说,生产的苹果将被处理两次. 我想将IApple注册为.ExternallyOwned()不是可行的解决方案,因为可能会更容易让Autofac处理IApples的生命周期. Deterministic disposal with Autofac需要使用container.BeginLifetimeScope()创建一个嵌套的容器,但是我不想在HorseKeeper.FeedHorse中使用它,因为这样HorseKeeper将依赖于Autofac,我想保持我的代码IoC-agnostic. 题: 如何在IoC(Autofac)诊断方式下实现HorseKeeper.FeedHorse,同时确保即时生成的对象被正确放置? 解决方法
其他答案在这里是有洞察力的,但有一个问题.在这两种情况下,如果苹果有其他依赖需要处理,则不会发生正确的清理.
Autofac 2提供了一个新的功能来帮助这里称为“拥有的实例”.我注意到你的注册码是Autofac 1.4,所以如果你无法升级让我知道(还有其他的,透明度较低的方法) 像往常一样注册苹果(不是外部拥有的): builder.RegisterType<Apple>().As<IApple>(); 将AppleFactory声明为: public delegate Owned<IApple> AppleFactory(); 在Autofac 2中,您不需要再调用RegisterGeneratedFactory() – 这是自动的. 然后,在HorseKeeper,喂马像这样: public void FeedHorse() { using (var apple = appleFactory()) { horse.Eat(apple.Value); } } (注意.Value属性来获取底层的IApple. 在使用块的末尾,苹果加上其所有依赖项,将被清理掉. 直接使用IApple(作为依赖)的任何其他组件将获得通常的行为. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |