代码之家  ›  专栏  ›  技术社区  ›  jonathanpeppers

MVVM和DI—如何处理模型对象?

  •  4
  • jonathanpeppers  · 技术社区  · 14 年前

    我使用的是Caliburn和C#,但我觉得这是一个通用的MVVM/DI问题。

    假设我有一个视图模型NoteViewModel,它传递了一个名为Note的模型对象。

    下面是一些代码:

    class NoteViewModel : PropertyChangedBase
    {
      private readonly Note _note;
    
      public NoteViewModel(Note note)
      {
        _note = note;
      }
    
      public string Title
      { 
        get { return _note.Title; } 
        set { _note.Title = value; NotifyOfPropertyChange(() => Title); }
      }
    }
    

    现在这个对象是通过调用new()并传递一个模型对象来创建的。

    好吧,这很好,但是现在我需要添加一个方法,该方法需要从我的DI容器中导入一个类。

    所以我是否只调用ServiceLocator.Current.GetInstance()来获取它?或者我应该设计这个视图模型来通过DI容器创建,并以某种方式设置传递Note对象的方法?

    3 回复  |  直到 14 年前
        1
  •  3
  •   Marco Amendola    14 年前

    Caliburn有一个接口(IHaveSubject及其类型化版本IHaveSubject)来解决这种情况:基本上,它允许在实例化ViewModel之后,通过容器配置一个“subject”:

    class NoteViewModel : PropertyChangedBase, IHasSubject<Note> {
      ...   
    } 
    
    myNoteViewModel = ... //obtain an instance
    myNoteViewModel.WithSubject(new Note());
    

    基础设施。

    在这种情况下,我认为您必须利用DI容器的特殊特性,因为您可能有一些表示“真实”输入参数的构造函数参数,而其他参数可能是服务依赖项。

    http://kozmic.pl/archive/2009/12/24/castle-typed-factory-facility-reborn.aspx

        2
  •  0
  •   herzmeister    14 年前

    你能用层次视图模型解决这个问题吗?

    对我来说,每个视图需要一个ViewModel越来越清楚了 在构建更大的应用程序时,每个模型项或集合有一个ViewModel。

    关于Caliburn,我不知道关于这个框架的任何细节,抱歉。

        3
  •  0
  •   David Lynch    14 年前

    我也在使用ServiceLocator。我也觉得这样做很肮脏。但是我已经决定使用YAGNI原则并保持这种模式,直到我发现一个令人信服的回报:向我的构造函数中添加5个iSeries设备,通过3-4层继承将它们传递到需要它们的基类,并通过容器创建所有东西。当然,我的应用程序在不断发展,而雅格尼并不总是持续下去。。。