Инъекции при наследовании
Есть базовый и потомковые классы. Хочу, чтобы в потомковых юзались некие объекты. Можно инъектировать их через конструкторы потомковых классов. Но ведь можно забыть, что в каждом потомковом должна быть такая инъекция. Тогда переношу ссылку на объект в базовый класс, инъектирую объект через конструктор базового, ну и по цепочке потомковых конструкторов передаю эту инъекцию на уровень базового. Ну а потом в потомках использую эту ссылку на объект из базового класса. Типа такого
class Base
{
public Base(IService service)
}
class Descendant
{
public Descendant(IService service) : base(service)
}
Вопрос - а никак нельзя по-другому обойтись, без портянок передачи инъекции в базовый по всей цепочке потомков, если надо ЗАСТАВИТЬ использовать этот объект в потомках? А то цепочка наследований может быть длинной, и потомков во всём дереве наследования может быть туева куча. И везде, в конструкторах всех потомков, писать base(service) как-то задалбывает. Тем более, что в реальности это выглядит куда длиннее - типа
base(IDatabaseContextService<MyDatabaseContext>)
А, да - у нас не синглетоны, а надо, чтобы в каждом объекте свой экземпляр MyDatabaseContext юзался.
а надо, чтобы в каждом объекте свой экземпляр MyDatabaseContext юзался.
AddTransient
https://www.c-sharpcorner.com/article/understanding-addtra...
без портянок передачи инъекции в базовый по всей цепочке потомков
хотя бы serviceProvider надо передать
var service = (IFooService)serviceProvider.GetService(typeof(IFooService));
можно еще поизвращаться через статический класс, но это новые явные зависимости.
https://code-maze.com/aspnetcore-resolve-instances-with-de...
AddTransient
https://www.c-sharpcorner.com/article/understanding-addtra...
Это всё "области видимости", а передавать-то всё равно придётся.
можно еще поизвращаться через статический класс, но это новые явные зависимости.
Вот по идее статический класс (фабрика там или сам экземпляр сервиса) как раз самое то. Не понимаю, почему статика это зависимость? Зависимость, это когда у вас в клиентском коде объекты конкретных типов создаются, без интерфейсов. Статика применяется по месту и не засоряет всю цепочку конструкторов или методов портянкой передачи зависимости. Статическая фабрика, возвращающая интерфейсные объекты - и от зависимостей от конкретных типов ушли, и мусор в сигнатуре методов и конструкторов не множим.
Ещё бред - в обязон хранить ссылку на переданный объект. Точнее, не само хранение, а та куча кода, которая должна быть написана ради этого. Ради одной ссылки на один сервис я должен добавить как минимум поле (а то и свойство), код передачи параметра, код присвоения параметра полю. Вот нахрена вся эта простыня очевиднейшего кода?
class Base
{
protected IService _service;
public Base(IService service)
{
_service = service;
}
}
Вроде, придумали для удобства такой атрибут и директиву @inject. Но это только для Блейзор. Накидать свойств с такой инъекцией в какой-нибудь обычной модели или вью модели MAUI или WPF я не могу ("solely applied").
а передавать-то всё равно придётся
Так это было ко второму вопросу.
Не понимаю, почему статика это зависимость?
Как и любой синглтон. Объект зависит от его состояния.
Попался одни проект от любителя статических зависимостей. Как то его преобразовать - практически невозможно, все в таком клубке что никак не распутать.
Ещё бред - в обязон хранить ссылку на переданный объект
Есть более лучшее решение?
Кстати, прикольный код подсмотрел в исходниках
if (injectables is null)
{
return static (_, _) => { };
}
Это что за "попа" нарисована? )) Типа лямбда с "пофиг какими параметрами" и пустым телом?
ну так на выходе то это
private static Action<IServiceProvider, IComponent>
https://dotnetpattern.com/csharp-action-delegate - в самом конце пример
Делаете дифолт конструкторы потемкинских классов, которые "чтоб не забыть", приватными, и никто не забудет.
Но тогда я не догоняю, зачем нам тогда нужна иерархия классов вообще, если в базовом мы ничего (кроме названия, возможно) иметь не хотим, все - только в потемкиных? Выкиньте это базовый нафер и пишите себе потемкинцев самостоятельными и свободными.
А знак "_" как раз и говорит, что аргумент в игноре
https://learn.microsoft.com/ru-ru/dotnet/csharp/language-r...
А знак "_" как раз и говорит, что аргумент в игнореhttps://learn.microsoft.com/ru-ru/dotnet/csharp/language-r...
А, понял. В смысле, что по вашей ссылке пример
(_, _) => 0
смысла не имеет, т.к. проще сделать ()=>0. Но относительно того, откуда я привёл первоначальный пример - там да. Т.е. такая лямбда нужна лишь для соблюдения формальности - сигнатуры возврата метода, когда на самом деле ничего возвращать не планируется.
Я же ответил, что для конкретной сигнатуры - конкретная "попа". Чем больше параметров, тем больше полупопий. А "пустая" лямбда - для метода без параметров.
ХЗ, по-моему, проще было бы придумать какой-нибудь оператор типа "вернуть заглушку" для случаев, когда нужно вернуть ничего не значащий объект лишь в качестве филлера, для соответствия сигнатуре. Чтобы этот оператор сам определял, для какого возврата какая заглушка, а программисту нужно было лишь написать имя оператора: типа "return empty".
в какой-нибудь обычной модели
можно, но не нужно
https://stackoverflow.com/questions/38459625/property-inje...
Кстати, прикольный код подсмотрел в исходниках
if (injectables is null){return static (_, _) => { };}
Это что за "попа" нарисована? )) Типа лямбда с "пофиг какими параметрами" и пустым телом?
меня больше интересует, что тут значит слово static…
Хочу, чтобы в потомковых юзались некие объекты. Можно инъектировать их через конструкторы потомковых классов. Но ведь можно забыть, что в каждом потомковом должна быть такая инъекция.
Несколько раз прочитал, но так и не понял, что именно забыть и как это можно забыть? Можешь пояснить свой пример кодом?
если надо ЗАСТАВИТЬ использовать этот объект в потомках?
Заставить использовавать что-либо нельзя Даже если ты через 100 потомков протащишь какую-нибудь инекцию ты никогда не сможешь гарантировать, что все потомки используют именно этот объект. Да даже если там всего 1 потомок, ты тоже не можешь этого гарантировать :)
А то цепочка наследований может быть длинной, и потомков во всём дереве наследования может быть туева куча.
Значит проблемы с архитектурой. Тут либо рефакторить, либо страдать :)
И везде, в конструкторах всех потомков, писать base(service) как-то задалбывает. Тем более, что в реальности это выглядит куда длиннее - типаbase(IDatabaseContextService<MyDatabaseContext>)
Нет, в реальности это выглядит именно "base(service)". При передаче параметров не надо указывать их тип.
меня больше интересует, что тут значит слово static…
Это что-то из последних версий Сишарпа. Понамудрили, блин... Через пару лет откроешь чужой код, написанный по последней моде... и закроешь с матерками. ))
Шарп превращается в ипанатство с кучей нечитаемых последовательностей знаков припенания.
Хочу, чтобы в потомковых юзались некие объекты. Можно инъектировать их через конструкторы потомковых классов. Но ведь можно забыть, что в каждом потомковом должна быть такая инъекция.Несколько раз прочитал, но так и не понял, что именно забыть и как это можно забыть? Можешь пояснить свой пример кодом?
Есть идея, что в каждом потомке надо использовать внешний объект-сервис определённого типа. Новый чел, пришедший делать нового потомка, может об этом не знать и начнёт невдуплять, как сервис инжектировать. Будет в методы его передавать, например. А можно "заставить" его это сделать через обязательный параметр базового конструктора. Тогда ему и в потомковом придётся эту инжекцию провести.
Заставить использовавать что-либо нельзя Даже если ты через 100 потомков протащишь какую-нибудь инекцию ты никогда не сможешь гарантировать, что все потомки используют именно этот объект. Да даже если там всего 1 потомок, ты тоже не можешь этого гарантировать :)
Тогда лучше использовать не "заставить", а "подсказать, как правильно".