I am doing manual dependency injection right now. This works, but I believe it could be better.
Requirements
No circular dependencies
Allow constructor injection to make unit testing easier
Lazy injection so that I do not need to add dependencies to the graph in a special order.
Singletons
Overrides for integration/UI testing
Works in node and browser so it can be used in node development and Vuejs web dev I do.
Bonus: Less boilerplate. Right now with my manual DI, it takes a lot of boilerplate to add something to the graph.
Bonus: Strict type checking when getting a dependency from the graph. Right now, you have code like this:
let userController: UserController = container.get<Dependency.UserController>()
What if you have a typo in the Dependency.UserController? You get a runtime exception. I would rather do:
let userController = container.userController()
And this returns back UserController. No runtime exceptions.
Ideas
The manual dependency injection I do right now takes care of a lot of the requirements above. However, the type checking on it is a mess. This code speaks for itself:
inject<T>(dependency: Dependency): T {
const overridenValue = this.overrides[dependency] as T
if (overridenValue) {
return overridenValue
}
switch (dependency) {
case Dependency.KeyValueStorage:
return (new RedisKeyValueStorage(this.inject(Dependency.RedisClient)) as unknown) as T
I could simply refactor the existing manual dependency injection code to make it have strict type checking and not be a pain to type.
Using a project like this for inspiration. Using this project does not allow you to use constructor injection but it does do lazy injection as well as includes various ways of doing injection which I could use to give me ideas on how to do this.
Overall, I am happy with what I have now but I still have some pains with (1) maintaining it especially as the code base grows and (2) it's not strictly type checked.
I am doing manual dependency injection right now. This works, but I believe it could be better.
Requirements
What if you have a typo in the
Dependency.UserController
? You get a runtime exception. I would rather do:And this returns back
UserController
. No runtime exceptions.Ideas
The manual dependency injection I do right now takes care of a lot of the requirements above. However, the type checking on it is a mess. This code speaks for itself:
I could simply refactor the existing manual dependency injection code to make it have strict type checking and not be a pain to type.
Using a project like this for inspiration. Using this project does not allow you to use constructor injection but it does do lazy injection as well as includes various ways of doing injection which I could use to give me ideas on how to do this.
Overall, I am happy with what I have now but I still have some pains with (1) maintaining it especially as the code base grows and (2) it's not strictly type checked.