Given a parent class and a child class that are both @injectable() with an @inject() member each...
@injectable()
export abstract class ParentStore {
@inject(TYPES.StoreFactory)
protected readonly storeFactory: StoreFactory;
}
@injectable()
export class ChildStore extends ParentStore {
@inject(TYPES.Logger)
public readonly logger: Logger;
}
...and a class that creates new instances of the ChildStore using an Inversify Container...
export class StoreFactory {
public constructor(private readonly container: Container) { }
public create(): ChildStore {
return this.container.get<() => ChildStore>(TYPES.ChildStore)();
}
}
...and a main that binds ChildStore to a simple factory method...
const container = new Container();
container.bind(TYPES.Logger).to(Logger);
container.bind(TYPES.StoreFactory).toConstantValue(new StoreFactory(container));
container
.bind(TYPES.ChildStore)
.toFactory(
() =>
() => new ChildStore());
const storeFactory = new StoreFactory(container);
const childStore = storeFactory.create();
childStore.logger.log("Why am I undefined?");
...when we create a new ChildStore instance, we expect that the logger should be injected.
It's undefined instead.
git clone https://github.com/JoshuaKGoldberg/inversiwat && cd inversiwat && npm i && tscnode lib/index.jsIn a more complex application, the goal is to allow the factory to create different child stores depending on POJO models passed into the factory (see an earlier inversiwat commit). Stores can then create child stores dynamically using DI based on their models.
4.3.08.0.0This is expected. Inversify will resolve dependencies when objects are instantiated via the container. In this case, the factory method that you are binding here:
container
.bind(TYPES.ChildStore)
.toFactory(
() =>
() => new ChildStore());
is creating a ChildStore via its constructor, instead of through the container. What you want is probably:
// Bind the ChildStore class
container.bind(TYPES.ChildStore).toFactory(ChildStore);
// Bind the factory
container
.bind(TYPES.ChildStoreFactory)
.toFactory(
() =>
() => container.get(TYPES.ChildStore));
Thanks so much @sleepysort!
Most helpful comment
This is expected. Inversify will resolve dependencies when objects are instantiated via the container. In this case, the factory method that you are binding here:
is creating a
ChildStorevia its constructor, instead of through the container. What you want is probably: