2010-05-03 40 views
3

我正在學習將MVP應用於C#中一個簡單的WinForms應用程序(只有一種形式),並在static void Main()中創建主要演示者時遇到問題。爲了將它作爲參數提供給Application.Run(),從Presenter公開一個View是否是一個好主意?應如何爲MVP WinForms應用程序的主要演示者調用Application.Run()?

目前,我實現了一個辦法,讓我不暴露查看演示的屬性:

static void Main() 
    { 
     IView view = new View(); 
     Model model = new Model(); 
     Presenter presenter = new Presenter(view, model); 
     presenter.Start(); 
     Application.Run(); 
    } 

啓動和停止方法主講人:

public void Start() 
    { 
     view.Start(); 
    } 

    public void Stop() 
    { 
     view.Stop(); 
    } 

開始和視圖中的Stop方法(Windows窗體):

public void Start() 
    { 
     this.Show(); 
    } 

    public void Stop() 
    { 
     // only way to close a message loop called 
     // via Application.Run(); without a Form parameter 
     Application.Exit(); 
    } 

Application.Exit()調用似乎是關閉窗體(和應用程序)的一種不雅的方式。另一種方法是將View作爲Presenter的公共屬性公開,以便使用Form參數調用Application.Run()。

static void Main() 
    { 
     IView view = new View(); 
     Model model = new Model(); 
     Presenter presenter = new Presenter(view, model); 
     Application.Run(presenter.View); 
    } 

Presenter中的啓動和停止方法保持不變。額外的屬性添加到返回查看錶單:

public void Start() 
    { 
     view.Start(); 
    } 

    public void Stop() 
    { 
     view.Stop(); 
    } 

    // New property to return view as a Form for Application.Run(Form form); 
    public System.Windows.Form View 
    { 
     get { return view as Form(); } 
    } 

的啓動和停止方法在View(Windows窗體)將被寫成如下:

public void Start() 
    { 
     this.Show(); 
    } 

    public void Stop() 
    { 
     this.Close(); 
    } 

任何人都可以建議哪些是更好的方法,爲什麼?或者有更好的方法來解決這個問題?

+0

我感謝羅傑,Heinzi和妮可爲自己寶貴的意見,但我選擇了Heinzi的答案終於因爲我已經適應了他的答案用兩個額外的接口IMainPresenter和IMainView我的實際應用。 – anonymous 2010-05-12 03:29:39

回答

9

什麼如下:

// view 
public void StartApplication() // implements IView.StartApplication 
{ 
    Application.Run((Form)this); 
} 

// presenter 
public void StartApplication() 
{ 
    view.StartApplication(); 
} 

// main 
static void Main()  
{  
    IView view = new View();  
    Model model = new Model();  
    Presenter presenter = new Presenter(view, model);  
    presenter.StartApplication();  
}  

這樣,你不需要暴露欣賞到外面。另外,觀點和主持人都知道這個觀點已經開始作爲一個「主要形式」,這可能是一個有用的信息。

+1

IMO,演示者或視圖界面都不應該知道如何啓動windows消息泵。 您只會用不存在的方法膨脹IView接口,如果您正在編寫針對僞視圖的測試,則必須實施該方法。 – 2010-05-05 15:26:58

+1

將爲視圖和演示者創建另一個接口,例如IMainView,IMainPresenter僅專門處理StartApplication()和StopApplication()。所以View將實現Iview和IMainView,Presenter將實現IMainPresenter。 – anonymous 2010-05-07 01:34:10

+1

@羅伯斯先生:這是個好主意。您甚至可以製作IView和IPresenter的IMainView和IMainPresenter子接口,因爲IMainView始終是IView(與Presenter相同)。 – Heinzi 2010-05-07 05:37:11

5

我會去第二種方法。 你也可以通過簡單地將視圖轉換爲void Main來形成額外的屬性,因爲無論如何你都知道它是一種形式(我沒有理由使它更通用,因爲它只是啓動winform APP)

Application.Run(view as Form); 
1

如果您允許多種方式退出應用程序(例如:用於退出的菜單項),或者您在特定條件下阻止關閉應用程序,情況會變得更復雜。在任何一種情況下,應用程序關閉的實際調用通常應從演示者代碼中調用,而不是簡單地關閉具體視圖。這可以通過使用Application.Run()或Application.Run(ApplicationContext)重載並通過控制反轉公開應用程序退出操作來完成。

註冊和使用應用程序退出操作的確切方法將取決於您正在使用的IoC機制(例如:服務定位器和/或依賴項注入)。因爲你沒有提到你的現任國際奧委會的做法可能是什麼,這裏有一個樣本這是獨立於任何特定的IoC框架的:

internal static class Program 
{ 
    [STAThread] 
    private static void Main() 
    { 
     ApplicationActions.ExitApplication = Application.Exit; 

     MainPresenter mainPresenter = new MainPresenter(new MainView(), new Model()); 
     mainPresenter.Start(); 

     Application.Run(); 
    } 
} 

public static class ApplicationActions 
{ 
    public static Action ExitApplication { get; internal set; } 
} 

public class MainPresenter : Presenter 
{ 
    //... 

    public override void Stop() 
    { 
     base.Stop(); 

     ApplicationActions.ExitApplication(); 
    } 
} 

這種基本方法可以很容易地適應您的首選IoC機制。例如,如果您使用服務定位器,則可能需要考慮至少移除ApplicationActions.ExitApplication屬性上的setter,然後將該委託存儲在服務定位器中。如果ExitApplication getter仍然存在,它將爲服務定位器實例檢索器提供一個簡單的外觀。例如: -

public static Action ExitApplication 
{ 
    get 
    { 
     return ServiceLocator.GetInstance<Action>("ExitApplication"); 
    } 
} 
+0

最初,我打算將Application.Exit()放置在presenter.Stop()中,但隨後決定禁止它,因爲這會在用於實現視圖的技術(例如演示者中的WinForms)上創建依賴項。在此期間我會研究IoC - 以任何方式用一些僞代碼來說明它? – anonymous 2010-05-07 01:28:56

+0

實現的哪個部分需要示例? – 2010-05-11 13:53:10

+0

Application.Exit()部分的IoC部分會很好。謝謝! – anonymous 2010-05-12 02:04:29

相關問題