Внедрение зависимостей и / против Global Singleton - PullRequest
0 голосов
/ 05 декабря 2018

Я новичок в модели внедрения зависимостей.Я люблю эту идею, но изо всех сил пытаюсь применить ее в моем случае.У меня есть одноэлементный объект, давайте назовем его X, который мне часто нужен во многих частях моей программы, во многих различных классах, иногда глубоко в стеке вызовов.Обычно я реализую это как глобально доступный синглтон.Как это реализовано в шаблоне DI, в частности, в контейнере .NET Core DI?Я понимаю, что мне нужно зарегистрировать X в контейнере DI как одиночку, но как мне получить к нему доступ?DI будет создавать экземпляры классов с конструкторами, которые будут ссылаться на X, это здорово - но мне нужно X глубоко внутри иерархии вызовов, внутри моих собственных объектов, о которых .NET Core или контейнер DI ничего не знают, в объектах, которые были созданы с использованием новых, а несоздается экземпляром DI-контейнера.

Я предполагаю, что мой вопрос - как глобальный одноэлементный шаблон выравнивается / реализуется / заменяется / избегается с помощью шаблона DI?

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Просто идея, и, может быть, мне нужна ваша мысль:

public static class DependencyResolver
{
    public static Func<IServiceProvider> GetServiceProvider;
}

Тогда при запуске:

public void Configure(IApplicationBuilder app, IServiceProvider serviceProvider)
{
    DependencyResolver.GetServiceProvider = () => { return serviceProvider; };
}

А теперь в любом классе дел:

DependencyResolver.GetServiceProvider().GetService<IService>();
0 голосов
/ 05 декабря 2018

Ну, "new это клей" ( Ссылка ).Это означает, что если у вас есть new 'экземпляр, он приклеен к вашей реализации.Вы не можете легко поменять его на другую реализацию, например, на макет для тестирования.Как склеивать кирпичи Lego.

Если вы хотите использовать правильное внедрение зависимостей (с использованием контейнера / фреймворка или нет), вам нужно структурировать свою программу таким образом, чтобы вы не склеивали свои компоненты вместе, а вместо этого внедряли их.

Тогда каждый класс в основном находится на уровне иерархии 1.Вам нужен экземпляр вашего регистратора?Вы вводите это.Вам нужен экземпляр класса, которому нужен регистратор?Вы вводите это.Вы хотите проверить свой механизм регистрации?Легко, вы просто внедряете что-то, что соответствует вашему интерфейсу регистратора, который входит в список, и в конце теста вы можете проверить свой список и посмотреть, есть ли все необходимые журналы.Это то, что вы можете автоматизировать (в отличие от обычного механизма ведения журналов и проверки файлов журналов вручную).

Это означает, что в итоге у вас нет иерархии, потому что каждый класс, который у вас есть, простополучает их зависимости, и это будет контейнер / инфраструктура или ваш управляющий код, который определяет, что это означает для порядка создания объектов.


Что касается шаблонов проектирования, позвольте мне наблюдать: даже сейчас вам не нужно синглтон.Прямо сейчас в вашей программе это будет работать, если у вас будет простая глобальная переменная.Но я думаю, вы читали, что глобальные переменные "плохие".И шаблоны дизайна "хорошие".А поскольку вам нужна глобальная переменная, а синглтон предоставляет глобальную переменную, зачем использовать «плохую», если вы можете использовать «хорошую», верно?Ну, проблема в том, что даже с одиночным кодом глобальная переменная плохая.Это недостаток паттерна, жаба, которую вы должны проглотить, чтобы синглтонная логика работала.В вашем случае вам не нужна одиночная логика, но вам нравится вкус жаб.Итак, вы создали синглтон.Не делайте этого с шаблонами дизайна.Прочитайте их очень внимательно и убедитесь, что вы используете их по назначению , а не потому, что вам нравятся их побочные эффекты или потому, что вам удобно использовать шаблон проектирования.

...