Autofac,WinForms集成问题
本文关键字:成问题 集成 WinForms Autofac | 更新日期: 2023-09-27 18:08:02
我有一个非常简单的WinForms POC利用Autofac和MVP模式。在这个POC中,我通过Autofac的Resolve方法从父窗体打开子窗体。我有问题的是子窗体如何保持开放。在子表单的Display()
方法中,如果我调用ShowDialog()
,子表单将保持打开状态,直到我关闭它。如果我调用Show()
,子窗体闪烁并立即关闭-这显然不是很好。
我已经做了很多关于将Autofac集成到WinForms应用程序中的搜索,但是我没有找到任何关于Autofac/WinForms集成的好例子。
我的问题是:
- 用我的方法显示非模态子表单的正确方法是什么?
- 在WinForms应用程序中是否有比我的方法更好的方法来使用Autofac ?
- 我如何确定没有内存泄漏,Autofac是否正确清理模型/视图/演示者对象的子窗体?
下面只显示相关代码。
谢谢,
凯尔
public class MainPresenter : IMainPresenter
{
ILifetimeScope container = null;
IView view = null;
public MainPresenter(ILifetimeScope container, IMainView view)
{
this.container = container;
this.view = view;
view.AddChild += new EventHandler(view_AddChild);
}
void view_AddChild(object sender, EventArgs e)
{
//Is this the correct way to display a form with Autofac?
using(ILifetimeScope scope = container.BeginLifetimeScope())
{
scope.Resolve<ChildPresenter>().DisplayView(); //Display the child form
}
}
#region Implementation of IPresenter
public IView View
{
get { return view; }
}
public void DisplayView()
{
view.Display();
}
#endregion
}
public class ChildPresenter : IPresenter
{
IView view = null;
public ChildPresenter(IView view)
{
this.view = view;
}
#region Implementation of IPresenter
public IView View
{
get { return view; }
}
public void DisplayView()
{
view.Display();
}
#endregion
}
public partial class ChildView : Form, IView
{
public ChildView()
{
InitializeComponent();
}
#region Implementation of IView
public void Display()
{
Show(); //<== BUG: Child form will only flash then instantly close.
ShowDialog(); //Child form will display correctly, but since this call is modal, the parent form can't be accessed
}
#endregion
}
看下面的代码:
using(ILifetimeScope scope = container.BeginLifetimeScope())
{
scope.Resolve<ChildPresenter>().DisplayView(); //Display the child form
}
首先,使用子生命周期作用域是好的。如果从顶层容器中解析,对象的生存期将与该容器一样长(通常是应用程序的整个生命周期)。
然而,这里有一个问题。当DisplayView
调用Form.Show
时,它立即返回。using
块结束,子作用域被处理,它的所有对象(包括视图)也被处理。
在这种情况下,您不需要using
语句。您需要做的是将子生命周期作用域绑定到视图,以便在视图关闭时,处置子作用域。参见我的另一个答案中的FormFactory
示例。还有其他方法可以将这个想法应用到您的架构中——例如,您可以在注册(ContainerBuilder)中这样做。