[英]Mediatr Notifications on ViewModel in WPF MVVM
While implementing a WPF Application I stumbled on the problem that my application needs some global data in every ViewModel. 在实现WPF应用程序时,我偶然发现了我的应用程序在每个ViewModel中都需要一些全局数据的问题。 However some of the ViewModels only need reading access while other need read/write access for this Field. 但是,某些ViewModel仅需要对该字段的读取访问权限,而另一些需要对该字段的读/写访问权限。 At First I stumbled upon the Microsoft Idea of a SessionContext like so: 最初,我偶然发现了Microsoft的SessionContext想法,如下所示:
public class SessionContext
{
#region Public Members
public static string UserName { get; set; }
public static string Role { get; set; }
public static Teacher CurrentTeacher { get; set; }
public static Parent CurrentParent { get; set; }
public static LocalStudent CurrentStudent { get; set; }
public static List<LocalGrade> CurrentGrades { get; set; }
#endregion
#region Public Methods
public static void Logon(string userName, string role)
{
UserName = userName;
Role = role;
}
public static void Logoff()
{
UserName = "";
Role = "";
CurrentStudent = null;
CurrentTeacher = null;
CurrentParent = null;
}
#endregion
}
This isn't (in my Opinion at least) nicely testable and it gets problematic in case my global data grows (A think that could likely happen in this application). 这(至少在我看来)是无法很好测试的,并且如果我的全局数据增长(这可能会在此应用程序中发生),就会出现问题。 The next thing I found was the implementation of a Mediator/the Mediator Pattern from this link . 我发现的下一件事情是从此链接实现Mediator / Mediator模式。 I liked the Idea of the Design Norbert is going here and thought about implementing something similar for my project. 我喜欢“设计理念”,诺伯特(Norbert)会在这里思考如何为我的项目实施类似的设计。 However in this project I am already using the impressive Mediatr Nuget Package and that is also a Mediator implementation. 但是,在这个项目中,我已经使用了令人印象深刻的Mediatr Nuget包,它也是Mediator的实现。 So I thought "Why reinvent the Wheel" if I could just use a nice and well tested Mediator. 因此,我想想“为什么要重新发明轮子”,只要我能使用一个经过良好测试的好中介者即可。 But here starts my real Question: In case of sending changes to the global data by other ViewModels to my Readonly ViewModels I would use Notifications. 但这是我真正的问题:如果其他ViewModel将对全局数据的更改发送到我的Readonly ViewModel,我将使用Notifications。 That means: 这意味着:
public class ReadOnlyViewModel : NotificationHandler<Notification>
{
//some Member
//global Data
public string Username {get; private set;}
public async Task Handle(Notification notification, CancellationToken token)
{
Username = notification.Username;
}
}
The Question(s) now: 1. Is this a good Practice for using MVVM (It's just a Feeling that doing this is wrong because it feels like exposing Business Logic in the ViewModel) 2. Is there a better way to seperate this so that my Viewmodel doesn't need to inherit 5 to 6 different NotificationHandlers<,>? 现在的问题:1.这是使用MVVM的一种良好实践(感觉这是错误的,因为感觉就像在ViewModel中公开了业务逻辑一样,这是一种感觉)2.有更好的方法对此进行区分,以便我的Viewmodel不需要继承5到6个不同的NotificationHandlers <,>吗?
Update: As Clarification to what I want to achieve here: My Goal is to implement a wpf application that manages some Global Data (lets say a Username as mentioned above) for one of its Window. 更新:澄清我想在这里实现的目标:我的目标是实现一个wpf应用程序,该应用程序为其窗口之一管理某些全局数据(如上面所说的用户名)。 That means because i am using a DI Container (and because of what kind of data it is) that I have to declare the Service @mm8 proposed as a Singleton. 这意味着因为我使用的是DI容器(并且由于它是哪种数据),所以我必须将提出的Service @ mm8声明为Singleton。 That however is a little bit problematic in case (and I have that case) I need to open a new Window that needs different global data at this time. 但是,在某些情况下(我有这种情况)有点问题,我需要打开一个新窗口,此时需要不同的全局数据。 That would mean that I either need to change the lifetime to something like "kind of scoped" or (breaking the single Responsibility of the class) by adding more fields for different Purposes or I create n Services for the n possible Windows I maybe need to open. 这意味着我要么需要将生存期更改为“某种范围的”,要么(为了打破该类的单一职责),通过为不同目的添加更多字段,或者为n个可能的Windows创建n个服务打开。 To the first Idea of splitting the Service: I would like to because that would mitigate all the above mentioned problems but that would make the sharing of Data problematic because I don't know a reliable way to communicate this global data from the Writeservice to the readservice while something async or parallell running is happening in a Background Thread that could trigger the writeservice to update it's data. 关于拆分服务的第一个想法:我想这样做是因为这样可以缓解上述所有问题,但是这会使数据共享成为问题,因为我不知道将这种全局数据从Writeservice传递到数据库的可靠方法。后台线程中发生异步或并行运行时,可能触发readservice更新其数据。
You could use a shared service that you inject your view models with. 您可以使用注入视图模型的共享服务。 It can for example implement two interfaces, one for write operations and one for read operations only, eg: 例如,它可以实现两个接口,一个用于写操作,一个仅用于读操作,例如:
public interface IReadDataService
{
object Read();
}
public interface IWriteDataService : IReadDataService
{
void Write();
}
public class GlobalDataService : IReadDataService, IWriteDataService
{
public object Read()
{
throw new NotImplementedException();
}
public void Write()
{
throw new NotImplementedException();
}
}
You would then inject the view models that should have write access with a IWriteDataService
(and the other ones with a IReadDataService
): 然后,您应该使用IWriteDataService
(和其他具有IReadDataService
)的注入应该具有写访问权限的视图模型:
public ViewModel(IWriteDataService dataService) { ... }
This solution both makes the code easy to understand and easy to test. 该解决方案既使代码易于理解又易于测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.