2010-01-15 35 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

相关问题