Mediatr Уведомления о ViewModel в WPF MVVM - PullRequest
0 голосов
/ 27 февраля 2019

При реализации приложения WPF я наткнулся на проблему, заключающуюся в том, что моему приложению нужны глобальные данные в каждой модели представления.Однако некоторым ViewModels требуется только доступ для чтения, в то время как другим нужен доступ для чтения / записи для этого поля.Сначала я наткнулся на идею 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 из этой ссылки .Мне понравилась идея дизайна Норберт собирается здесь и подумывает о реализации чего-то похожего для моего проекта.Однако в этом проекте я уже использую впечатляющий пакет Mediatr Nuget, и это тоже реализация Mediator.Поэтому я подумал «Зачем изобретать Колесо», если бы я мог просто использовать хороший и хорошо проверенный Медиатор.Но здесь начинается мой реальный вопрос: в случае отправки изменений в глобальные данные другими ViewModels в мои ReadMly ViewModels, я бы использовал уведомления.Это означает:

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 служб для n возможных Windows, которые мне могут понадобитьсяоткрыть.К первой идее разделения Сервиса: я хотел бы, потому что это уменьшило бы все вышеупомянутые проблемы, но это сделало бы проблематичным совместное использование Данных, потому что я не знаю надежного способа передачи этих глобальных данных из Сервиса записи вreadservice, когда в фоновом потоке происходит что-то асинхронное или параллельное выполнение, которое может инициировать writeservice для обновления своих данных.

1 Ответ

0 голосов
/ 28 февраля 2019

Вы можете использовать общий сервис, с помощью которого вы внедряете модели представлений.Например, он может реализовать два интерфейса, один для операций записи и один только для операций чтения, например:

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

Это решение облегчает понимание и тестирование кода.

...