Всем привет!
Есть у меня проект (Test) я создал внутри одного решения еще несколько проектов (TestA, TestB)
TestA, TestB это модули WPF приложения с интерфейсом (UserControl) и viewmodel к ним.
Я хочу в главном приложении Test вызвать VM из модуля TestA и подгрузить usercontrol в Test, но
когда в методе вызова я инициализирую viewmodel из модуля TestA (CurrentVM = new TestAVM())
я получаю ошибку.
TestAVM недоступен из за его уровня защиты.
Если открыть класс TestAVM и добавить модификатор public ошибка пропадает, но тогда внутри модуля начинаются такие проблемы в итоге приходится почти все классы внутри модуля делать public.
Как правильно это реализовать? Я знаю про то что можно использовать prism и тд, но я хочу попробовать разобраться сам.
Структура проекта такая
--Test
----Models
----View
----ViewModels
--TestA
----Models
----View
----ViewModels
--TestB
----Models
----View
----ViewModels
Michael, ну так это не те модули. Это про динамическую загрузку, а не про деланье видимыми на уровне языка internal элементы.
Если вы так уверены, что это именно то что вам нужно в рамках тестов - почему не попробуете?
Если не подойдёт - всегда можно удалить и попробовать другой вариант.
Василий Банников, возможно мы по разному понимаем слово "Модуль". Попробую объяснить что я хотел попробовать.
Суть в том что есть основная программа которая запускает подпрограммы (библиотеки dll), эти подпрограммы или библиотеки самостоятельны, там своя логика, модели, никак не связанные с основной программой. В основной программе есть меню, в этом меню я выбираю нужную мне подпрограмму и она загружается в ContentControl
Michael, видимо да.
Ну в таком случае по идее да - вариант от prisma должен подойти (если конечно у него нет требования к публичности).
Но в той ошибке, которую вы описывали, он не поможет - вы же напрямую пытались обратиться к этому классу.
да об объявлен как internal, но когда я объявляю его как public, эта ошибка появляется внутри модуля на списках List ругается на ModelName, и так на все классы.. я думал может есть какой то другой способ сделать это
эта ошибка появляется внутри модуля на списках List ругается на ModelName, и так на все классы..
Ну да, это проблема из-за несовместимости уровней доступа. Тут либо идти чуть ли не по всему проекту, объявляя всё публичным (мб решарпер умеет это автоматически делать. Не уверен)
Либо использовать InternalsVisibleTo
Больше вариантов в принципе нет. Лично я просто взял как привычку делать всё публичным, если явно не хочется сделать интерналом.
Василий Банников, просто если делать все как public в программе Test я могу использовать любой класс из модуля, что немного, как мне кажется, не правильно. Модуль вроде должен быть самостоятельной единицей, которая основная программа должна просто вызвать, а делаю все public можно наворотить такого, что модуль станет частью основной программы
а делаю все public можно наворотить такого, что модуль станет частью основной программы
Хз что надо сделать, чтобы он стал частью программы.
просто если делать все как public
А делай не всё публичным, а только интерфейс - то, с чем должно должна будет взаимодействовать программа.
То, что используется ТОЛЬКО внутри модуля - пусть остаётся интернал.
Название "Test" немного запутывает, и кажется, что это проект с юнит тестами)
Правда это не особо влияет.
Michael, Все, что используется вне модуля - public, все что внутри - internal. В этом ничего плохого нет. Модуль и так это часть программы, смысл разделения на сборки лишь в удобстве разработки (меньше нагроможденность, каждый разраб со своей сборкой работает и тд.).
Василий Банников, Роман, меня вот что смущает, если я правильно понимаю. Допустим есть программа, назовем ее CoolProga, я добавляю в решение VS библиотеку классов, допустим News, далее в программе CoolPraga в MainWindow.xaml я пишу что то типа
сюда я планирую подгрузить MainNewsControl.xaml после того как пользователь выберет модуль News в меню.
В MainWindowVM основной программы я пишу
CurrentVM = new MainNewsControlVM();
ViewControl = new MainNewsControl { DataContext = CurrentVM };
В MainNewsControlVM есть список
public ObservableCollection<News> News { get; set; }
в таком варианте будет ошибка MainNewsControlVM нужно сделать public.Хорошо я сделал его паблик, теперь ошибка в модели News. Но если я сделаю модель News public, я смогу в основной программе взаимодействовать с этой моделью, чего быть не должно. Я думал может есть какой то вариант не делать эти методы public, возможно какую то прослойку между программой и модулем News. Или я не правильно что то делаю?
Michael, судя по тому что, News это ObservableCollection, значит оно будет привязываться.
Если не хочешь чтобы можно было менять коллекцию, есть врапер ReadOnlyObservableCollection https://docs.microsoft.com/en-us/dotnet/api/system...
основная коллекция - с доступом Internal, и вторая ReadOnlyObservableCollection только с геттером.
меняя основную меняется и сразу ReadOnlyObservableCollection
я смогу в основной программе взаимодействовать с этой моделью, чего быть не должно
а смысл делать модель, чтобы с ней не взаимодействовать? странно.
Роман, модуль News реализует внутри себя всю логику, вывод списка новостей, чтение конкретной новости и тд..
NewsModule
-Models
-Views
-ViewModels
public ObservableCollection<News> News { get; set; }
работает внутри модуля News, то есть из основной программы я не должен иметь доступ к этой модели, что что я могу сделать из основной программы это вызов модуля. Если же я сделаю public модель News, то в основной программе я могу сделать что то типо
var news = new News();
news.Title = "fdsfs";
и если через какое то время в модуле News изменится модель по какой то причине получится ошибка, так как поля Title может уже не быть.. поэтому я и думаю как ограничить доступ так, чтобы можно было вызвать этот модуль и не давать излишнего доступа к этому модулю.. нашел такую статью пока не знаю подойдет или нет, надо попробовать
News = new ReadOnlyObservableCollection<News>(InternalNews)
Тогда наружу будет торчать коллекция только для чтения, с приватным сеттером, и при этом меняя InternalNews, будет сразу меняться News и от нее будут улетать события об изменении коллекции.