繁体   English   中英

WPF MVVM中ViewModel的Mediatr通知

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM