maia-yt icon indicating copy to clipboard operation
maia-yt copied to clipboard

Replace Inversify with my own DI: ts-di-transformer

Open YePpHa opened this issue 6 years ago • 0 comments

I have two problems with Inversify.

  1. The first and most annoying problem is that decorators have to be added to everything. This makes your code "semi"-dependent on Inversify in the sense that if you want to change dependency system you have to change each and every file that has dependency injection.
  2. Interfaces are a no go. You can't use interfaces for their intended use case. You have to either use abstract classes instead of interfaces, or you have to add a @inject(IDENTIFIER) before your parameter and then in the config you bind everything to that identifier and not the interface. And again this comes back to the first point of decorators.

I've been trying to solve these two issues and had decent success (with help of custom transformers). I've been able to completely eliminate the first issue. All the metadata that Inversify needed are now resolved on compile-time. The second issue with interfaces are almost completely fixed. In TypeScript you can't pass an interface as an argument which makes it a bit annoying. The workaround is that I've created a method called InterfaceSymbol<I>(), This method doesn't actually exists, but is a placeholder for the compiler to read the type I (the interface) and replace the method call with Symbol.for("SHA256"). So when writing the config file the compiled code will look something like this:

const container = new Container();
container.bind(InterfaceSymbol<IBird>(), Crow);
container.bindToConstant(InterfaceSymbol<IOperator>(), new MyBrokenOperator());
container.bindToConstant(InterfaceSymbol<IOperator>(), new MyOperator());
container.bind(Test, MyTest);

container.resolve(App);
var container = new api_1.Container();
container.bind(Symbol.for("IBird#43930b5e457781450ed58ecf67cf87fd55dfb552014d356b65819092e1388cac"), Crow_1.Crow, [[Symbol.for("IOperator#95edec318c008d1b9561dc601f3389626222d4782436d7e85055a33e5f6e63fc")]]);
container.bindToConstant(Symbol.for("IOperator#95edec318c008d1b9561dc601f3389626222d4782436d7e85055a33e5f6e63fc"), new MyBrokenOperator_1.MyBrokenOperator());
container.bindToConstant(Symbol.for("IOperator#95edec318c008d1b9561dc601f3389626222d4782436d7e85055a33e5f6e63fc"), new MyOperator_1.MyOperator());
container.bind(Test_1.Test, MyTest_1.MyTest, []);
container.resolve(App_1.App, [Symbol.for("IBird#43930b5e457781450ed58ecf67cf87fd55dfb552014d356b65819092e1388cac"), Test_1.Test]);

In conclusion I will replace Inversify with my own dependency system: ts-di-transformer. Hopefully all goes well and if I find things that's missing I will just try to implement these features into the DI.

YePpHa avatar Jan 31 '19 22:01 YePpHa