0

I am from c# background. I am new to Angular 6. I learnt that there is lib similar to ninject for DI. Inversify. I tried to use it in an application.

I did configure Bindings and TYPES.

TYPES.ts

const TYPES = {
    IAppService : Symbol.for("IAppService")
};

export {TYPES}

Bindings.ts

import 'reflect-metadata';
import { Container } from "inversify"
import { TYPES } from "./TYPES"
import { IAppService } from "./services/IAppService"
import { AppService } from "./services/AppService"


const inversifyContainer = new Container();
inversifyContainer.bind<IAppService>(TYPES.IAppService).to(AppService).inSingletonScope();

export { inversifyContainer };

And my class which I am injecting APPService

    import { inject } from "inversify";
    import { Component, OnInit } from '@angular/core';
    import { AppModel } from './model/AppModel'
    import { IAppService } from './services/IAppService';
    import { TYPES } from "./TYPES";


    @Component({
        selector: 'summary-app',
        templateUrl: './summary-app.component.html'
    })
    export class SummaryApp implements OnInit {

        private _service: IAppService;

        constructor(
            @inject(TYPES.IAppService) service: IAppService,
        ) {
            this._service = service;
        }
}

Module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppService } from "./services/AppService"
import { SummaryApp } from './summary-app.component';

@NgModule({
  declarations: [
    SummaryApp
  ],
  imports: [
    BrowserModule
  ],
  providers: [
    AppService
  ],
  bootstrap: [SummaryApp]
})
export class AppModule {
}

The compilation is successful. But I get runtime error Can't resolve all parameters for SummaryApp

This means that inversify is not able to resolve the dependency. I see many examples where people have resolved dependency using service locator. But I feel its anti pattern. Where can I have composition root for inversify container?

MARKAND Bhatt
  • 2,428
  • 10
  • 47
  • 80
  • 1
    Looks like `IAppService` is not an "Angular service" (declared using the `@Injectable` decorator)? Any reason for using a custom DI over Angular's build in DI though? – naeramarth7 Oct 09 '18 at 06:32
  • 2
    I think the runtime error comes from angular, not inversify. I would suggest using the normal angular DI as well – SirDieter Oct 09 '18 at 07:04
  • Angular DI doesn't resolve interface with class. So using inversify to resolve IAppService with AppService. Or can Angular DI resolve interface with class? – MARKAND Bhatt Oct 10 '18 at 00:31

2 Answers2

0

Is SummaryApp being instantiated through the conainer? If that's not the case, we are not in the best case scenario. I see two different solutions:

  1. Try to instantiate SummaryApp through the inversify container (I am not an Angular expert so I don't know how to accomplish such a feat)
  2. Use @lazyInject
import getDecorators from "inversify-inject-decorators";

import { container } from 'your-container-module';

const { lazyInject } = getDecorators(container); // Export your inversify container

@Component({
    selector: 'summary-app',
    templateUrl: './summary-app.component.html'
})
export class SummaryApp implements OnInit {

    private _service: IAppService;

    constructor(
        @lazyInject(TYPES.IAppService) service: IAppService,
    ) {
        this._service = service;
    }
}


This decorator uses a proxy to perform a call to the inversify container. This should work unless your bundler redefines the property once inversify has placed the proxy (see this issue for more details)

0

That's not the way to work with Angular, man.

Sorry to be so direct, but I would recommend that you not swim against the current and use the very complete hierarchical system of dependencies included in Angular instead of Inversify.

https://angular.io/guide/dependency-injection