1

我正在嘗試在我的新項目中使用模型 - 視圖 - 控制器模式,這是一個Windows Forms C#應用程序。 我有我的項目拆分成若干個子項目:如何管理MVC模式中的多個表單

Core 
UI (View) 
Controller 
Model 
Services 
Helper 
Tests 

項目依賴條件如下:Project Dependencies (generated by Visual Studio

我的UI項目包含2種形式,ListForm和AddForm(還有其他形式,但這些與這個問題無關)。

  • 在控制器項目中,我有不同形式的接口,Controller用於更新視圖。

  • 在Core-Project中,我初始化一個新的ListForm,Controller和Model。

現在,如果用戶單擊ListForm中的Add-Button,我希望AddForm顯示。 但是,如果控制器甚至不知道UI-Project,如何在控制器內創建AddForm的新實例?

我試着使用一個服務,但由於服務必須知道UI-Project來創建實例,所以我會產生循環依賴(根據Visual Studio)。

如何在用戶單擊ListForm內的Add-Button時顯示AddForm? (每次最多顯示1個AddForm)。

+0

我編輯了你的標題。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 –

回答

2

可能的方法之一涉及控制器工廠。工廠負責創建控制器和視圖並將它們連接在一起。

工廠應該是可配置的,因此您可以針對不同的視圖設置不同的實現 - 用於構建實際UI的一組視圖具有自己的工廠,另一個測試集具有另一個工廠等。通過相同的API,以便在必要時只重新配置工廠。實現這種工廠的一種可能的方法是使用IoC容器,它可以簡化實現,但不是必需的。使用IoC容器,您只需註冊視圖的不同實現,並且可以重用工廠的相同實現,而如果沒有IoC容器,則需要爲每組視圖額外實施工廠。

然後,您的父控制器使用工廠創建子控制器的實例。工廠返回注入了正確視圖的子控制器。父控制器調用子控制器上的ShowView,該控件只是使視圖可見,或者子控制器甚至可以在創建時自動顯示視圖。

編輯:例如工廠,創建控制器/意見:

在控制層:

public interface IControllerFactory 
{ 
    TController CreateControllerAndView<TController>() 
     where TController : Controller; 
} 

public class ControllerFactory 
{ 
    // actual provider 
    private static IControllerFactory _provider; 

    // factory method 
    public static TController 
     CreateControllerAndView<TController>() where T : Controller 
    { 
     return _provider.CreateController<TController>(); 
    } 

    public static void SetProvider(IControllerFactory provider) 
    { 
     _provider = provider; 
    } 
} 

任何時候你想創建一個新的控制器,請向工廠:

var controller = ControllerFactory.CreateControllerAndView<UserController>(); 

請注意,工廠不依賴於任何東西,它只是定義,尚未實現。

然後,地方在最上層,在可能啓動項目,你實現一個具體提供者:

public class ConcreteControllerFactory : IControllerFactory 
{ 
    public TController CreateControllerAndView<TController>() 
    { 
     // since you are in the top most layer, you know all types from 
     // underlaying layers, including controllers and views 

     // IoC would help here a lot! But without it: 

     if (typeof<TController> == typeof<UserController>) 
     { 
      IUserView view = new UIUserView(); 
      UserController c = new UserController(view); 
     } 
     ... 
    } 
} 

,然後某處

ControllerFactory.SetProvider(new ConcreteControllerFactory()); 

這樣你可以將任何特定的供應商到工廠,測試提供商,ui提供商,無論如何。實際的實施可能會有所不同,但你應該明白。

+0

在哪個項目中我需要放置這個工廠以避免循環依賴。 另外,我之前沒有使用過「父控制器」。你能解釋一下你的意思嗎(我腦子裏有東西,但我不知道它是否正確)? –

+0

工廠應在您的控制器和UI界面定義的項目中定義。工廠的具體提供者應該在您的「組合根」中實施,即您的解決方案的主要項目。通過「父控制器」,我指的是與父(主)視圖相關的控制器,與「子控制器」相對應,與您即將創建的表單相關聯,並且您詢問了該控制器。 –

+0

我知道什麼是工廠,但工廠的提供者是什麼,它有什麼作用? –

相關問題