С Новым годом! Форум программистов, компьютерный форум, киберфорум
ООП и паттерны
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 140
1

Правильная архитектура приложения по паттерну MVVM

28.08.2024, 13:55. Показов 895. Ответов 17
Метки c#, mvvm (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте.
Объясните, пожалуйста, как должна выглядеть правильная архитектура приложения, из чего состоять и тд и тп.
В MVVM приложение делить на 3 слоя View, Model и ViewModel . Вопрос - каждый из слоев должен быть отдельным проектом в решении или достаточно разделить на папки в одном проекте? Также Model должна ли еще делиться на уровни (на сколько я понимаю да), уровень доступа к данным DAL, уровень бизнес логики BLL. Это в свою очередь также нужно делать на несколько проектов?

Как должно выглядеть решение? Проект с view, проект с VM, проект M который также разделен на несколько проектов для BLL и DAL? Также слышал про разные сервисы , которые должны например создавать нужные окна и тому подобное, что это за сервисы в каком уровне они должны храниться?

Если есть ссылки на статьи или литературу, которая поможет это все понять пришлите, пожалуйста
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.08.2024, 13:55
Ответы с готовыми решениями:

Правильная архитектура MVVM
Здравствуйте. Пытаюсь на примере своего реального проекта реализовать паттерн MVVM. Вроде бы с...

Правильная архитектура приложения
По порядку, есть устройство с 2мя сетевыми картами. Есть 2 класса Управление 1 и Управление 2,...

EJB правильная архитектура приложения
Добрый день! Посоветуйте, пожалуйста, где можно найти (почитать, посмотреть код...) правильные...

Правильная архитектура API приложения
Всех притствую. Я не имею опыта разработки, и мне задали курсовую работу, повязаную с API, и не...

17
Модератор
Эксперт функциональных языков программирования
3077 / 2226 / 462
Регистрация: 26.03.2015
Сообщений: 8,626
29.08.2024, 16:55 2
Зависит от разных факторов - тип проекта, размер, язык...

Самый простой подход - если не знаете, зачем разбивать на проекты, держите всё в одном.

Обычно делят на ядро (Model) и интерфейс (View и ViewModel ). Чтобы можно было использовать ядро отдельно интерфейса.

И так далее. Сначала причина - потом деление.

Например, если есть код, который используется в нескольких проектах, то его стоит вынести в отдельный проект (библиотеку).

Например, если если есть код Х, который использует только некоторую часть библиотеки, которую по смыслу можно выделить из библиотеки, то стоит разбить её на две. Особенно, если это позволит коду Х не тащить ненужные ему ссылки (например, на SQL Client или Web).
0
Модератор
Эксперт .NET
15836 / 10984 / 2852
Регистрация: 21.04.2018
Сообщений: 32,243
Записей в блоге: 2
13.10.2024, 19:10 3
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
Правильная архитектура приложения по паттерну MVVM
99% реализаций MVVM - это C#+ XAML платформа.
MVVM, собственно, и разработан был как разновидность MV* адаптированная под WPF.

Структура WPF решения
Структура WPF+БД решения
Структура связей в WPF Решении
Потоки в асинхронном MVVM
0
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 140
17.10.2024, 09:36  [ТС] 4
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Структура связей в WPF Решении
спасибо за ссылки. есть уточнения.
если создавать отдельный проект например .net standart в котором будут храниться все интерфейсы необходимых приложению сервисов, и из каждого слоя ссылаться на этот проект и делать реализацию нужного сервиса. то все слои будут зависеть от этой библиотеки. разве это не будет нарушением DI? расширить - добавить интерфейс и где-то в нужном модуле реализовать да без проблем, но не получится без проблемно заменить эту библиотеку другой

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Структура WPF+БД решения
правильно понимаю, что 1 проект это wpf в котором view, viewmodel и model и еще 2 проекта для бизнес логики и работы с бд?
что подразумевается под моделью? просто набор классов , которые необходимы для отображению во view? или там должна быть какая-то логика?
Что из себя представляет контекстная модель для работы с хранилищем?
0
Модератор
Эксперт .NET
15836 / 10984 / 2852
Регистрация: 21.04.2018
Сообщений: 32,243
Записей в блоге: 2
17.10.2024, 23:02 5
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
то все слои будут зависеть от этой библиотеки. разве это не будет нарушением DI?
А при чём здесь DI ?
Где в паттерне MVVM, есть хоть слово о DI?

Если не говорит о самых простых задачах, то ОДНОЙ общей библиотеки на все слой никогда не будет.
Будет какая-то общая библа, к ней будут библы для слоёв, в реализации слоя тоже будут библы.
Даже на схеме Оконное приложение с учётом MVVM. Алгоритм конструирования для латунных чайников для каждого слоя указана своя библа.

Суть этих библ только в замене сильных связей на слабые.
В MVVM оговорены функции слоёв и как они связываются друг с другом. Но смысл это приобретает только в том случае, когда каждый слой можно заменить на другую реализацию, не трогая, не изменяя другие слои. Даже если это изменение требует только пересборки с новой связью. Реализовать это можно только убрав сильные связи между слоями. А для этого требубются какие-то внешние библы, которые необходимы и достаточны для выполнения требования по связям между слоями. В них находятся интерфейсы (или базовые классы) для "морд" слоёв и типы необходимые для работы этих интерфейсом (типы общего применения: DTO, реже POCO). Теже штеб double, string - это тоже типы общего применения, которые может использвоать любой слой.
В самых простых сучаях, дробить эти (кастомные) интерфейсы и типы по нескольким сборкам не имеет смысла. Поэтому при реализации все эти библы могут быть объединены в одной сборке. Это не нарушение MVVM. Это допустимое упрощение реализации с учётом требований реальной, конкретной задачи. Но повторюсь. На практике такое встречается только в очень небольших задачах, приложениях.

Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
расширить - добавить интерфейс и где-то в нужном модуле реализовать да без проблем,
Все межуровневые интерфейсы создаются на этапа проектирования архитектуры под определённое ТЗ.
"Расширить" межуровневый интерфейс - это изменение архитектуры приложения. И такое может случиться только, если сильно неправильно была спроектирована архитектура, либо существенно изменилось ТЗ.

Условно.
Изменение внутри слоёв - это изменение подверсии приложения: 1.1, 1.2, 1.3 и т.д.
А изменение взаимодействия между слоями это изменение версии 1.х, 2.х, 3.х и т.д.
Одна версия от другой может отличаться настолько, что общее между ними будет только название.


Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
Цитата Сообщение от Элд Хасп Посмотреть сообщение
правильно понимаю, что 1 проект это wpf в котором view, viewmodel и model и еще 2 проекта для бизнес логики и работы с бд?
Нет.
Обратите внимание, что там написано "Десктоп ПРИЛОЖЕНИЕ".
А приложение имеет свою многослойную архитектуру с несколькими сборками. И три сборки View, Model и ViewModel - это просто тот минимум который обозначен на схеме, который необходим для разъяснения обсуждаемоего там вопроса.

Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
что подразумевается под моделью?
Вся логика по работе с данными, кроме её части относящейся к сохранению-восстановлению данных.

Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
Что из себя представляет контекстная модель для работы с хранилищем?
Ну, допустим Entity Framework и/или ADO.

Добавлено через 4 минуты
В теме Пример создания приложения "Работа с комнатами в студенческих общежитиях" [WPF, SQLite, Элд Хасп] прочитайте ближайшие посты до и после указанного. Там идёт обсуждение деталей, почему так, а не этак. Очень существенно вклад в разъяснения внёс Usaga.
0
Модератор
Эксперт функциональных языков программирования
3077 / 2226 / 462
Регистрация: 26.03.2015
Сообщений: 8,626
18.10.2024, 09:57 6
Тут главное не путать два разных вопроса: декомпозиция кода по классам и разнесение этих классов по разным сборкам. В простых случаях всё находится в одной-двух сборках, но все "слои" при этом никуда не деваются.
0
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 140
18.10.2024, 11:36  [ТС] 7
Цитата Сообщение от Элд Хасп Посмотреть сообщение
А при чём здесь DI ?
так тут MVVM postgres на скриншоте указано "App(приложение) все зависимости внедряются здесь" это разве не DI?
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Но смысл это приобретает только в том случае, когда каждый слой можно заменить на другую реализацию, не трогая, не изменяя другие слои. Даже если это изменение требует только пересборки с новой связью. Реализовать это можно только убрав сильные связи между слоями.
как это можно реализовать? добавить для каждого слоя свой интерфейс? если да, то где должны храниться эти интерфейсы? вероятно в отдельном проекте, но этот отдельный проект какого типа должен быть WPF, .Net Standart? у меня есть сервисы для работы с окнами, например , который должен получить на вход VM и по ней выдать нужную View, сервис для логирования
и надо как-то сделать так чтобы модель была минимально связана с VM, а VM с view чтоб при необходимости можно было заменить 1 модуль совершенно другим (если я правильно понимаю суть MVVM)
0
Модератор
Эксперт .NET
15836 / 10984 / 2852
Регистрация: 21.04.2018
Сообщений: 32,243
Записей в блоге: 2
18.10.2024, 12:19 8
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
все зависимости внедряются здесь" это разве не DI?
DI - это один из инструментов для внедрения зависмостей (см. Пример реализации однооконного и мультиоконного Представления для одних и тех же Модели и ViewModel [WPF, Элд Хасп]) :
Внедрение зависимостей может быть таким:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
using Model;
using Simplified;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
using ViewModel;
using Views;
 
namespace MultiWindows
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private readonly IAuthorizationModel model;
        private readonly IAuthorizationViewModel vm;
 
        // "Слабая" таблица для хранения пар "команда-делегат подъёма RequerySuggested".
        // Такая таблица позволяет удалить мусорщику RelayCommand, если она больше нигде не используется.
        private readonly ConditionalWeakTable<RelayCommand, EventHandler> commands = new();
 
        public App()
        {
            model = new AuthorizationModel();
            vm = new AuthorizationViewModel(model, RegisterCommand);
 
            // Прослушка сообщений для их вывода в отдельном Окне.
            vm.PropertyChanged += (sender, args) =>
            {
                if (args.PropertyName == nameof(IAuthorizationViewModel.Message))
                {
                    MessageBox.Show(vm.Message, "Последнее сообщение");
                }
            };
        }
 
        /// <summary>Платформозависимая часть инициализации команды.</summary>
        /// <param name="command">Инициализируемая команда.</param>
        private void RegisterCommand(RelayCommand command)
        {
            if (!commands.TryGetValue(command, out EventHandler? requerySuggested))
            {
                requerySuggested = delegate { command.RaiseCanExecuteChanged(); };
 
                // Подписка, которая используется только в WPF для автоматического
                // обновления состояния команды при действиях пользователя в GUI.
                CommandManager.RequerySuggested += requerySuggested;
 
                // Маршалин (при необходимости) CanExecuteChanged в UI поток.
                // Необходим только для WPF платформы.
                command.PreviewCanExecuteChanged += (s, e) =>
                {
                    if (!Dispatcher.CheckAccess())
                    {
                        e.Handled = true;
                        Dispatcher.Invoke(command.RaiseCanExecuteChanged);
                    }
                };
 
                commands.Add(command, requerySuggested);
            }
        }
 
        private void OnStartup(object sender, StartupEventArgs e)
        {
            // Окно для Представления Авторизации
            var window = new Window { DataContext = vm, Content = new AuthorizationUC() };
            MainWindow = window;
 
            // Делегат для прослушки INotifyPropertyChanged.PropertyChanged
            PropertyChangedEventHandler eventHandler = (sender, args) =>
            {
                // Проверка произошла ли авторизация.
                if (args.PropertyName == nameof(IAuthorizationViewModel.IsAuthorized) && vm.IsAuthorized)
                {
                    // Если произошла, то закрытие окна авторизации с маршалингом в UI поток.
                    if (Dispatcher.CheckAccess())
                    {
                        window.Close();
                    }
                    else
                    {
                        Dispatcher.Invoke(window.Close);
                    }
                }
            };
 
            // Подключение делегата прослушки.
            vm.PropertyChanged += eventHandler;
 
            // Прослушка события "закрывается" (Closing) окна.
            // Событие "закрыто" (Closed) не подходит так как в нём уже проходит сигнал к закрытию приложения.
            window.Closing += (s, e) =>
            {
                // Если авторизация произошла, то открытие рабочего окна.
                if (vm.IsAuthorized)
                {
                    MainWindow = new Window { DataContext = vm, Content = new WorkUC() };
                    vm.PropertyChanged -= eventHandler;
                    MainWindow.Show();
                }
                else
                {
                    e.Cancel = ! (MessageBox.Show("Точно хотите выйти из приложения?", "Приложение закрывается", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
                }
            };
            MainWindow.Show();
        }
 
    }
 
}
Добавлено через 17 минут
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
как это можно реализовать? добавить для каждого слоя свой интерфейс? если да, то где должны храниться эти интерфейсы?
Интерфейс или реже базовый класс (обычно абстрактный).
Храниться в общей библиотеке. Но в данном случае "общая библиотека" - это не обязательно одна сборка.

Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
вероятно в отдельном проекте, но этот отдельный проект какого типа должен быть WPF, .Net Standart?
Лучше всегда стараться делать Standard 2.0 - так как это обеспечит максимальную платформонезависимость.
Если не получается по каким-то причинам, то 2.1. Если и это не выходит то уже тогда .Net 6 или 8. Платформозависимые классы лучше делать в отдельных сборках от платформонезависимых.

Например, часто в WPF используется реализация команд использующая CommandManager - это "чисто" WPF класс. И такую реализацию лучше делать в отдельной сборке, предназначенной тольке для WPF.
1
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 140
18.10.2024, 12:57  [ТС] 9
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Храниться в общей библиотеке. Но в данном случае "общая библиотека" - это не обязательно одна сборка.
что имеется в виду под сборкой, что-то я запутался. Есть же решение, в котором уже различные проекты (модули, например). или сборка это и есть проект?

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Если не получается по каким-то причинам, то 2.1. Если и это не выходит то уже тогда .Net 6 или 8. Платформозависимые классы лучше делать в отдельных сборках от платформонезависимых.
если я правильно понял, то те сервисы (зависимости в виде интерфейсов), которые зависят от wpf делать в одном проекте библиотека WPF, а те что не зависят ни от чего , в библиотеке на .net standart?

а как должна выглядеть абстракция для UI (IView или IWindow)? что должно быть в этом интерфейс , ведь в классе окна у наc по хорошему не должно быть никакого кода.

с абстракцией к VM вроде понятно, в интерфейсе указать хотя бы 1 метод или команду и свойство, который точно должен присутствовать в VM.

а вот с абстракцией model также как и с VM? 1 какой-то класс , который должен реализовать интерфейс с методом, например, buildTree?
0
Модератор
Эксперт .NET
15836 / 10984 / 2852
Регистрация: 21.04.2018
Сообщений: 32,243
Записей в блоге: 2
18.10.2024, 13:10 10
В коде выше используется платформонезависмая реализация команды.
Зависимость команды с CommandManager создаётся уже в рантайм:
C#
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
        /// <summary>Платформозависимая часть инициализации команды.</summary>
        /// <param name="command">Инициализируемая команда.</param>
        private void RegisterCommand(RelayCommand command)
        {
            if (!commands.TryGetValue(command, out EventHandler? requerySuggested))
            {
                requerySuggested = delegate { command.RaiseCanExecuteChanged(); };
 
                // Подписка, которая используется только в WPF для автоматического
                // обновления состояния команды при действиях пользователя в GUI.
                CommandManager.RequerySuggested += requerySuggested;
 
                // Маршалин (при необходимости) CanExecuteChanged в UI поток.
                // Необходим только для WPF платформы.
                command.PreviewCanExecuteChanged += (s, e) =>
                {
                    if (!Dispatcher.CheckAccess())
                    {
                        e.Handled = true;
                        Dispatcher.Invoke(command.RaiseCanExecuteChanged);
                    }
                };
 
                commands.Add(command, requerySuggested);
            }
        }
0
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 140
18.10.2024, 14:55  [ТС] 11
Элд Хасп, посмотрел ваш пример, получается что для view не надо никакой абстракции делать (не нужно создавать интерфейсы)?

никак не могу вникнуть в то, что должно быть в модели.
допустим, до этого я использовал для себя понятие объектная модель, то есть создавал папку ObjectModel создавал в ней нужные мне классы (например, User, MyObject, TreeObject) и вот при старте приложения нужно создать и заполнить эти классы, из базы взял данные. (работа с базой отдельный модуль) с этими данными нужно что-то сделать проверить, еще что-то - вот эта работа должна делаться в модели? или в отдельном проекте бизнес-логики? или во вью-модели? или в класс MyObject помимо свойств добавить методы по получению всех данных?
0
Модератор
Эксперт функциональных языков программирования
3077 / 2226 / 462
Регистрация: 26.03.2015
Сообщений: 8,626
18.10.2024, 15:03 12
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
или сборка это и есть проект?
Упрощённо говоря, да.
1
Модератор
Эксперт .NET
15836 / 10984 / 2852
Регистрация: 21.04.2018
Сообщений: 32,243
Записей в блоге: 2
18.10.2024, 18:16 13
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
посмотрел ваш пример, получается что для view не надо никакой абстракции делать (не нужно создавать интерфейсы)?
В MVVM - нет. View здесь верхний слой паттерна.
В MVC и MVP - надо.

Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
что имеется в виду под сборкой,
Основные моменты упрощённо.
Проект - это Source Code (Исходные коды).
Проект может быть типа "Библиотека" или "Приложение".
Проект компилируется в CIL-сборку. Для Библиотеки в *.dll, для приложения в *.exe. Exe-сборка может использоваться и как библиотека.
Решение - это просто набор проектов.
У сборок есть зависимости друг от друга. Те из них которые задаются в проектах и "жёстко" зафиксированы в скомпилированном коде называются "Сильными". Для их изменения нужна перекомпилиция проекта в новую сборку.
Те зависимости которые создаются (корректнее - внедряются) в рантайм - называются "слабыми", поскольку они позволяют динамически при обращении к сборке настроить эти зависимости. И для их изменения не требуется перекомпиляции исходных кодов.

В контексте MVVM мы говорим за СЛОИ. Слой - это не обязательно одна сборка. Может быть и несколько. Поэтому "Слой Библиотека" - это не обязательно "1 сборка библиотека". Это могут быть и отдельные сборки которыми пользуются не все, а только часть других сборок.

Добавлено через 10 минут
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
а как должна выглядеть абстракция для UI (IView или IWindow)?
Хоть это часто используется, но это "ни есть хорошо". Такие интерфейсы специфичны для MVC, MVP. И "перетекли" в MVVM.
В MVVM, например, внедряются диалоги (через делегаты обратного вызова, события, сервисы, DI - роли это не имеет). А что там за диалогом скрыто - не должно иметь значения. Это может быт открытие Окна, а может быть получение данных "с Луны".

Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
если я правильно понял, то те сервисы (зависимости в виде интерфейсов), которые зависят от wpf делать в одном проекте библиотека WPF
Какой сервис?
Если для каких-то внутренних View функций - да. Правда не пойму зачем там может сервис понадобиться.
Для взаимодействия между слоями - однозначно нет.

Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
ведь в классе окна у наc по хорошему не должно быть никакого кода
MVVM не определяет правила реализации внутри слоёв.
То о чём вы пишите это рекомендация (а иногда и корпоративные правила) "Не использовать Code Behind". Code Behind в WPF - это любой Шарп-код в классе инициализация, которого происходит посредством XAML части.
В других типах WPF шарп код используется очень мнгого. Без него невозможна реализация: конвертеров, Custom Control, Расширений разметки, навигаторов и многого другого.

Добавлено через 2 минуты
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
абстракцией к VM вроде понятно, в интерфейсе указать хотя бы 1 метод или команду и свойство, который точно должен присутствовать в VM.
Все свойства к которым будет осуществлять привязка должны быть определены в интерфейсе VM. Не только свойства - все члены которые будут использоваться в View. Но в связи со спецификой платформы, кроме свойств VM в WPF редко что используется.

Добавлено через 1 час 9 минут
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
что должно быть в модели.
Модель в концепции MVVM это слой со всей Бизнес Логикой. В том числе к нему относятся: нужные мне классы (например, User, MyObject, TreeObject), работа с базой отдельный модуль, с этими данными нужно что-то сделать проверить и т.д.
Для упрощения часто под моделью понимают не весь слой, а только ту его часть через которую с ней взаимодействуют внешние потребители (в том числе ViewModel). Возможно ваш класс MyObject и есть этот фасад за которым будет инкапсулирована вся остальная логика.
2
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 140
20.10.2024, 12:07  [ТС] 14
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Какой сервис?
например, выбор нужного окна по переданной в него vm. ведь vm не должна ничего знать про окна, а когда вызываешь 1 окно из другого, вызов происходит из vm.

сейчас стало чуть больше понятно.
а что обычно в приложении по mvvm могут заменить? понятно что модуль получения данных, он может поменяться (БД, xml-файл еще что-то). Модель врятли, так это основа нашего приложения, замени модель - это уже новое приложение. а вот view могут решить поменять, например, захотят чтобы это было и wpf приложение и например web то есть надо заменить view как можно добиться легкости такой замены?
0
Модератор
Эксперт .NET
15836 / 10984 / 2852
Регистрация: 21.04.2018
Сообщений: 32,243
Записей в блоге: 2
20.10.2024, 12:48 15
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
например, выбор нужного окна по переданной в него vm.
Это функция View.
В теме на которую давал ссылку, есть пример реализации: Пример реализации однооконного и мультиоконного Представления для одних и тех же Модели и ViewModel [WPF, Элд Хасп]

Никаких IView, IWindow и подобных View интерфейсов и сервисов создавать и передавать в VM для этого не нужно.

Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
а что обычно в приложении по mvvm могут заменить?
Реализация по паттерну должна быть такой, что позволяет независимо заменить любой слой. В этом весь смысл паттернов семейства MV*.
Другое дело что на практике, для упрощения часто допускают нарушения паттерна.

В теме по ссылке выше я показал как заменить View на принципиально другой.
Сегодня постарюсь дополнить ещё и UWP-View, если время будет.

В другой теме я показал пример смены Репозитория: Пример создания приложения "Работа с комнатами в студенческих общежитиях" [WPF, SQLite, Элд Хасп]

Сейчас я тоже работаю над проектом Avalonia, где три разных репозитория: XML, JSON и SQLite.
И две разные модели: одна работает только на просмотр - для пользователей, вторая для админа - с редактированием и настройками.

Добавлено через 13 минут
Цитата Сообщение от Элд Хасп Посмотреть сообщение
одна работает только на просмотр - для пользователей, вторая для админа - с редактированием и настройками.
Как я писал в сообщении выше, Решение - это набор проектов.
Поэтому в одном решении может быть НЕСКОЛЬКО проектов-приложений.

Например в Пример реализации однооконного и мультиоконного Представления для одних и тех же Модели и ViewModel [WPF, Элд Хасп] для разных GUI (одно или много оконный) созданы два разных проекта-решений.
Но коды (компоновки приложения) в них динамические. Поэтому не проблема совместить их в одном решении, при старте читать какие-то настройки и запускать GUI в нужном режиме.
Даже можно сделать консольное приложение, которые позволит выбирать между UWP и WPF GUI.
1
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 140
20.10.2024, 13:01  [ТС] 16
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Это функция View.
В теме на которую давал ссылку, есть пример реализации
либо я слишком не внимательный, либо не смог понять.
вы имете в виду вот это?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Прослушка события "закрывается" (Closing) окна.
            // Событие "закрыто" (Closed) не подходит так как в нём уже проходит сигнал к закрытию приложения.
            window.Closing += (s, e) =>
            {
                // Если авторизация произошла, то открытие рабочего окна.
                if (vm.IsAuthorized)
                {
                    MainWindow = new Window { DataContext = vm, Content = new WorkUC() };
                    vm.PropertyChanged -= eventHandler;
                    MainWindow.Show();
                }
                else
                {
                    e.Cancel = ! (MessageBox.Show("Точно хотите выйти из приложения?", "Приложение закрывается", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
                }
            };
если да, то это же не во вью происходит, а стартовом классе приложения.
а если мне надо открыть окно не при закрытии второго, а чтобы они вместе были открыты?
И еще момент, если я делаю не приложение WPF, а библиотеку классов WPF (плагин для другого приложения), то есть точкой входа в приложение, будет старт из другого приложения.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Сейчас я тоже работаю над проектом Avalonia, где три разных репозитория: XML, JSON и SQLite.
И две разные модели: одна работает только на просмотр - для пользователей, вторая для админа - с редактированием и настройками.
тоже сейчас хочу сделать 2 режима работы, для админа и просто пользователя. как это можно реализовать, обязательно ли 2 модели если объекты будут одинаковые , только возможности разные? и view будут разные
0
Модератор
Эксперт .NET
15836 / 10984 / 2852
Регистрация: 21.04.2018
Сообщений: 32,243
Записей в блоге: 2
20.10.2024, 14:15 17
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
обязательно ли 2 модели если объекты будут одинаковые , только возможности разные? и view будут разные
Зависит от требований безопасности.
Можно в настройках поставить галочки, или ввести разные роли для пользователей и использовать одну модель.

В моём случае требуются именно разные модели, так как админ - это мой заказчик и его сотрудники могут вносить изменения. А пользователи - это его клиенты, которым в принципе не должна быть доступна функция изменений.

Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
вы имете в виду вот это?
Это одна из возможных реализаций.
Она может быть реализована как на уровне View, так и на уровне App. App "знает всё и про всех". Поэтому может "залезть" в любой слой и делать там что угодно. Другое дело, что это тоже должно быт в разумных рамках. В моём примере функцию создания окон было разумно разместить в App поскольку больше ничего в нём и нет, собственно говоря.

Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
а если мне надо открыть окно не при закрытии второго, а чтобы они вместе были открыты?
Но есть же какое-то действие, событие по которому нужно открыть другое окно.
В моём примере - это действие "закрытие окна авторизации".
Там же в примере есть вывод окна сообщений, которое происходит без закрытия текущего окна:
C#
29
30
31
32
33
34
35
36
            // Прослушка сообщений для их вывода в отдельном Окне.
            vm.PropertyChanged += (sender, args) =>
            {
                if (args.PropertyName == nameof(IAuthorizationViewModel.Message))
                {
                    MessageBox.Show(vm.Message, "Последнее сообщение");
                }
            };
Добавлено через 4 минуты
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
И еще момент, если я делаю не приложение WPF, а библиотеку классов WPF (плагин для другого приложения), то есть точкой входа в приложение, будет старт из другого приложения.
Роли это не играет.
Главное правильно запустить WPF часть.
Пример запуска из консольного приложения есть в этом посте: Пример создания приложения "Работа с комнатами в студенческих общежитиях" [WPF, SQLite, Элд Хасп]

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using StudentDormitories;
using System;
using System.CodeDom.Compiler;
using System.Diagnostics;
 
namespace SQLiteModel
{
    class Program
    {
        /// <summary>
        /// Application Entry Point.
        /// </summary>
        [STAThread()]
        [DebuggerNonUserCode()]
        [GeneratedCode("PresentationBuildTasks", "4.0.0.0")]
        static void Main(string[] args)
        {
 
            ModelSQLite model = new ModelSQLite("DefaultConnection");
 
            App app = new App(model);
 
            app.InitializeComponent();
            app.Run();
        }
    }
}
0
Модератор
Эксперт функциональных языков программирования
3077 / 2226 / 462
Регистрация: 26.03.2015
Сообщений: 8,626
20.10.2024, 15:15 18
Цитата Сообщение от IIIIIIIIIgor Посмотреть сообщение
тоже сейчас хочу сделать 2 режима работы, для админа и просто пользователя. как это можно реализовать
Лучше 2 разных приложения, использующих одну и ту же Модель (Бизнес Логику). И, возможно, Вы захотите сделать для них разные методы авторизации.
0
20.10.2024, 15:15
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.10.2024, 15:15
Помогаю со студенческими работами здесь

Правильная архитектура ASP.net приложения с wcf
Нужна помощь... Есть задание создать asp.net сайт, сервер учета wcf, и база mssql... Нужно...

Правильная архитектура Android приложения, использующего restful api
Добрый день! есть задача написать приложение. Главный функционал- отображение данных из БД. БД...

Архитектура консольного приложения по типу паттернов MVVM, MVC, MVP
Добрый день! Есть всякие паттерны MVVM, MVC, MVP но они не предназначены для консольного...

Некоторые вопросы по паттерну MVVM
Элд Хасп, .... Да, поэтому и написал, что говнокод, ибо не у кого спросить многие вещи помимо...

Создание диалоговых окон, согласно паттерну MVVM
Заинтересовался темой создания диалоговых окон, согласно паттерну MVVM. Пожалуй самый простой ...

В указанном dsn архитектура драйвера и архитектура приложения не соответствуют друг другу
Добрый день. При запуске программы выскакивает вот такая вот ошибка. В чем может быть проблема и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru