[英]WPF MVVM PropertyChanged notifications in the ViewModel triggered by Model Events
[英]Mediatr Notifications on ViewModel in WPF MVVM
在实现WPF应用程序时,我偶然发现了我的应用程序在每个ViewModel中都需要一些全局数据的问题。 但是,某些ViewModel仅需要对该字段的读取访问权限,而另一些需要对该字段的读/写访问权限。 最初,我偶然发现了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
}
这(至少在我看来)是无法很好测试的,并且如果我的全局数据增长(这可能会在此应用程序中发生),就会出现问题。 我发现的下一件事情是从此链接实现Mediator / Mediator模式。 我喜欢“设计理念”,诺伯特(Norbert)会在这里思考如何为我的项目实施类似的设计。 但是,在这个项目中,我已经使用了令人印象深刻的Mediatr Nuget包,它也是Mediator的实现。 因此,我想想“为什么要重新发明轮子”,只要我能使用一个经过良好测试的好中介者即可。 但这是我真正的问题:如果其他ViewModel将对全局数据的更改发送到我的Readonly ViewModel,我将使用Notifications。 这意味着:
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;
}
}
现在的问题:1.这是使用MVVM的一种良好实践(感觉这是错误的,因为感觉就像在ViewModel中公开了业务逻辑一样,这是一种感觉)2.有更好的方法对此进行区分,以便我的Viewmodel不需要继承5到6个不同的NotificationHandlers <,>吗?
更新:澄清我想在这里实现的目标:我的目标是实现一个wpf应用程序,该应用程序为其窗口之一管理某些全局数据(如上面所说的用户名)。 这意味着因为我使用的是DI容器(并且由于它是哪种数据),所以我必须将提出的Service @ mm8声明为Singleton。 但是,在某些情况下(我有这种情况)有点问题,我需要打开一个新窗口,此时需要不同的全局数据。 这意味着我要么需要将生存期更改为“某种范围的”,要么(为了打破该类的单一职责),通过为不同目的添加更多字段,或者为n个可能的Windows创建n个服务打开。 关于拆分服务的第一个想法:我想这样做是因为这样可以缓解上述所有问题,但是这会使数据共享成为问题,因为我不知道将这种全局数据从Writeservice传递到数据库的可靠方法。后台线程中发生异步或并行运行时,可能触发readservice更新其数据。
您可以使用注入视图模型的共享服务。 例如,它可以实现两个接口,一个用于写操作,一个仅用于读操作,例如:
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();
}
}
然后,您应该使用IWriteDataService
(和其他具有IReadDataService
)的注入应该具有写访问权限的视图模型:
public ViewModel(IWriteDataService dataService) { ... }
该解决方案既使代码易于理解又易于测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.