为什么Castle.Windsor会解决我的意见?

时间:2014-02-12 17:50:59

标签: c# castle-windsor ioc-container

我有一些现有的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<T>()方法时,Windsor会返回已处理的表单,当MdiParent尝试显示它时会导致ObjectDisposedException

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

1 个答案:

答案 0 :(得分:1)

LifestylePooled可能不是你想要的。

首先,它不会阻止实例化maxSize个以上的对象。它只会维持最多maxSize个热门对象。

第二次发布池化组件可能(取决于池中有多少个对象),只需使该对象可以重用。

如果对象构造起来很昂贵且不能是单例,但可以由不同的组件重用,那么汇总很有用。

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