WPF/MVVM:在多个控制器中重用 ViewModel 和关注点分离 [英] WPF/MVVM: Re-use a ViewModel in multiple Controller and Separation of Concerns

查看:85
本文介绍了WPF/MVVM:在多个控制器中重用 ViewModel 和关注点分离的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 AdministrationController 中,我使用了一个 PupilViewModel,例如:

In my AdministrationController I use a PupilViewModel like:

_adminRepo.GetSchoolclassPupilList().ForEach(s =>
            {
                SchoolclassViewModel sVM = new SchoolclassViewModel(s, _adminRepo);

                foreach (PupilViewModel pVM in sVM.PupilListViewModel)
                {
                    pVM.Documents.DeleteDocumentDelegate += new Action<List<Document>>(OnDeleteDocument);
                    pVM.Documents.AddDocumentDelegate += new Action(OnAddDocument);
                    pVM.Documents.OpenDocumentDelegate += new Action<int, string>(OnOpenDocument);
                }
                SchoolclassList.Add(sVM);
            }); 

PupilViewModel 就是这样创建的:

public SchoolclassViewModel(Schoolclass schoolclass, IAdministrationRepository adminRepo)
        {
            _schoolclass = schoolclass;
            _adminRepo = adminRepo;  

            PupilListViewModel = new ObservableCollection<PupilViewModel>();
            schoolclass.Pupils.ForEach(p => PupilListViewModel.Add(new PupilViewModel(p, _adminRepo)));                      
        }

正如您肯定注意到的,PupilViewModel 在其构造函数中采用 2 个参数.重要的是第二个参数,它是一个服务/存储库,具体来说是它的 IAdministrationRepository 实例.

As you surely noticed the PupilViewModel takes 2 paramter in its Constructor. The important one is the 2nd paramter which is a service/repository to be specific its the IAdministrationRepository instance.

现在存在另一个名为 IncidentReportingController控制器.在它的构造函数中,我做的和在 AdministrationController 中的一样:

There exists now another Controller called IncidentReportingController. In its Constructor I do the same as in the AdministrationController:

// When I now try to wrap my pupils into a ViewModel I have a problem:

IEnumerable<Pupil> pupils = incidentRepo.GetPupilIncidentReportDocumentList();         
PupilViewModels = new ObservableCollection<PupilViewModel>(pupils.Select(p => new PupilViewModel(p, ???)));

A.) 我不想将服务传递给 PupilViewModel,因为没有理由更新 PupilViewModel 中的属性,因为它在视图中是只读的.

A.) Either I do not want to pass a Service to the PupilViewModel because there is no reason to update a property i the PupilViewModel as it is readonly in the View.

B.) 在我的 AdministrationController 中,我从这个 Aggregation 的服务中获取数据:1个Schoolclass有N个Pupil,1个Pupil有N个Documents.这些实体被包装成SchoolclassViewmodelsPupilViewModelsDocumentViewModels...

B.) In my AdministrationController I get data from the service from this Aggregation: 1 Schoolclass has N Pupils and 1 Pupil has N Documents. Those entities are wrapped into SchoolclassViewmodels, PupilViewModels and DocumentViewModels...

现在在我的 IncidentController 中,我也从服务中获取数据,并且我的 Aggregation 非常相似:1个Pupil有N个IncidentReports,1个IncidentReport有N个Documents.这些实体被包装成PupilViewModelsIncidentReportViewModelsDocumentViewModels...

Now in my IncidentController I get data from the service too and my Aggregation is pretty similar: 1 Pupil has N IncidentReports and 1 IncidentReport has N Documents. Those entities are wrapped into PupilViewModels, IncidentReportViewModels, DocumentViewModels...

问题是 => 在 PupilViewModel 类中,它已经包装了一个 DocumentListViewModel.现在我再次需要 PupilViewModel 来包装 IncidentReportListViewModel,稍后我又需要 1 个 Pupil 有 1 个 SeatingChair 并再次包装它们.这意味着我必须将三个服务传递给 PupilViewModel,尽管我并不总是需要它们.

PROBLEM is => In the PupilViewModel class it wraps already a DocumentListViewModel. Now I need the PupilViewModel again to wrap a IncidentReportListViewModel and Later again I have 1 Pupil has 1 SeatingChair and wrap those again. That means I have to pass THREE Services to the PupilViewModel although I do not always need them.

我很难直截了当地解决问题,但不知何故,我觉得这不是正确的方法.

Its hard for me to cut right to the chase with the problem but somehow I feel that is not the right way.

那么我如何重用相同的 ViewModel 来包装具有不同服务的不同聚合的实体?

So How do I re-use the same ViewModel which wrap entities with different aggregations having different services?

推荐答案

在不知道你的道路有多远的情况下...我强烈建议你看看 Prism 使用 Unity>.正如 Unity 网站上所述...

Without knowing how far down the path you are...I would highly suggest you take a look at Prism which makes use of Unity. As stated on Unitys web site...

Unity 应用程序块 (Unity) 是轻量级的可扩展依赖注射容器支持构造函数、属性和方法调用注射.

The Unity Application Block (Unity) is a lightweight extensible dependency injection container with support for constructor, property, and method call injection.

在使用这些不同的框架时,您获得的是广泛的解耦和实例化的职责"等.然后,您不再需要担心传递给构造函数的参数,因为框架会为您解析它们.

What you gain when making use of these varying frameworks is the extensive decoupling and the 'duty' of instantiation among other things. You then no longer need to worry about the parameters being passed into the constructor as the framework will resolve them for you.

例如,您还可以将已注册类型(例如 IDoSomethingController)的生命周期设置为实际类型 DoSomethingController...并将其生命周期设置为单例(如果您需要在有人请求时传递单个实例)IDoSomethingController 类型的对象.

You can also for instance set the lifetime of a registered type, say IDoSomethingController, to an actually type, DoSomethingController...and set it's lifetime to behave as a Singleton should you need the single instance being passed around as someone requests an object of type IDoSomethingController.

一旦您使用了这些框架,您就不再是新建"一个实例,而是在利用该框架来提供您正在寻找的重用.

Once you make use of these frameworks you are no longer 'newing' up an instance, you are making use of the framework to provide the reuse that you are looking for.

IDoSomethingController controller = IUnityContainer.Resolve<IDoSomethingController>();

EDIT:既然您说您使用的是 MEFedMVVM;DI 框架存在.您的 PupilViewModel 是 ObservableCollection 的一个实例.这太过分了,通过这个.在您离开之前, ViewModel 应该需要承担额外的重量,只需通过数据即可.您的 ViewModel 似乎试图代表对象与概念.我的意思是,您可以简单地拥有一个 SchoolViewModel 来公开学生、班级等.这些项目成为可以以某种形式聚合到您的 ViewModel 上的模型.ViewModel 旨在成为 View 的中介.它可以包含跨不同模型和服务的大量信息,成为视图的单点数据.

EDIT: Since you stated you are using MEFedMVVM; the DI framework exists. Your PupilViewModel is an instance of an ObservableCollection. This is overkill, pass this through. a ViewModel should need to carry additionally weight before you depart simply passing the data through. Your ViewModels seem to be trying to represent objects verusu concepts. What I mean is that you could simply have a SchoolViewModel which exposes pupils, classes, etc.. Those items become Models which can be aggregated in some form on your ViewModel. The ViewModel is meant to be the mediator to the View. It can contain a wealth of information across varying models and services, becoming a single point of data for the View.

这篇关于WPF/MVVM:在多个控制器中重用 ViewModel 和关注点分离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆