我有一些现有的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
),但即使不推荐这种特殊用法,行为似乎也是如此很难解释。
答案 0 :(得分:1)
LifestylePooled可能不是你想要的。
首先,它不会阻止实例化maxSize
个以上的对象。它只会维持最多maxSize
个热门对象。
第二次发布池化组件可能(取决于池中有多少个对象),只需使该对象可以重用。
如果对象构造起来很昂贵且不能是单例,但可以由不同的组件重用,那么汇总很有用。
满足您要求的一种方法是使用LifestyleTransient并自行进行引用计数。 Show中的增量。减少关闭。当您的参考计数达到零时释放。这不是使用容器的最佳方式,但由于您已经在Service Locator anti pattern道路上行驶,因此可以接受。