I want to resolve dependency with the Initialization parameters which will be the constructor‘s parameters .
resolve dependency with the Initialization parameters which will be constructor‘ parameters
I can't find the solution about how to afferent the initialization parameters after I have look up the documents and issues on this project.
Please provide some more detail. A code sample would really help.
Thanks
@AltekkeE thank you for your reply.
My code sample show as below:
ILogger.ts:
export interface ILogger {
info(obj: any): void;
debug(obj: any): void;
error(obj: any): void;
fatal(obj: any): void;
}
loggerType.ts
const LoggerType = {
Logger: Symbol.for('Logger')
};
export { LoggerType };
log4jImp.ts
import { injectable, inject } from 'inversify';
import 'reflect-metadata';
import * as path from 'path';
import { ILogger } from '../interfaces/ILogger';
import { LoggerType } from '../types/loggerType';
import * as log4js from 'log4js';
@injectable()
class Log4jImp implements ILogger {
private logger: log4js.Logger;
constructor(category: string) {
log4js.configure({
appenders: {
file: {},
dateFile: {},
out: { }
},
categories: {
default: { appenders: ['file', 'dateFile', 'out'], level: 'info' }
}
});
this.logger = log4js.getLogger(category);
}
public debug(obj: any) {
this.logger.debug(obj);
}
public info(obj: any) {
this.logger.info(obj);
}
public error(obj: any) {
this.logger.error(obj);
}
public fatal(obj: any) {
this.logger.fatal(obj);
}
}
export { Log4jImp };
inversify.config.ts
import { Container } from 'inversify';
import { LoggerType } from './types/loggerType';
import { ILogger } from './interfaces/ILogger';
import { Log4jImp } from './implements/log4jImp';
const IocContainer = new Container();
IocContainer.bind<ILogger>(LoggerType.Logger).to(Log4jImp);
export { IocContainer };
I resolve dependency like this:
import { IocContainer } from '../inversify.config';
import { LoggerType } from '../types/loggerType';
import { ILogger } from '../interfaces/ILogger';
const log4jHelper = IocContainer.get<ILogger>(LoggerType.Logger);
log4jHelper.info('garden server has started!');
but I don't know how to pass initialization parameters to constructor(category: string) in log4jImp.ts.
You'd probably want to bind the initialization parameters to a constant or dynamic value and let the container inject them into the constructor for you.
// inversify.config.ts
const container = new Container();
container.bind<ILogger>(LoggerType.Logger).to(Log4jImp);
container.bind('LoggerCategory').to('myCategory');
@injectable()
class Log4jImp implements ILogger {
constructor(@inject('LoggerCategory') category: string) {
// ...
}
}
I'm facing the same issue, and you cannot inject all constructor variables because they will be called in different locations, did anyone figure out a better solution?
@zachrbrown
That's not so nice.
container.bind('LoggerCategory').to('categoryA');
const aLogger = IocContainer.get<ILogger>(LoggerType.Logger);
container.bind('LoggerCategory').to('categoryb');
const BLogger = IocContainer.get<ILogger>(LoggerType.Logger);
Something like this would be better.
const aLogger = IocContainer.get<ILogger>(LoggerType.Logger, 'categoryA');
const BLogger = IocContainer.get<ILogger>(LoggerType.Logger, 'categoryB');
Hello people...Is there any solution for this particular problem ? I'm facing too this issue and I don't know How to use Inversify with class that needs initialization parameters in the constructor, parameters that can be primitive types... Thank you for your help.
This is an issue which also occurs in other IOC libraries. I'm not sure if inversify supports passing parameters to constructors, but there are some patterns around this. You could specify an initialization function, or convert the constructor parameters to properties with getters and
I think having a constructor parameter could be breaking the abstraction here, because now you have to know about the inner workings of the concrete class instead of following the interface's API. There is no guarantee that if you replace the implementation of the interface with a different concrete class that the new implementation will take the same constructor parameters. So I think it's best to avoid them.