2

I have tried to add dependency injection in typescript code its working fine .but I need to load express application in dependency injection.

Dependencies.ts

import { injectable } from 'inversify';

@injectable()
export class DependencyA{
    public getName(){
        return "dependencyA"
    }
}

@injectable()
export class DependencyB{
    public getName(){
        return "dependencyB"
    }
}

Service.ts

import {injectable} from 'inversify';
import { DependencyA,DependencyB } from './dependencies';

@injectable()
export class Service{
    dependencya: DependencyA;
    dependencyb: DependencyB;
    constructor(dependencya:DependencyA,dependencyb:DependencyB){
        this.dependencya = dependencya;
        this.dependencyb = dependencyb

    }

    public getAllName(){
        return this.dependencya
    }
}

main.ts

import 'reflect-metadata'
import { Service } from './service';
import {container} from 'tsyringe';

const service = container.resolve(Service)  
console.log(service.getAllName)

how to load the express app in dependency injection and express app pass the parameter in dependency constructor

1
  • Shameless plug, you can try iti library. Might be much simpler that inversify/tsyring reflect metadata Commented Jul 24, 2023 at 9:43

1 Answer 1

1

I would make sure you stick to inversify across your whole app, and use inversify's Container rather than the container from tsyringe.

I would also point you towards this package (https://github.com/inversify/inversify-express-utils) which I'm using successfully in production for a service based express app using DI.

You can create an InversifyExpressServer passing it your inversify container and your custom express app like so

const container = new Container();

container.bind<MyServiceA>(TYPES.MyServiceA).to(MyServiceA)
container.bind<MyServiceB>(TYPES.MyServiceB).to(MyServiceB)

const app = express();

// apply middleware
app.use(middleware)

// any regular functional express routes
app.use('/', controllerFunc)

...etc etc

const server = new InversifyExpressServer(container, null, null, app);

InversifyExpressServer will handle resolving your ioc root for you and registering all your controllers, all you have to do is bind your services to the container. These services will then be available to @inject and use in your controllers (or in other services)

@controller("/names")
export class NamesController extends HttpBaseController {
    @inject(TYPES.MyServiceA) private myServiceA!: MyServiceA

    @httpGet("/")
    private index(): string {
        return this.myServiceA.getAllNames();
    }
}

It integrates well with existing apps. I'm currently migrating an express app with ~100 endpoints from a plain js express app to a ts app using this inversify package. Since you can pass the InversifyExpressServier a custom app, you can keep all your old routes on there fully functional until you refactor them.

Alternatively, if your project is new, I'd recommend checking out Nestjs (https://nestjs.com/). It's a framework built on express with it's own built in dependency inversion inspired by angular.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.