
Igor
28.02.2017
17:08:46
Кстати, еще один напряг от ООП - зависимости
Я думаю все прописывают зависимости в конструкторе (через DI), тк неявные зависимости это ужас.
При этом я не могу сказать "мне нужно что-то с сигнатурой: User => List<Messages>"
И вот тут начинается Interface-HELL.
На одном из Xamarin митапов видел код, где к каждому классу Service обязательно создается IService,
в котором тупо перечислены все публичные методы этого класса.
В итоге в вызывающий класс попадет не только ссылка на нужный метод, но еще 100500 для него не нужных.

Roman
28.02.2017
17:09:52
он был давно надо потратить время на поиск. Но он как раз про DI и "сигнатурные" сервисы в C#

Akhmed
28.02.2017
17:14:18
А в чем именно ад с интерфейсами?

Google

Akhmed
28.02.2017
17:14:41
руками их набирать не надо
все делает Resharper
и при этом упрощает тестирование

Roman
28.02.2017
17:15:19

Akhmed
28.02.2017
17:15:34
это правильно

Igor
28.02.2017
17:15:48
А в чем именно ад с интерфейсами?
В итоге в вызывающий класс попадет не только ссылка на нужный метод, но еще 100500 для него не нужных.
Вообще по дяде Бобу нужно "инвертировать зависимости" и "юзать тонкие интерфейсы (хоть из 1 метода (которые факт. являются функцией))",
но так никто не делает ибо будет уж слишком много интерфейсов.

Akhmed
28.02.2017
17:16:57
https://vimeo.com/113588389

Igor
28.02.2017
17:17:44
все делает Resharper
Это как в Java говорить "проперти не нужны, IDEA генерирует get/set методы автоматически".
Но "бойлерплейта" меньше в код это этого не становится.

Roman
28.02.2017
17:17:49
http://bartoszsypytkowski.com/c-a-different-look-at-service-design/ смотри как круто сделано.
нашел!

Akhmed
28.02.2017
17:19:21
я согласен. Не спорю что если довести до абсолюта ООП подход постепенно выраждается в функциональный подход

Google

Roman
28.02.2017
17:20:14

Akhmed
28.02.2017
17:20:38
но тем не менее - в проекте с 2860 файлами cs не кажется адом

Roman
28.02.2017
17:20:50

Igor
28.02.2017
17:21:32

Roman
28.02.2017
17:21:36

Akhmed
28.02.2017
17:22:45
http://i.imgur.com/guFkuoF.png - вот у меня пока не хватает скила переписать этот проект на F# )
командой в 7 человек почти два года писали проект и только сейчас уже более менее закончились новые фичи

Igor
28.02.2017
17:24:15
И как меня убивает вот это https://i.gyazo.com/3c14032703d7c69c1263bf147d5c7066.png

Roman
28.02.2017
17:25:23

Igor
28.02.2017
17:26:05

Akhmed
28.02.2017
17:26:22
сама по себе консутркция убивает. Но в качестве альтернативы мы вообще не вызываем конструктор
и если объект вызывается из 100500 мест то добавление или удаление лишнего аргумента в конструктор никак не влияет на остальной код
все пользователи класса ничего не знают о его конструкторе

Igor
28.02.2017
17:27:05

Akhmed
28.02.2017
17:27:53
но если надо заменить одну компоненту на другую?
но в целом я согласен что функциональных подход проще
просто я не до конца осмыслил какие могут возникнуть проблемы если заюзать это в enterpise

Igor
28.02.2017
17:29:58

Akhmed
28.02.2017
17:30:45
так вот это new (не важно с ним или без) - любое явное создание конструктора это зло
ну т.е. прямое конструирование объекта

Google

Igor
28.02.2017
17:31:34

Roman
28.02.2017
17:31:45

Akhmed
28.02.2017
17:31:58
этим занимается контейнер

Roman
28.02.2017
17:32:08

Akhmed
28.02.2017
17:32:19
мы просто регистрируем в контейнере реализацию на интерфейс и контейнер сам резолвит интерфейс
так например можно одной строчкой кода сделать из объекта тот же синглтон
или синглотон на поток
или новый инстанс на каждый вызов
и т.д. и т.п.

Roman
28.02.2017
17:33:15
но это не совсем не используем конструктор. Я хчоу получить объект X как мне это можно сделать?

Akhmed
28.02.2017
17:34:23
если речь о DTO то для них сделано исключение
и то их не везде можно порождать - только в сервисах

Roman
28.02.2017
17:35:02
ок, а если не DTO?

Akhmed
28.02.2017
17:35:16
все остальное только через абстракцию

Roman
28.02.2017
17:35:35
Вот я хочу получить обект с интерфейсом IX

Akhmed
28.02.2017
17:35:45
просто передаем его в конструктор и все
больше ничего не надо делать
ну кроме как в контейнере зарегать этот интерфейс

Roman
28.02.2017
17:36:05
В конструктор к объекту IXX?

Google

Akhmed
28.02.2017
17:36:30
я немного запутался с вопросом
минутку

Roman
28.02.2017
17:36:31
да и ок, я хочу этот IX параметризировать своим личным IService

Akhmed
28.02.2017
17:36:34
пример приведу

Igor
28.02.2017
17:37:03
В конструктор к объекту IXX?
Кстати (вы наверное в курсе), это так любят в интерпрайзе,
что даже в .NET/JVM зашили паттерн "1 интерфейс - 1 реализация" (называется девертуализация)`.

Roman
28.02.2017
17:37:33

Igor
28.02.2017
17:38:21
зашили? Не понял, ты про конвенцию?
Про то что в runtime если существует только одна реализация интерфейса (для 2 и больше не работает),
то все виртуальне методы JIT заменяет на прямые.
Это есть и в Java и .NET, но для Java это важнее тк там по умолчанию все методы виртуальные.

Akhmed
28.02.2017
17:38:42
вот пример
public DownloadService(IFileManager fileManager,
ILogger logger,
)
{
_logger = logger;
_fileManager = fileManager;
}

Roman
28.02.2017
17:38:45

Akhmed
28.02.2017
17:38:51
теперь
для WPF
cb.RegisterType<FileManagerWpf?).As<IFileManager?).SingleInstance();
кто нить знает как тут код без смайлов вливать? )

Roman
28.02.2017
17:40:06
(<>)
` вот такие

Akhmed
28.02.2017
17:40:51
cb.RegisterType<FileManagerDroid>().As<IFileManager>().SingleInstance();
это для андроида
ну и т.д.

Google

Akhmed
28.02.2017
17:41:14
нигде нет такого вроде new FileManagerDriod() и т.п.

Roman
28.02.2017
17:42:46

Akhmed
28.02.2017
17:42:59
А все
понял вопрос
в умных DI контейнерах это все разруливается
минутку

Roman
28.02.2017
17:44:18
да, Ninject по имени например , stracturemap можно явгно указать что если инжектимся в этот тип, то используй это, если в другой то то.
Но если я пишу плагин, например и у меян нет доступа к настройке вашего DI фреймворка

Akhmed
28.02.2017
17:45:47
на самом деле есть несколько готовых решений
по имени
через декоратор/адаптер
и т.п.
минутку

Roman
28.02.2017
17:46:59
тогда вым надо высатвить api своего DI контейнера, чтоб я мог зарегистрировать свой адаптер например.

Akhmed
28.02.2017
17:47:07
http://docs.autofac.org/en/latest/advanced/keyed-services.html

Roman
28.02.2017
17:47:34

Akhmed
28.02.2017
17:48:22
ну там и другие варианты есть - можно какой нить enum сделать и по нему резолвить если точно известен все возможные варианты

Roman
28.02.2017
17:49:02
т.е. я его должен регистрировать сам.

Akhmed
28.02.2017
17:49:30
в том то весь и замес что я знаю только об обстракции
хорошо написанной компоненте должно быть все равно какая именно реализация у него будет