Let's suppose I have this Angular 2 service:
@Injectable()
class Demo {
constructor(private instanceSpecificString: string) {
}
}
Notice that its constructor
accepts an instance-specific string
. What I mean by that is that I want to instantiate this service multiple times and, each time it gets instantiated, I want to pass it a different string
based on the context in which the service is instantiated.
How do I do that?
P.S. string
is used as an example, but the parameter could easily be of type number
, or boolean
or even some kind of configuration object
.
If you want to pass additional parameters to an Angular service, what you are looking for is @Inject decorator. It helps you pass your parameters to the service through Angular's dependency injection mechanism. @Inject() is a manual mechanism for letting Angular know that a parameter must be injected.
Also, DI in our Angular components/services can be implemented using either constructor or injector.
Acquiring a service dynamically through injector in Angular 2(+) is pretty straightforward. All you have to do is inject the Injector itself into the component's constructor instead of the services and then get the service instance by using the injector. get() method.
The value that gets passed to your service will be determined by the injector that's instantiating it. You might be able to do this in one of your component definitions:
@Component({
...
providers: [
provide(string, {useValue: "someSpecificValue"})
]
})
However, this has the problem that you're defining a provider for the string token and that could lead to maintainability issues.
It would probably be a better pattern to define some config model for your service:
class DemoConfig {
instanceSpecificString: string;
}
And then you could create an instance of that to pass to your service.
let config = { instanceSpecificString: "someSpecificValue" }
@Component({
...
providers: [
provide(DemoConfig, {useExisting: config})
]
})
Hope this is helpful. I haven't tried this myself; the services I use in my application are singletons. Here is the reference that I was using:
https://angular.io/docs/ts/latest/api/core/index/provide-function.html
Because the service is declared a injectable (@Injectable()
annotation) it is a singleton. So instead just remove the annotation from the top of your service to remove that restriction.
This is not necessarily best practices but it will work and compile with AOT enabled.
Example:
Change this service:
@Injectable()
export class BaseSocket extends Socket {
protected constructor(
private baseConfig:SocketIoConfig
...
) {
super();
}
}
Into this:
export class BaseSocket extends Socket {
protected constructor(
private baseConfig:SocketIoConfig
...
) {
super();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With