【问题标题】:Why is Castle.Windsor resolving my disposed views?为什么 Castle.Windsor 解决了我处置的意见?
【发布时间】:2014-02-12 17:50:58
【问题描述】:

我有一些现有的 MDI WinForms 代码,它使用 Windsor 来解析这样的子表单:

private void Show<T>() where T : IMdiChildView
{
    var view = _windsorContainer.Resolve<T>();
    view.Closed += (sender, args) => _windsorContainer.Release(view);
    view.Show(this);
}

视图注册一个 IWindsorInstaller 像这样:

public class ViewInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Classes.FromAssemblyContaining(typeof(IView)).BasedOn(typeof(IView))
                                  .WithServiceAllInterfaces().LifestylePooled(1));
    }
}

LifestylePooled(1) 的原因是当子视图打开时,应该只有一个。这可能是使用LifestylePooled 的错误方式? LifestyleTransient 不会发生这种情况,但是当存在一个表单时,我们不希望创建任何新表单,并且在处理每个表单时,它们只是坐在容器中占用内存。

最简单的视图没有其他依赖项,但是当我们关闭它并随后再次调用Show&lt;T&gt;() 方法时,Windsor 会返回已处理的表单,当 MdiParent 尝试显示它时会导致 ObjectDisposedException

我开始认为在这个项目中使用 Windsor 是有缺陷的(我已经认识到它被用作 ServiceLocator),但即使不推荐这种特殊用法,这种行为似乎也很难解释。

【问题讨论】:

    标签: c# castle-windsor ioc-container


    【解决方案1】:

    LifestylePooled 可能不是您想要的。

    首先,它不会阻止实例化多个maxSize 对象。它只会保持高达maxSize 热对象准备就绪。

    第二次释放一个池化组件可能(取决于池中有多少对象)只是使该对象可供重用。

    如果您的对象构建起来很昂贵并且不能是单例但可以被不同的组件重用,则池化非常有用。

    满足您的要求的一种方法是使用 LifestyleTransient 并自己进行引用计数。显示中的增量。关闭时递减。当您的参考计数达到零时释放。这不是使用容器的最佳方式,但由于您已经在Service Locator anti pattern 道路上,所以它可能是可以接受的。

    【讨论】:

    • 如果你想做引用计数一次性用品,我强烈建议你使用System.Reactive.Disposible.RefCountDisposable
    猜你喜欢
    • 1970-01-01
    • 2022-01-14
    • 2017-08-01
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    • 1970-01-01
    • 2015-03-18
    相关资源
    最近更新 更多