我有一个接口和一个类型化的工厂接口:
public interface ITransientItem : IDisposable
{
void DoWork(WorkItem item);
}
public interface ITransientItemFactory : IDisposable
{
ITransientItem Create();
void Destroy(ITransientItem item);
}
Run Code Online (Sandbox Code Playgroud)
然后,我有了另一个接口的实现,该接口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
}
}
Run Code Online (Sandbox Code Playgroud)
该DependencyOwner对象具有另一个对象的依赖关系,并且可以有许多DependencyOwner实现,这些实现可以通过CollectionResolverSub Resolver 进行解析。但我认为这与这个问题无关。其构造函数如下所示:
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>();
Run Code Online (Sandbox Code Playgroud)
实际运行代码的一切都很好。问题是该关闭程序了。
该ITransientItemFactory是越来越布置之前DependencyOwner的Dispose方法甚至被称为(我已经通过戴上Dispose方法的第一行设置一个断点,然后再检查我的日志来查看错误已经存在验证了这一点)。这将导致处理过程中的所有workItem失败,并且程序崩溃而不是正常结束。
我得到的异常是:
System.ObjectDisposedException:工厂已经处置,不能再使用。对象名称:“ this”。
温莎为什么不尊重这种依赖性?
编辑:我在这里偶然发现了这个技巧,并且已经能够确认工厂确实以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>();
Run Code Online (Sandbox Code Playgroud)
我\xe2\x80\x99 已经为此贡献了一个修复程序,该修复程序已在 Castle.Windsor 4.1.0 中提供!
\n\nhttps://github.com/castleproject/Windsor/pull/344
\n https://github.com/castleproject/Windsor/releases/tag/v4.1.0