【问题标题】:MVVM and StructureMap usageMVVM 和 StructureMap 的使用
【发布时间】:2009-07-16 07:47:14
【问题描述】:

我的 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

编辑:我已经为此开放了一个赏金,因为我想要更多的意见。

【问题讨论】:

    标签: wpf mvvm dependency-injection structuremap


    【解决方案1】:

    另一种选择...

    看看这个 LessonViewModel。它只依赖于 Pupils 和 Teachers,对 PupilParents 或任何其他子对象一无所知。

    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
            };
        }
    }
    

    【讨论】:

    • 但是恐怕这太复杂了...最好有一个 EducationFactory 结合所有的工厂。
    【解决方案2】:

    使用依赖注入的好处是,如果 SchoolsViewModel 本身不需要知道,例如,teacherRepository,那么它甚至不需要在构造函数中引用它。即使父视图模型对此一无所知,子视图模型仍然可以获取教师存储库的句柄。这可以防止父 ViewModel 被它并不真正需要的依赖项污染。

    【讨论】:

      【解决方案3】:

      也许我在这里没有看到大局?您不能使用 StructureMap 及其所有基础来为您处理这项肮脏的工作吗?您可以使用 StructureMap 的构造函数注入来处理所有这些工作。通过将接口和它及其子级所依赖的所有接口连接到 StructureMap - 并将各种依赖接口放入需要它们的各种对象的构造函数中......当您实例化对象 1 时,它依赖于对象 2 又依赖于对象 3...StructureMap 将负责这一切。

      也许我错过了什么?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多