Пример по переходу проекта на PRISM:  
![Пример по переходу проекта на PRISM](../Pictures/07_01.%20Пример%20по%20переходу%20проекта%20на%20PRISM.png)  
- Требуется выводить информацию в заголовок
- Наполнение страницы произвольное, однако следует использовать все наработки из WPF MVVM приложения
- Должна быть навигация между различными страницами приложения
  
![Пример по переходу проекта на PRISM](../Pictures/07_02.%20Пример%20по%20переходу%20проекта%20на%20PRISM.png)  
Наполнение страницы произвольное, однако следует использовать данные для отображения и редактирования настроек приложения.
## Этап 1. Создание проектов
![Создание проектов](../Pictures/07_03.%20Создание%20проектов.png)
## Этап 2. Настройка оболочки
Класс `App` наследуется от класса `PrismApplication`.  
Также ниже приведен пример подключения ресурсов из других библиотек:
```xml
<prism:PrismApplication
	xmlns:prism="http://prismlibrary.com/"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
	<Application.Resources>
		<ResourceDictionary>
			<ResourceDictionary.MergedDictionaries>
				<ResourceDictionary Source="pack://application:,,,/SamplePrism2023.Counter;component/Themes/Generic.xaml"/>
			</ResourceDictionary.MergedDictionaries>
		</ResourceDictionary>
	</Application.Resources>
</prism:PrismApplication>
```
Класс `App` настраиваем зависимости и регистрируем модули.  
В общей библиотеке заносим справочник регионов.
```cs
public partial class App
{
	protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
	{
		// Тут регистрируем модули
	}
	
	protected override void RegisterTypes(IContainerRegistry containerRegistry)
	{
		// Тут регистрируем зависимости
	}
	
	protected override Window CreateShell()
		=> Container.Resolve<ВашаОболочка>();
}
```
В оболочке размечаем регионы, используя `ContentControl`-ы.
```xml
<ContentControl prism:RegionManager.RegionName=«Тут нужно указать из общего проекта название региона в виде строки"/>
```
## Этап 3. Настройка модуля
Переносим вторую лабораторную работу в отдельный модуль: проект настраиваемых элементов управления.  
Добавляем класс для регистрации модуля:
```cs
public class YourModule : IModule
{
	public void RegisterTypes(IContainerRegistry containerRegistry)
	{
		// Регистрация зависимостей
		containerRegistry
			.Register<IИнтерфейс, Класс_реализующий_интерфейс>()
			.RegisterSingleton<IИнтерфейс, Класс_реализующий_интерфейс>()
			.Register<Класс>() // не имеет смысла
			.RegisterSingleton<Класс>();
		
		// Для навигации
		containerRegistry
			.RegisterForNavigation<имя_представления>();
	}
	
	public void OnInitialized(IContainerProvider containerProvider)
	{
		//Если надо сразу же привязать представление к региону
		containerProvider.Resolve<IRegionManager>()
			.RegisterViewWithRegion(“Название региона”, “Название представления”);
	}
}
```
## Этап 4. Навигация
Основные классы для навигации.
Внедряем менеджер регионов, используем его для навигации.
```cs
private readonly IRegionManager _regionManager;

private void Navigate()
{
	_regionManager
		.RequestNavigate(“Имя региона”, “Имя представления”);
}
```
## Этап 5. Обмен между модулями
Основные классы для отправки сообщений:
```cs
public class Какое_то_имя : PubSubEvent<Какой_то_тип> {}

IEventAggregator eventAggregator
```
Функцию `WhenPropertyChanged` из библиотеки MVVM:
```cs
Какая_то_модель.WhenPropertyChanged(x => x.Какое_то_свойство, eventAggregator.GetEvent<Какое_то_имя>().Publish);

// Информирование об изменении какого то свойства, используя агрегатор событий и возможности Reactive UI
var someObs = Model.WhenAnyValue(x => x.Какое_то_свойство);   
someObs.Subscribe(eventAggregator.GetEvent<Какое_то_имя>().Publish);
```
Основные классы для приема сообщений:
```cs
public class Какое_то_имя : PubSubEvent<Какой_то_тип> {}

IEventAggregator eventAggregator

 eventAggregator
	.GetEvent<Какое_то_имя>()
	.Subscribe(Какое_то_действие);
```
## Использование Reactive UI + Fody
```cs
// Реактивные модели
internal class Какая_то_Model : ReactiveObject
{
	[Reactive] public int Value { get; set; }
}

// Reactive UI Commands
var counterObs = Model.WhenAnyValue(x => x.Value);
IncrementCommand = ReactiveCommand.CreateFromTask(Increment, counterObs.Select(CanIncrement));
DecrementCommand = ReactiveCommand.Create(Decrement, counterObs.Select(CanDecrement));

// MVVM
DecrementCommand = new RelayCommand(Decrement, CanDecrement);
Model.WhenPropertyChanged(x => x.Value, DecrementCommand.RaiseCanExecuteChanged);
```