Today I switched a js electron project to typescript, asking myself if there is an equivalence to angular's dependency injection. As Angular Universal seems to be at a very early state and there is no documentation at all in using it with electron instead of express, it seems that inversify could fit my needs. Also because it's more lightweight than angular, as I only need DI.
I ended up in trying to create a decorator that should work similar to NgModule
decorator in Angular.
import { app, Menu, ipcMain, BrowserWindow } from 'electron';
import { Container } from 'inversify';
import { DatabaseService } from 'core/database.service';
function servermodule(data: {providers: Array<any>}) {
// Some code that instantiate the declarations array classes
// Do they have to be returned, if I don't need a reference?
let container = new Container();
return (target: Object) => {
for(const service of data.providers) {
container.bind(service).toSelf();
}
}
}
which cycles through each entry in providers and binds it to inversifys container object. This function I want to use as follows. The usage would then be exactly as in angulars decorator.
@servermodule({
declarations: [
// Some other classes, that maybe can get DatabaseService injected
],
providers: [
DatabaseService
]
})
export class AppModule { ...
The DatabaseService
could for example look like
import { injectable } from 'inversify';
@injectable()
export class DatabaseService { ...
And should be injectable in angular style, e.g. like
import { inject } from 'inversify';
import { DatabaseService } from './database.service';
export class Models {
constructor(@inject(DatabaseService) dbService: DatabaseService) { }
}
I'm not sure about inversify's container. Is its scope only in the decorator function? Would it be better to use it as
container = new Container({ autoBindInjectable: true });
How do I return it properly to the AppModule
? Is my idea to declare the classes in servermodule decorator a good thought?
For now I just get the following error message on tsc and electron execution, but there are no ts linting errors.
App threw an error during load
Error: Cannot find module 'database.service'
Another idea/question is: If I want in addition to declarations and providers an import attribute. Would it then be a good idea to modify the constructor by the decorator and import these classes?
Thanks!
Regarding this question half a year ago, I worked on implementing decorator functions for an hierarchical DI that look similar to the angular ones and bundled them in an npm package fl-node-di. With it you are able to generate modules
FlModule({
imports: [ AnotherModule ] // imports other FlModules
providers: [ MyService ] // adds Injectables() to the modules container
declaration: [] // same as providers but immediatly creates an instance
exports: [] // places the Injectable() in the parents container
})
export class MyModule {}
The other module could look like
FlModule({
declarations: [ MyComponent ]
})
export class AnotherModule {}
And the component could look like
@Component()
export class MyComponent {
constructor (@Inject(MyService) myService: MyService) {}
}
Pay attention to the Service. The service is provided in the parent module, so this is hierarchical.