0
votes

Dart 2.0.0 Angular 5

I have an application divided into two packages. Let's say that we have package A and package B, that depends on package A. In package A I have a class that uses the service "ServiceA". Now, in package B I have a service called "Service B" that extends "serviceA". I would like to inject "service B" instead of "serviceA" every time that in package A "serviceA" is used. I tried to configure my packageB.AppComponent providers this way:

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

and, in a certain way, it works. The above statements say: use an instance (of ServiceB) when you encounter a ServiceB declaration or use another instance of ServiceB when you have to inject a ServiceA class. But I need something diffrent. Inside classA I have defined serviceA as a provider, because I want that every time that classA is called, a different instance of ServiceA is created (and ServiceB when called from package B). If I use packageA alone, it works fine, when I run packageB and I call classA, I cannot get an instance of ServiceB, but always an instance of serviceA. How can I solve this? Is there something wrong in the way I have understood DI?

Edit 1:

Ted suggestion was not so clear to me, so I did a couple of tests and then I succeeded, but I do not really like the solution I found. First I added this lines In ServiceA class:

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

The idea here is to decouple the function that generates the service (() => ServiceA()) from ServiceAFactory, so that I can inject (manually...) the correct function in package B.

Inside classA I removed the

providers: [
ClassProvider(ServiceA)

and I set the ServiceAProvider

providers: [
 ServiceAProvider

In ServiceB I added the following:

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

Only the first line here is strictly needed, but I added the other just in case tomorrow I could have a package C inheriting from this service.

Last step, in package B, in AppComponent class, I removed the providers I defined:

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

And I changed the constructor injecting the correct function:

 AppComponent() {
    package_a.serviceAFactoryFunction =
       serviceBFactoryFunction;
  }

This way it works, but I do not really like all this extra code to be generated. Any other solution?

1

1 Answers

0
votes

For the case of wanting a different instance of a class I would suggest using factories instead of separate providers. Especially if you want to always have a different instance regardless of where you are in the injection tree. This way you can specify only one provider at the root and still get separate instances no matter where in the tree you are.