2013-04-08 70 views
3

我有一個非常簡單的WinForms POC利用Autofac和MVP模式。在此POC中,我通過Autofac的Resolve方法從父窗體打開子窗體。我遇到的問題是孩子的形式如何保持開放。在兒童表格的Display()方法中,如果我打電話給ShowDialog(),那麼子表格將保持打開狀態,直到我將其關閉。如果我撥打Show(),孩子表格會閃爍並立即關閉 - 這顯然不好。Autofac和WinForms集成問題

我已經做了很多關於將Autofac集成到WinForms應用程序的搜索,但是我還沒有在Autofac/WinForms集成上找到任何好的例子。

我的問題是:

  1. 什麼是顯示與我的做法非模態子窗體的正確方法?
  2. 在WinForms應用程序中使用Autofac比我的方法更好嗎?
  3. 如何確定沒有內存泄漏,並且Autofac正在清理子窗體的Model/View/Presenter對象?

只有相關的代碼如下所示。

感謝,

凱爾

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 

} 

回答

2

看看這段代碼:

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

首先,這是件好事,你用一個孩子一生的範圍。如果您解決了頂級容器之外的問題,那麼這些對象將與該容器(通常是應用程序的整個生命週期)一樣長。

但是,這裏有一個問題。當DisplayView調用Form.Show時,它立即返回。 using塊結束,子範圍被丟棄,並且其所有對象(包括視圖)也被丟棄。

在這種情況下,您不需要using聲明。你想要做的是將子生命週期範圍綁定到視圖,以便在視圖關閉時處理子範圍。示例見the FormFactory in one of my other answers。還有其他一些方法可以將此想法應用於您的架構 - 例如,您可以在註冊(ContainerBuilder)中執行此操作。