Autofac,WinForms集成问题

本文关键字:成问题 集成 WinForms Autofac | 更新日期: 2023-09-27 18:08:02

我有一个非常简单的WinForms POC利用Autofac和MVP模式。在这个POC中,我通过Autofac的Resolve方法从父窗体打开子窗体。我有问题的是子窗体如何保持开放。在子表单的Display()方法中,如果我调用ShowDialog(),子表单将保持打开状态,直到我关闭它。如果我调用Show(),子窗体闪烁并立即关闭-这显然不是很好。

我已经做了很多关于将Autofac集成到WinForms应用程序中的搜索,但是我没有找到任何关于Autofac/WinForms集成的好例子。

我的问题是:

  1. 用我的方法显示非模态子表单的正确方法是什么?
  2. 在WinForms应用程序中是否有比我的方法更好的方法来使用Autofac ?
  3. 我如何确定没有内存泄漏,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
}

Autofac,WinForms集成问题

看下面的代码:

using(ILifetimeScope scope = container.BeginLifetimeScope())
{
    scope.Resolve<ChildPresenter>().DisplayView(); //Display the child form
}

首先,使用子生命周期作用域是好的。如果从顶层容器中解析,对象的生存期将与该容器一样长(通常是应用程序的整个生命周期)。

然而,这里有一个问题。当DisplayView调用Form.Show时,它立即返回。using块结束,子作用域被处理,它的所有对象(包括视图)也被处理。

在这种情况下,您不需要using语句。您需要做的是将子生命周期作用域绑定到视图,以便在视图关闭时,处置子作用域。参见我的另一个答案中的FormFactory示例。还有其他方法可以将这个想法应用到您的架构中——例如,您可以在注册(ContainerBuilder)中这样做。