Angular dart: как внедрить сервис в многоуровневую пакетную среду - PullRequest
0 голосов
/ 01 октября 2018

Дарт 2.0.0 Угловой 5

У меня есть приложение, разделенное на два пакета.Допустим, у нас есть пакет A и пакет B, который зависит от пакета A. В пакете AI есть класс, который использует сервис «ServiceA».Теперь в пакете BI есть сервис под названием «Сервис B», который расширяет «сервис А».Я хотел бы вводить «service B» вместо «serviceA» каждый раз, когда в пакете A используется «serviceA».Я попытался настроить своих поставщиков packageB.AppComponent следующим образом:

ClassProvider (ServiceB), ClassProvider (package_a.ServiceA, useClass: ServiceB)

и, в некотором роде, это работает.Вышеприведенные операторы говорят: используйте экземпляр (ServiceB), когда вы встречаете объявление ServiceB, или используйте другой экземпляр ServiceB, когда вам нужно внедрить класс ServiceA.Но мне нужно что-то другое.Внутри classA я определил serviceA как провайдера, потому что я хочу, чтобы каждый раз, когда вызывался этот classA, создавался другой экземпляр ServiceA (и ServiceB при вызове из пакета B).Если я использую только packageA, он работает нормально, когда я запускаю packageB и вызываю classA, я не могу получить экземпляр ServiceB, но всегда экземпляр serviceA.Как я могу решить это?Что-то не так в том, как я понял DI?

Правка 1:

Предложение Теда было мне не столь очевидно, поэтому я сделал пару тестов, а затем мне это удалось, но яне очень нравится решение, которое я нашел.Сначала я добавил следующие строки в классе ServiceA:

Function serviceAFactoryFunction = () => ServiceA();
ServiceA ServiceAFactory() => serviceAFactoryFunction();
const ServiceAProvider = FactoryProvider(ServiceA, ServiceAFactory);

Идея состоит в том, чтобы отделить функцию, которая генерирует службу (() => ServiceA ()) от ServiceAFactory, чтобы я мог ввести (вручную)...) правильная функция в пакете B.

Внутри класса A я удалил

providers: [
ClassProvider(ServiceA)

и установил ServiceAProvider

providers: [
 ServiceAProvider

В ServiceB я добавил следующее:

Function serviceBFactoryFunction = () => ServiceB();
ServiceB ServiceBFactory() => serviceBFactoryFunction();
const ServiceBProvider = FactoryProvider(ServiceB, ServiceBFactory);

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

Последний шаг в пакетеB, в классе AppComponent я удалил провайдеров, которых я определил:

ClassProvider(ServiceB), ClassProvider(package_a.ServiceA, useClass:
   ServiceB)

И я изменил конструктор, введя правильную функцию:

 AppComponent() {
    package_a.serviceAFactoryFunction =
       serviceBFactoryFunction;
  }

Таким образом, это работает, но я неочень нравится весь этот дополнительный код для генерации.Любое другое решение?

1 Ответ

0 голосов
/ 03 октября 2018

Для случая, когда нужен другой экземпляр класса, я бы предложил использовать фабрики вместо отдельных провайдеров.Особенно, если вы хотите всегда иметь другой экземпляр независимо от того, где вы находитесь в дереве инъекций.Таким образом, вы можете указать только одного поставщика в корне и по-прежнему получать отдельные экземпляры, независимо от того, где вы находитесь в дереве.

...