I would like to have a possibility to declaratively define construction parameters of injected entities.
I would like to be able to constsruct a logger like this:
@inject("Logger") @named("logger context") logger: Logger;
I found two solutions, that are possible with the current (v4.3.0) implentation:
container.bind<Logger>("Logger").toDynamicValue(context => new Logger("logging context 1")).whenTargetNamed("context1");
container.bind<Logger>("Logger").toDynamicValue(context => new Logger("logging context 2")).whenTargetNamed("context2");
LoggerFactory, which forces me to write 'additional' code (compared to the solution below) when using it:private logger: Logger;
constructor(@inject(Factory<Logger>) loggerFactory) {
this.logger = loggerFactory('logging context 1');
}
My preferred solution is to use the value from e.g. the @named-decorator in toDynamicValue to construct the entity. Currently I could not find the value in the provided interfaces.Context-object. So a solution would be to extend this information somehow, so one is able to use it there:
container.bind<Logger>("Logger").toDynamicValue(context => new Logger(context.getNameSomehow()));
With the above 'generic' implementation, one could inject entities like this without additional code:
@inject("Logger") @named("logger context 1") logger: Logger;
@inject("Logger") @named("logger context 2") logger: Logger;
I hope I didn't miss something in the docs (interfaces.Context or other APIs)!
Thanks in advance & Cheers,
Stephan
I just found #576, which may be related to this
Hi @stephandrab
This is now implemented by https://github.com/inversify/InversifyJS/pull/719 and available in [email protected] 馃帀
You can now access the current request via context.currentRequest. The following code snippet is an example:
@injectable()
class Logger {
public named: string;
public constructor(named: string) {
this.named = named;
}
}
const container = new Container();
const TYPE = {
Logger: Symbol.for("Logger")
};
container.bind<Logger>(TYPE.Logger).toDynamicValue((context) => {
const namedMetadata = context.currentRequest.target.getNamedTag();
const named = namedMetadata ? namedMetadata.value : "default";
return new Logger(named);
});
const logger1 = container.getNamed<Logger>(TYPE.Logger, "Name1");
const logger2 = container.getNamed<Logger>(TYPE.Logger, "Name2");
expect(logger1.named).to.eq("Name1");
expect(logger2.named).to.eq("Name2");
Most helpful comment
Hi @stephandrab
This is now implemented by https://github.com/inversify/InversifyJS/pull/719 and available in
[email protected]馃帀You can now access the current request via
context.currentRequest. The following code snippet is an example: