![](/img/trans.png)
[英]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.