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

mvvm和structuremap的使用

  •  4
  • Grokys  · 技术社区  · 15 年前

    我的mvvm应用程序中有很多父细节视图模型。像这样的:

    SchoolsViewModel
      +- SchoolViewModel
          +- LessonViewModel
              +- PupilsViewModel
                  +- PupilViewModel
              +- TeacherViewModel
          +- PupilsViewModel
              +- PupilViewModel
                  +- LessonsViewModel
          +- TeachersViewModel
    

    等等…

    此外,一个视图模型可以出现在多个地方,这取决于用户是按课程还是按学生等进行浏览。

    每个子视图模型都是由父视图模型创建的,因此许多视图模型都需要传入子视图模型的依赖项。例如,schoolsviewmodel的构造函数可能是:

    SchoolsViewModel(ISchoolsRepository schoolsRepository,
                     ILessonsRepository lessonsRepository,
                     IPupilsRepository pupilsRepository,
                     ITeachersRepository teachersRepository,
                     ...)
    

    现在,使这一切易于管理的通常方法是使用di框架(如structuremap)将所有必需的参数传递给视图模型。但是,因为在这种情况下,我的应用程序通常只创建schoolsviewmodel,所以它的用途有限。

    我的第一个问题是,在这种情况下,是让schoolsviewmodel将每个依赖项传递给每个子视图模型,还是让每个视图模型使用objectfactory.getInstance()创建子视图模型?也许通过一个工厂类来抽象出对di框架的依赖?

    还有一个问题与此相关: MVVM: locating other ViewModels

    编辑:我已经开奖了,因为我想听听更多的意见。

    3 回复  |  直到 7 年前
        1
  •  1
  •   alex2k8    15 年前

    另一个选择…

    看看这个LessonViewModel。它只取决于学生和老师,对家长或任何其他儿童对象一无所知。

    public class LessonViewModel
    {
        private IPupilsFactory _pupilsFactory;
        private ITeachersFactory _teachersFactory;
    
        public LessonViewModel(IPupilsFactory pupilsFactory, ITeachersFactory teachersFactory)
        {
            _pupilsFactory = pupilsFactory;
            _teachersFactory = teachersFactory;
        }
    
        public string Name { get; set; }
        public List<string> PupilNames { get; set; }
        public string TeacherName { get; set; }
    
        public PupilViewModel GetPupil(string name) 
        {
            return _pupilsFactory.Create(name);
        }
    
        public TeacherViewModel GetTeacher()
        {
            return _teachersFactory.Create(TeacherName);
        }
    }
    

    课程工厂包含所有必需的依赖项,但它也不了解pupilparents。

    public interface ILessonsFactory
    {
        LessonViewModel Create(string name);
    }
    
    public class LessonsFactory : ILessonsFactory
    {
        private ILessonsRepository _lessonsRepository;
        private IPupilsFactory _pupilsFactory;
        private ITeachersFactory _teachersFactory;
    
        public LessonsFactory(ILessonsRepository lessonsRepository, IPupilsFactory pupilsFactory, ITeachersFactory teachersFactory)
        {
            _lessonsRepository = lessonsRepository;
            _pupilsFactory = pupilsFactory;
            _teachersFactory = teachersFactory;
        }
    
        public LessonViewModel Create(string name)
        {
            Lesson lesson = _lessonsRepository.Read(name);
    
            return new LessonViewModel(_pupilsFactory, _teachersFactory) {
                Name = lesson.Name,
                PupilNames = lesson.PupilNames,
                TeacherName = lesson.TeacherName
            };
        }
    }
    
        2
  •  0
  •   Scott Whitlock    15 年前

    使用依赖注入的好处是,如果schoolsviewmodel本身不需要知道teachersrepository,那么它甚至不需要在构造函数中引用它。尽管家长对此一无所知,但孩子的viewmodel仍然能够处理teachersrepository。这可以防止父视图模型被它并不真正需要的依赖项污染。

        3
  •  0
  •   Andrew Siemer    15 年前

    也许我没有看到这里的大局?你不能用structuremap和它的所有基础来帮你处理这些肮脏的工作吗?您可以使用structuremap的构造函数注入来处理所有这些工作。通过连接一个接口以及它和它的子接口依赖于structuremap的所有接口,并将各种依赖接口放入需要它们的各种对象的构造函数中……当实例化依赖于对象2的对象1时,对象2又依赖于对象3……structuremap将把一切都搞定。

    也许我遗漏了什么?