TypedFactory在组件将其用作依赖项之前进行处置

pqu*_*est 5 c# castle-windsor

我有一个接口和一个类型化的工厂接口:

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)

jnm*_*nm2 1

我\xe2\x80\x99 已经为此贡献了一个修复程序,该修复程序已在 Castle.Windsor 4.1.0 中提供!

\n\n

https://github.com/castleproject/Windsor/pull/344
\n https://github.com/castleproject/Windsor/releases/tag/v4.1.0

\n