2010-01-15 64 views
5

我有兩種初始化WPF CAL MVVM中的Views和ViewModels的方法。什麼是在WPF CAL中初始化模型和視圖的正確方法MVVM

1 - 似乎更受歡迎。要求您解析ViewModel以自動解析視圖。 ViewModel包含有關視圖的信息。

public interface IView 
    { 
     void SetModel(IViewModel model); 
    } 

    public interface IViewModel 
    { 
     IView View { get; } 
    } 

    public class View 
    { 
     public void SetModel(IViewModel model) 
     { 
      this.DataContext = model; 
     } 
    } 

    public class ViewModel 
    { 
     private IView view; 

     public ViewModel(IView view) 
     { 
      this.view = view; 
     } 

     public IView View { return this.view; } 
    } 

2 - 看起來很乾淨,並從ViewModel中刪除視圖。要求您解析視圖以自動解析ViewModel。將對象注入視圖(不知道這是否好)。

public interface IView 
    { 
    } 

    public interface IViewModel 
    { 
    } 

    public class View 
    { 
     private IViewModel model; 

     public View(IUnityContainer unityContainer) 
     { 
      this.model = unityContainer.Resolve<IViewModel>(); 
      this.DataContext = this.model; 
     } 
    } 

    public class ViewModel 
    { 
    } 

什麼是初始化視圖和模型的可接受方法,以及每種方法的優點和缺點是什麼。你應該將物體注入視圖嗎?

回答

3

它們都是有效的,但#1趨於更容易測試(它至少讓你的測試更簡潔)。 #2的優勢在於它更加明確,並使維護更清晰一些,特別是當你有很多營業額時,這種事情。採取較少的解釋(雖然這不是採用它的理由,但這只是一個真理)。

區別在於#1被稱爲依賴注入#2被稱爲服務位置。他們經常感到困惑,因爲他們通常都會使用某種IoC容器(儘管這不一定是這種情況)。

這是一個偏好問題,但正如我所說,我認爲你會發現#1更容易測試......你不必在測試/嘲諷中涉及IUnityContainer接口。

1

選項1看起來是正確的,給視圖引用viewmodel。

雖然具有引用的視圖模型回到視圖看起來有點可疑。這看起來更像是一個模型 - 視圖 - 演示者類型的體系結構。如果您的視圖模型與視圖重疊並且需要對視圖的引用,那麼您可能會更好地將視圖模型分割爲純粹用於數據綁定的視圖模型和執行更復雜交互的演示者。

選項2看起來不正確。將ioc容器的引用傳遞給類是我書中的一個大代碼。應該儘量減少對IoC容器的調用。在我的大部分應用程序中,我只在程序開始時調用容器來連接一些東西。更動態的對象創建通常使用工廠類來完成。

+0

選項1視圖屬性已被發現由我在各種例子,但我同意,它不應該在那裏。 – anon 2010-01-15 15:49:36

2

我寧願定義XAML視圖模型,並提供類型訪問一個只讀屬性:

<UserControl ...> 
    <UserControl.DataContext> 
     <local:MyViewModel/> 
    </UserControl.DataContext> 

    ... 

</UserControl> 

public partial class MyView : UserControl, IMyView 
{ 
    public MyViewModel ViewModel 
    { 
     get { return this.DataContext as MyViewModel; } 
    } 

    ... 
} 
+0

+1爲只讀屬性 – 2010-07-31 02:28:29

1

該代碼的問題在於,選項2的烘焙程度超過了需要。它確實不需要也​​不應該有對容器的引用。

另一種允許選項2是作爲可測試的選項1,但在視圖模型從來不知道有關視圖概念更加清晰。

,如果你想使用XML文件,而不是使用棱鏡的區域,它允許你使佈局易於配置指定佈局這是特別有用。

備選:

public interface IView 
{ 
} 

public interface IViewModel 
{ 
} 

public class View : IView 
{ 
    private IViewModel model; 

    public View(IViewModel m) 
    { 
     this.model = m; 
     this.DataContext = this.model; 
    } 
} 

public class ViewModel : IViewModel 
{ 
} 

和其他地方你必須:

Container.RegisterType<IViewModel, ViewModel>(/* appropriate container config */); 
Container.RegisterType<IView, View>(/* appropriate container config */); 

,你可以在任何地方創建一個視圖具有:

Container.Resolve<IViewModel>(); 
+0

+1注意類型解析不是視圖的工作。我也使用這種方法,並喜歡它。 – RMart 2011-07-21 13:02:40

相關問題