powered by simpleCommunicator - 2.0.19     © 2024 Programmizd 02
Map
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Реализация MVVM с несколькими разными хранилищами данных
25 сообщений из 25, страница 1 из 1
Реализация MVVM с несколькими разными хранилищами данных
    #40053587
КириллН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Коллеги, приветствую!
Посмотрел на YT несколько курсов лекций по теме, прочитал нескоько статей на Хабре и тематических ресурсах, но так и не принял для себя решение по деталям реализации осваиваемого мной ныне MVVM в разрабатываемом приложении.

Задача :
Нужно носимое приложение с минимальным количеством DLL в папке приложения. В этой же папке должен быть каталог с БД приложения. Интерфейс требуется сделать не-примитивным (подробнее - ниже), коим почти все обучающие примеры MVVM обладают. Данных будет не очень много (в пределах 30 МБ текста за год).

Решение :
NET Core 3 приложение на C# с использованием WPF.
БД на этапе разработки - файлы JSON, одна таблица БД - один файл. От SQLite+EF отказался на этом этапе как раз из-за того, что они тянут в папку приложения кучу библиотек. Подозреваю, это количество можно сильно уменьшить, но пока не знаю как.

Детали :
1. Набор таблиц не на 100% соответствует набору классов бизнес-модели (есть "промежуточные" таблицы для связи многие-ко-многим, а "бизнес-классов" для них, понятно, нет).
Из-за предстоящего возможного перехода на другой (или дополнительный) способ хранения данных хочу отделить бизнес-модель от модели данных. Сейчас есть:

Model\DataContext - бизнес-модель; набор интерфейсов, на которые буду ссылаться во ViewModel.
Например: IBuilding; IRoom; ISubject;

Model\Json - модель данных JSON; набор класов, которые воспроизводят структуру БД и реализуют интерфейсы бизнес-модели. Например:
JsonContext { GetBuildings(), SaveBuildings(), etc }
DbRecord { ID, IsArchive, DateModified };
Building : DbRecord, IBuilding;
Room : DbRecord, IRoom;
Subject : DbRecord, ISubject;

В перспективе вместо или в довесок к Model\Json может появиться Model\Excel, Model\SQLite, Model\Web и т.п. Таким образом, какие-то бизнес-объекты будут получать и сохранять данные не в Json, а в других хранилищах. Будет ли такое, что, например, объекты IBuilding будут загружаться частично из Json и частично из SQLite - не знаю пока. Скорее всего, нет. Т.е. источник данных для одного типа объектов только один.

Оптимально ли так реализовывать модели?

2. Где при такой реализации моделей надо держать экземпляры коллекций записей? К которым (коллекциям) биндятся элементы View.

3. Как корректно реализовать механизмы обработки изменений и сохранения записей, если требуется, чтобы только нажатием кнопки "Сохранить" можно было фиксировать изменения в хранилищах и в других окнах? Насколько я понимаю биндинг, это проблемно, т.к. например:
• Есть ListView с записями. Записи - из DataContext'ной коллекции, которая находится - где? (см. вопрос 2)
• Кликаем по записи дважды
• Открывается окно редактирования записи, DataContext'ом которого (окна) является ссылка на одну из записей коллекции.
• Вносим изменения в TextBox'ы. Учитывая биндинги, эти изменения сразу применяются к DataContext'ной записи, а значит и в общюю коллекцию записей. Т.е. нажатие тут кнопки Отмена, закрывающей окно редактирования, не приводит к игнору/отмене изменений, произошедших в этом окне.

4. Как можно подтягиваемые студией библиотеки зависимостей сложить в подпапку, а не чтобы они рядом с выходным exe лежали? VS Community 2019

Ваяю: MSA 2003, mdb | VB.NET + mdb/SQL Express | 1Сv8, ТК УП | C# + FDB
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40053627
КириллН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И по поводу интерфейса. Вот так (схематично) предполагается его реализация.
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40053640
КириллН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Батюшки, сколько ж опечаток я допустил в первом сообщении... Ууу, позорище!
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40053692
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если есть необходимость сделать при минимуме DLL, то их всех можно просто упаковать внутрь EXE как ресурсы и подгружать по требованию и пользоваться всеми библиотеками нормально
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40053699
КириллН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Roman Mejtes
если есть необходимость сделать при минимуме DLL, то их всех можно просто упаковать внутрь EXE как ресурсы и подгружать по требованию и пользоваться всеми библиотеками нормально


Об этом был как раз один из вопросов. Как это сделать с помощью VS Community 2019? Как гуглить?

EDIT: Видимо, это

Спасибо!

Остальные вопросы всё же актуальны.
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40053700
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
изменения должны храниться во ViewModel и при нажатии на кнопку сохраняться в объекты модели
тут главное не лениться и разделять объекты модели и модели представления в разные типы :)
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40053706
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
гуглить по ключевым словам

ResolveAssembly EmbeddedResource

https://www.codeproject.com/Articles/528178/Load-DLL-From-Embedded-Resource

где то у меня были инструкции по импорту библиотек в компилируемый файл для сценариев msbuild, но мне сейчас лень искать. И это не избавляет от необходимости добавлять обработчик к AddDomain.ResolveAssembly.
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40053717
КириллН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Roman Mejtes
изменения должны храниться во ViewModel и при нажатии на кнопку сохраняться в объекты модели
тут главное не лениться и разделять объекты модели и модели представления в разные типы :)


Как я понял этот ответ: экземлпяр коллекции ObservableCollection<IBuilding> для MainWindow должен лежать в MainWindowViewModel. Так?
Как тогда бороться с автоматическим обновлением записей этой коллекции тогда, когда это обновление не подтверждено пользователем?
Т.е. я открываю BuildingWindow; в его DataContext ссылаюсь на IBuilding в BuildingWindowViewModel и биндю поля формы BuildingWindow на свойства IBuilding - таким образом поля формы сразу же заполняются из записи коллекции. Далее, изменяя текст в полях, я получаю одновременное изменение этой записи в коллекции, что мне НЕ нужно, т.к. в коллекции я хотел бы отражать изменения только при нажатии кнопки ОК в BuildingWindow. Надо, видимо, биндиться на копию записи коллекции? Но тут возникает вопрос про копирование ещё и всех записей IRoom, вложенных в этот IBuilding...

EDIT: Ой, по-моему, я путаю сейчас коллекцию во вью-модели с коллекцией в модели (не в БД, а в памяти)... Если так (путаю), то возникает другой вопрос - про рассинхрон этих двух коллекций. Пользователь внёс изменения в форме редактирования записи - они по биндингам попали в запись коллекции вью-модели. Далее он нажал Отмену - и теперь мы имеем запись в коллекции вью-модели, отличающуюся от записи в коллекции бизнес-модели. Или бизнес-модель не должна иметь свой экземпляр, загруженный одновременно (параллельно) с экземпляром вью-модели?
И как нам в случае отмены изменений в форме редактирования вернуть запись в ObservableCollection в исходное состояние? Только перечитать из БД/JSON, принуждая MainView обновиться?
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40053732
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtes
гуглить по ключевым словам

ResolveAssembly EmbeddedResource

Ради б-га, не надо изобретать велосипед. Fody + Costura.Fody . Всё, что требуется - поставить из нугета 2 пакета, и слегка отредактировать FodyWeavers.xml.

КириллН
Как можно подтягиваемые студией библиотеки зависимостей сложить в подпапку, а не чтобы они рядом с выходным exe лежали?

В конец .csproj руками добавить
Код: xml
1.
2.
3.
4.
5.
6.
<Target Name="AfterBuild">
  <ItemGroup>
    <MoveToLibFolder Include="$(OutputPath)*.dll ; $(OutputPath)*.pdb ; $(OutputPath)*.xml ; Exclude="$(OutputPath)$(TargetName).pdb" />
  </ItemGroup>
  <Move SourceFiles="@(MoveToLibFolder)" DestinationFolder="$(OutputPath)lib" OverwriteReadOnlyFiles="true" />
</Target>


- файлы с масками, перечисленными в тэге MoveToLibFolder, будут после сборки перемещены в папку $(OutputPath)lib. Только при этом надо ещё в конфиге указать probingPath:
Код: xml
1.
2.
3.
4.
5.
<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <probing privatePath="lib"/>
  </assemblyBinding>
</runtime>


- иначе сборки не будут найдены.
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40053735
Eld Hasp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
КириллН , вы не хотите использовать SQLite+EF.
А какая есть альтернатива?
JSON и XML удобны только в случае небольшого количество данных.
У вас ежегодное накопление - 30 Мб.
На мой взгляд, это для XML и JSOM очень много.
Это же последовательные файлы.
И для работы с ними их придётся скачивать целиком в память.
Самый удобный способ работы с ними это сериализация/десериализация.
Но как быстро это будет для файлов размером 30-60-150-300 Мб?

Второй вопрос - это сохранение.
Если изменится хоть один символ XML(JSON) файл надо создавать полностью новый.
Изменить что-то в существующем практически невозможно.
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40053742
КириллН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Eld Hasp
КириллН , вы не хотите использовать SQLite+EF.
А какая есть альтернатива?
JSON и XML удобны только в случае небольшого количество данных.
У вас ежегодное накопление - 30 Мб.
На мой взгляд, это для XML и JSOM очень много.
Это же последовательные файлы.
И для работы с ними их придётся скачивать целиком в память.
Самый удобный способ работы с ними это сериализация/десериализация.
Но как быстро это будет для файлов размером 30-60-150-300 Мб?

Второй вопрос - это сохранение.
Если изменится хоть один символ XML(JSON) файл надо создавать полностью новый.
Изменить что-то в существующем практически невозможно.


Я прекрасно отдаю себе отчёт в этом и согласен с вами. Смысл этого "изврата" (использование JSON как хранилище на этапе разработки и на первых порах эксплуатации) - это как раз заставить себя понять, как пользовать MVVM в условиях разнородных/изменяющихся источников данных.
Мной лично уже выпущено немало приложений на разных языках и разных масштабов: моды, плагины, утилиты, носимые программы, клиент-серверные и веб-решения корпоративного/муниципального/регионального уровня, но я самоучка, пишу код редко и отстаю от мейнстримов.
Мне очень-очень хочется разобраться с этим паттерном, но академически я не умею учиться - только под реальный проект. Благо сейчас появился небольшой реальный проект с несжатыми сроками, в рамках которого я могу сделать правильно, "по науке", освоив популярный паттерн.
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40053842
Eld Hasp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
КириллН , Ok!

MVVM с учётом внешнего хранения данных, дополнится ещё репозиторием.
И по моему опыту общения, начинающим гораздо понятнее и удобнее делать реализацию приложения в таком порядке: Репозиторий, Модель, View, ViewModel.
Каждый из этих слоёв создаётся в отдельном проекте.
Плюс к ним, как минимум, ещё один проект общей библиотеки.

Поэтому советую начать с Репозитория.
А так как у вас возможно изменение хранилища, то лучше сначала задать интерфейс Репозитория и потом уже делать его реализацию.
Интерфейс объявляется в общей библиотеке.
В нём должны быть все необходимые для работы с хранилищем методы.
Методы в параметрах должны получать либо типы значений, либо ссылочные иммутабельные типы.
Очень часто используются иммутабельные DTO.
Все кастомные типы также объявляются в библиотеке.

Сам репозиторий (для XML или JSON) удобнее начинать создавать с образцового файла данных.
Потом по нему создаются классы для сериализации.

В репозитории методы сохранения/загрузки сериализует/десериализует этот файл.


Модель получает в конструкторе Репозиторий и реализует всю Бизнес Логику (кроме работы с хранилищем).
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40054502
КириллН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Eld Hasp, спасибо огромное за развёрнутый ответ!

Правильно ли я понял архитектуру решения (см.картинку)?
И мне не вполне понятно про "общую библиотеку".
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40054508
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ViewModel не должна содержать импорт типов из View, за редким исключением
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40054532
КириллН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Roman Mejtes
ViewModel не должна содержать импорт типов из View, за редким исключением

Роман, как тогда правильно открывать новые окна и передавать в них объекты в качестве DataContext, а также получать обратно результат работы (Ок, Отмена, выбранный элемент списка...)? В CodeBehind окон View?
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40054640
КириллН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хм... В Repo ещё должен быть "using Model", иначе Repo не будет знать о бизнес-интерфейсах из Model, которые должны быть реализованы в Data-классах Repo.
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40054641
Eld Hasp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
КириллН , несколько ссылок.
Может пригодятся.
Структура WPF решения
Структура WPF+БД решения
Потоки в асинхронном MVVM
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40054645
Eld Hasp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
КириллН , в Модели не должно быть ссылки на Репозиторий.
Вы же предполагаете возможную замену Репозитория, поэтому Модель "знает" о Репозитории только его интерфейс.
Интерфейс содержится в отдельной общей библиотеке.

При запуске приложения конкретный репозиторий создаст App и передаст в конструктор Модели по интерфейсу.
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40054661
КириллН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Eld Hasp, снова благодарю за полезные ссылки.

Eld HaspКириллН, в Модели не должно быть ссылки на Репозиторий.
Вы же предполагаете возможную замену Репозитория, поэтому Модель "знает" о Репозитории только его интерфейс.

Эти мои выводы сделаны на основании рассуждения - см. картинку. В нём что-то не так?
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40054672
КириллН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...таким образом, при смене слоя Json на слой SQLite надо будет только изменить в Model\DataContext слово Json на слово SQLite, чтобы вместо Json\JsonContext получилось SQLite\SQLiteContext. А если записывать в виде Json\Context то только namespace поменять. А вы предлагаете вариант, при котором не надо вообще ничего в Model менять? Тогда я недопонял, как это сделать. Пошёл по предоставленным ссылкам...
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40054757
Eld Hasp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
КириллН
...таким образом, при смене слоя Json на слой SQLite надо будет только изменить в Model\DataContext слово Json на слово SQLite...

Не должно такого быть.
Изменение репозитория не должны ни на йоту влиять на Модель.
Даже просто вставка незначащего пробела в код - это создание новой сборки.
Чтобы потом VM увидела эту новую сборку придётся её тоже пересобирать.
А потом и View.

Вот и получается, что любое незначительное изменение в репозитории приведёт к пересборке всех связанных сборок, хотя там не было никаких изменений.

Если же сборки связанны между собой через интерфейсы лежащие в отдельной общей библиотеке, то такого происходить не будет.
Внедрением зависимостей должен заниматься App - это самый верхний слой приложения, который лежит надо всеми и о всех всё знает.
Он по сути не входит в MVVM и должен быть в отдельном проекте.
Но для проектов "средней руки" так делать неудобно, поэтому такое решение используется редко.
Но оно более верное с точки зрения архитектуры приложения.
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40054758
Eld Hasp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
КириллН

Эти мои выводы сделаны на основании рассуждения - см. картинку. В нём что-то не так?


К своему рисунку нарисуйте слева на всю высоту сборку общей библиотеки.
Все слои ссылаются не на нижележащие на эту общую библиотеку.

А на всеми нарисуйте на всю ширину ещё слой App.
Он будет ссылать на все слои и на общую библиотеку.
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40054854
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КириллН,
сорри за оффтоп, но в чем вы рисуете такие классные диаграммы?
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40055304
КириллН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vb_sub
КириллН,
сорри за оффтоп, но в чем вы рисуете такие классные диаграммы?


https://miro.com/
Сам только недавно (на онлайн-собеседовании) про него узнал. Оч понравилось. =) Особенно совместная одновременная работа.
...
Рейтинг: 0 / 0
Реализация MVVM с несколькими разными хранилищами данных
    #40055333
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КириллН,

отечественный продукт. в моем городе пилят :)
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Реализация MVVM с несколькими разными хранилищами данных
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали тему (0):
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]