WPF MVVM 中 ViewModel 的 Mediatr 通知

Mediatr Notifications on ViewModel in WPF MVVM

在实现 WPF 应用程序时,我偶然发现了我的应用程序在每个 ViewModel 中都需要一些全局数据的问题。但是,一些 ViewModel 只需要读取权限,而其他 ViewModel 需要 read/write 访问此字段。起初,我偶然发现了 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/the 调解器模式的实现 link。我喜欢 Norbert 的设计理念,并考虑为我的项目实施类似的东西。然而,在这个项目中,我已经在使用令人印象深刻的 Mediatr Nuget 包,它也是一个 Mediator 实现。所以我想 "Why reinvent the Wheel" 如果我可以使用一个好的且经过良好测试的 Mediator。但这里开始我真正的问题:如果其他 ViewModel 将对全局数据的更改发送到我的只读 ViewModel,我将使用通知。这意味着:

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 应用程序,该应用程序为它的 Window 之一管理一些全局数据(比如说上面提到的用户名)。这意味着因为我使用的是 DI 容器(并且因为它是什么类型的数据)所以我必须声明服务 @mm8 提议为单例。然而,如果我需要打开一个新的 Window,此时需要不同的全局数据,那会有点问题(我有这种情况)。这意味着我要么需要将生命周期更改为 "kind of scoped" 之类的东西,要么(打破 class 的单一职责)通过为不同的目的添加更多字段,或者我为 n 个可能的 Windows 我可能需要打开。对于拆分服务的第一个想法:我想这样做,因为这会减轻上述所有问题,但这会使数据共享出现问题,因为我不知道将这些全局数据从 Writeservice 传递到readservice,而异步或并行 运行 正在后台线程中发生,这可能会触发 writeservice 更新它的数据。

您可以使用注入视图模型的共享服务。例如,它可以实现两个接口,一个用于写操作,一个只用于读操作,例如:

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) { ... }

该解决方案既使代码易于理解又易于测试。