Для простоты - Vm1 и Vm2 и Dto с параметрами для их конструирования - Dto1 и Dto2.
Цель - передать в некий сервис Dto1 и получить Vm1 и Dto2 - Vm2 соответственно.
Есть 3 сервиса - Svc1, Svc2, Svc3.
Vm1 хочет в конструкторе Dto1, Svc1, Svc2, а вот Vm2 хочет Dto2, Svc1, Svc2, Svc3.
Суть идеи - ты регистрируешь Func<Dto1, Vm1> и Func<Dto2,Vm2>.
При регистрации ты передаёшь в неё сам контейнер. В итоге Dto ты передаёшь как параметр, а сервисы подрезолвливаешь ручками из переданного при регистрации контейнера (это минус этого подхода, я о нём уже рассказывал). По сути получаются фабрики.
Какие от этого плюсы?
- Вью модельки ничего не знают о сервисах друг друга. Весь контракт для создания новой вью-модели - это передача Dto в сервис. Т.е. даже резолвинг Func и его вызов скрыт от них.
- При необходимости порефакторить параметры какой-то вью-модельки - ты рефакторишь Dto, и если это требуется - то резолвинг остальных сервисов, которые ей нужны. При этом порядок и количество аргументов для тебя перестают иметь значение, так как все они живут в Dto, который ты можешь вертеть как угодно. Для твоих вью-моделек весь контракт - это засунуть Dto в сервис и забрать новую вью-модель.
- При рефакторинге параметров для конструирования вью-моделек ты имеешь полную статическую типизацию, и если ты напишешь откровенную херню или что-то забудешь изменить - то код просто не соберётся. Этого нельзя достичь с аргументами, которые передаются у тебя как массив object’ов и потом в рантайме приводятся к нужному типу, как это у тебя было реализовано через метод Set.
- Все зависимости вью модельки получают через конструктор, и следовательно - после создания не требуют дополнительных телодвижений по какой-либо инициализации. Т.е. ты не сможешь создать объект с некорректным внутренним состоянием. При использовании подхода с отдельным методом, выполняющим инициализацию - ты можешь сконструировать объект, но забыть его вызвать.
- По причине того что все зависимости прилетают в конструкторе - их нетрудно тестировать.
Все приседания с Func нужны для упрощения контракта, по которому вью-модельки будут общаться между собой)
Ресолвить сервисы ручками — работа, регистрировать Func<> — работа, писать DTO — работа. Мне проще отправлять аргументы фабрике, и если resolvable-вьюмодель захочет их принять, инжектить в неё сервис, который может всё ей отдать. Просто, универсально и работать много не надо. Да, существенный минут — проё###### статическую типизацию и анализ кода на корректность. Но ведь работаем меньше!
Обсуждают сегодня