我有一个界面和一个打字的工厂界面:
public interface ITransientItem : IDisposable
{
void DoWork(WorkItem item);
}
public interface ITransientItemFactory : IDisposable
{
ITransientItem Create();
void Destroy(ITransientItem item);
}
然后我有另一个接口IDependencyOwner : IDisposable
的实现,它由以下实现:
public class DependencyOwner: IDependencyOwner
{
private ITransientItemFactory _factory;
public DependencyOwner(ITransientItemFactory factory)
{
_factory = factory;
}
public void PostWork(WorkItem workItem)
{
ITransientItem item = _factory.Create();
item.DoWork(workItem); //this is done on a seperate thread
_factory.Destroy(item);
}
public void Dispose()
{
//first wait for running items to dispose
//then do disposal stuff
}
}
DependencyOwner
对另一个对象持有依赖关系,并且可以有许多DependencyOwner实现,它们使用CollectionResolver
子解析器解析。但我不认为这与这个问题有关。它的构造函数如下:
public TopLevel(IDependencyOwner[] dependencies)
容器注册如下所示:
WindsorContainer container = new WindsorContainer();
container.AddFacility(new TypedFactoryFacility());
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
container.Register(Component.For<TopLevel>());
container.Register(Component.For<IDependencyOwner>().ImplementedBy<DependencyOwner>();
//there will be more IDependencyOwner Implementations in the future
container.Register(Component.For<ITransientItem>().ImplementedBy<TransientItem>()
.LifeStyle.Transient);
container.Register(Component.For<ITransientItemFactory>().AsFactory());
TopLevel top = container.Resolve<TopLevel>();
实际运行代码的一切都很好。是时候关闭程序了。
在调用DependencyOwner的Dispose方法之前ITransientItemFactory
正在被处理掉(我已经通过在dispose方法的第一行放置一个断点然后检查我的日志以查看错误已经验证了这一点当下)。这会导致处理过程中的任何workItem失败,程序崩溃而不是优雅地结束。
我得到的例外是:
System.ObjectDisposedException:工厂处理完毕,但没有 更长时间使用。对象名称:'this'。
为什么温莎不尊重这种依赖?
编辑:我偶然发现了this trick,并且能够确认工厂确实出现在依赖图中,作为DependencyOwner的依赖。
编辑2:我刚刚自己实施了工厂并拆除了打印的工厂。这解决了我的问题(因为依赖被尊重),但如果我能避免它,我宁愿不这样做。仅出于说明的目的,在这种情况下的注册成为:
WindsorContainer container = new WindsorContainer();
//container.AddFacility(new TypedFactoryFacility());
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));
container.Register(Component.For<TopLevel>());
container.Register(Component.For<IDependencyOwner>().ImplementedBy<DependencyOwner>();
//there will be more IDependencyOwner Implementations in the future
//No reason to register it anymore, it will never be instantiated by the container
//container.Register(Component.For<ITransientItem>().ImplementedBy<TransientItem>()
//.LifeStyle.Transient);
//container.Register(Component.For<ITransientItemFactory>().AsFactory());
container.Register(Component.For<ITransientItemFactory>()
.ImplementedBy<FactoryImplementation>());
TopLevel top = container.Resolve<TopLevel>();
答案 0 :(得分:1)
我为此提供了一个修复程序,该修复程序已在Castle.Windsor 4.1.0中发布!
https://github.com/castleproject/Windsor/pull/344
https://github.com/castleproject/Windsor/releases/tag/v4.1.0