Mapper from Container to inversify
Install via NPM:
npm install inversify-mapper
Create the file "inversify.config.json", and do your mapping from controllers, services, adapter, etc. See e.g.
{
"map": {
/* matches all files in the src directory (any level of nesting) that have the .ts or .js extension.*/
"include": [
"controllers/**/*Controller.{ts,js}",
"services/**/*Service.{ts,js}"
],
"exclude": ["**/BaseHttp*"]
}
}
import containerMap from "inversify-mapper";
const container = containerMap.load();
Create the file "inversify.config.json", and do your mapping from controllers, services, adapter, etc. See e.g.
Note that this way you can to name your injectable or controller classes with same names and it will be not conflict or ambiguous in the loadind.
// inversify.config.json
{
"map": {
"contexts": [
{
"name": "Vendor",
/* matches all files in the src directory (any level of nesting) that have the .ts or .js extension.*/
"include": [
"vendor/controllers/**/*Controller.{ts,js}",
"vendor/services/**/*Service.{ts,js}"
],
"exclude": ["**/BaseHttp*"]
},
{
"name": "Customer",
"include": [
"customer/controllers/**/*Controller.{ts,js}",
"customer/services/**/*Service.{ts,js}"
],
"exclude": ["**/BaseHttp*"]
}
]
}
}
// src/customer/services/AddSubscriptionService.ts
import { inject, injectable } from "inversify";
@injectable()
export class AddSubscriptionService {
constructor(
) {}
async handle(data: Subscription): Promise<Subscription> {
...
}
// src/vendor/services/AddSubscriptionService.ts
import { inject, injectable } from "inversify";
@injectable()
export class AddSubscriptionService {
constructor(
) {}
async handle(data: Subscription): Promise<Subscription> {
...
}
Approach without using the injectMapper decorator
// types.ts file
let TYPES = {
AddSubscriptionController: Symbol.for("AddSubscriptionController"),
AddSubscriptionService: Symbol.for("AddSubscriptionService"),
DeleteSubscriptionService: Symbol("DeleteSubscriptionService"),
ListSubscriptionService: Symbol("ListSubscriptionService"),
};
export default TYPES;
// injection
import { inject, injectable } from "inversify";
@injectable()
export class AddSubscriptionController {
constructor(
@inject(TYPES.AddSubscriptionService)
private readonly addSubscription: IAddSubscriptionUseCase
) {}
Approach using the injectMapper decorator
// types.ts file no needed
// injection
import { injectable } from "inversify";
import { injectMapper } from "inversify-mapper";
@injectable()
export class AddSubscriptionController {
constructor(
@injectMapper(AddSubscriptionService)
private readonly addSubscription: IAddSubscriptionUseCase
) {}
context => name of the context in "inversify.config.json" file
@injectMapper(AddSubscriptionService, context)
import { injectable } from "inversify";
import { injectMapper } from "inversify-mapper";
@injectable()
export class AddSubscriptionController {
constructor(
@injectMapper(AddSubscriptionService, "Customer")
private readonly addSubscription: IAddSubscriptionUseCase
) {}
If you want to inject the class using Singleton, this is a very simple approach:
import { injectMapper, injectableSingleton } from "inversify-mapper";
@injectableSingleton()
export class AddSubscriptionService {
constructor(
@injectMapper(AddSubscriptionRepository)
private readonly addSubscription: IAddSubscriptionRepository
) {}
If you use alias path to the directories in your ts-config, it is need to do some addition config. See it below:
tsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@core/*": ["src/core/*"],
"@common/*": ["src/common/*"],
"@infra/*": ["src/infra/*"],
"@application/*": ["src/application/*"],
"@test/*": ["test/*"]
}
}
}
Use the lib "link-module-alias" to make the mapping.
npm i --save-dev link-module-alias
package.json
{
"scripts": {
"postinstall": "link-module-alias"
},
"_moduleAliases": {
"@core": "src/core",
"@common": "src/common",
"@infra": "src/infra",
"@application": "src/application"
}
}
And so just execute once time, or always that you change your mapping
npm run postinstall
⚠️ Set the NODE_ENV=production environment variable. This package reads the 'outDir' property from your tsconfig.json file to get the root directory.
For the package to run correctly in production, assign a value in outDir.
tsconfig.json
{
"compilerOptions": {
"outDir": "dist" /* Redirect output structure to the directory. */
}
}
The default directory for the development environment is 'src'