Inversify dependency injection not injecting dependencies into constructor





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I have followed the guide on npm and github for inversify to configure dependency injection in my Typescript project.



I have a controller, a service and a router. The service is injected into the controller via constructor injection and the controller is pulled from the dependency injection container directly inside the router.



I get an error that 'Cannot read property 'listingService' of undefined'.



It seems the controller is accessed but for some reason when I try to access the service i find it is undefined.



Can anybody please enlighten me as to what the problem is?



The relevant skeleton code necessary to provide my working is as follows:






// ts.config.json
{
"compileOnSave": true,
"compilerOptions": {
"target": "es5",
"lib": ["es6"],
"types": ["reflect-metadata"],
"module": "commonjs",
"moduleResolution": "node",
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
"include": ["typings.d.ts", "server/**/*.ts"],
"exclude": ["node_modules"]
}

// TYPES.ts
const TYPES = {
ListingController: Symbol.for("ListingController"),
ListingService: Symbol.for("ListingService")
};
export { TYPES };



// inversify.config.ts
import "reflect-metadata";
import { Container } from "inversify";
import {TYPES} from "./Types";
import {ListingController} from "./interfaces/ListingController";
import {ListingControllerImpl} from "../controllers/ListingControllerImpl";
import {ListingService} from "./interfaces/ListingService";
import {ListingServiceImpl} from "../services/ListingServiceImpl";

const myContainer = new Container();
myContainer.bind<ListingController>(TYPES.ListingController).to(ListingControllerImpl);
myContainer.bind<ListingService>(TYPES.ListingService).to(ListingServiceImpl);
export { myContainer };



// router.ts
import * as express from 'express';
const app = express();
import {myContainer} from "../d.i./inversify.config";
import {TYPES} from "../d.i./Types";
import {ListingController} from "../d.i./interfaces/ListingController";
const listingController = myContainer.get<ListingController>(TYPES.ListingController);
app.post('/', listingController.create);
export default app;



export interface ListingController {
create(req: Request, res: Response): void;
}



export interface ListingService {
create(body: any, id: string): Promise<any>;
}



@injectable()
export class ListingControllerImpl implements ListingController {
public listingService: ListingService;

constructor()

constructor(@inject(TYPES.ListingService) listingService: ListingService) {
this.listingService = listingService;
}

public create(req: Request, res: Response): void {
this.listingService.create();
}
}



@injectable()
export class ListingServiceImpl implements ListingService {
constructor()

constructor() {

}

public all(uid: string, page: number, size): Promise<any> {
//
}

public byId(id: string, uid: string): Promise<any> {
//
}

public create(body: any, userId: string): Promise<any> {
// do something
}
}












share|improve this question































    0















    I have followed the guide on npm and github for inversify to configure dependency injection in my Typescript project.



    I have a controller, a service and a router. The service is injected into the controller via constructor injection and the controller is pulled from the dependency injection container directly inside the router.



    I get an error that 'Cannot read property 'listingService' of undefined'.



    It seems the controller is accessed but for some reason when I try to access the service i find it is undefined.



    Can anybody please enlighten me as to what the problem is?



    The relevant skeleton code necessary to provide my working is as follows:






    // ts.config.json
    {
    "compileOnSave": true,
    "compilerOptions": {
    "target": "es5",
    "lib": ["es6"],
    "types": ["reflect-metadata"],
    "module": "commonjs",
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
    },
    "include": ["typings.d.ts", "server/**/*.ts"],
    "exclude": ["node_modules"]
    }

    // TYPES.ts
    const TYPES = {
    ListingController: Symbol.for("ListingController"),
    ListingService: Symbol.for("ListingService")
    };
    export { TYPES };



    // inversify.config.ts
    import "reflect-metadata";
    import { Container } from "inversify";
    import {TYPES} from "./Types";
    import {ListingController} from "./interfaces/ListingController";
    import {ListingControllerImpl} from "../controllers/ListingControllerImpl";
    import {ListingService} from "./interfaces/ListingService";
    import {ListingServiceImpl} from "../services/ListingServiceImpl";

    const myContainer = new Container();
    myContainer.bind<ListingController>(TYPES.ListingController).to(ListingControllerImpl);
    myContainer.bind<ListingService>(TYPES.ListingService).to(ListingServiceImpl);
    export { myContainer };



    // router.ts
    import * as express from 'express';
    const app = express();
    import {myContainer} from "../d.i./inversify.config";
    import {TYPES} from "../d.i./Types";
    import {ListingController} from "../d.i./interfaces/ListingController";
    const listingController = myContainer.get<ListingController>(TYPES.ListingController);
    app.post('/', listingController.create);
    export default app;



    export interface ListingController {
    create(req: Request, res: Response): void;
    }



    export interface ListingService {
    create(body: any, id: string): Promise<any>;
    }



    @injectable()
    export class ListingControllerImpl implements ListingController {
    public listingService: ListingService;

    constructor()

    constructor(@inject(TYPES.ListingService) listingService: ListingService) {
    this.listingService = listingService;
    }

    public create(req: Request, res: Response): void {
    this.listingService.create();
    }
    }



    @injectable()
    export class ListingServiceImpl implements ListingService {
    constructor()

    constructor() {

    }

    public all(uid: string, page: number, size): Promise<any> {
    //
    }

    public byId(id: string, uid: string): Promise<any> {
    //
    }

    public create(body: any, userId: string): Promise<any> {
    // do something
    }
    }












    share|improve this question



























      0












      0








      0








      I have followed the guide on npm and github for inversify to configure dependency injection in my Typescript project.



      I have a controller, a service and a router. The service is injected into the controller via constructor injection and the controller is pulled from the dependency injection container directly inside the router.



      I get an error that 'Cannot read property 'listingService' of undefined'.



      It seems the controller is accessed but for some reason when I try to access the service i find it is undefined.



      Can anybody please enlighten me as to what the problem is?



      The relevant skeleton code necessary to provide my working is as follows:






      // ts.config.json
      {
      "compileOnSave": true,
      "compilerOptions": {
      "target": "es5",
      "lib": ["es6"],
      "types": ["reflect-metadata"],
      "module": "commonjs",
      "moduleResolution": "node",
      "experimentalDecorators": true,
      "emitDecoratorMetadata": true
      },
      "include": ["typings.d.ts", "server/**/*.ts"],
      "exclude": ["node_modules"]
      }

      // TYPES.ts
      const TYPES = {
      ListingController: Symbol.for("ListingController"),
      ListingService: Symbol.for("ListingService")
      };
      export { TYPES };



      // inversify.config.ts
      import "reflect-metadata";
      import { Container } from "inversify";
      import {TYPES} from "./Types";
      import {ListingController} from "./interfaces/ListingController";
      import {ListingControllerImpl} from "../controllers/ListingControllerImpl";
      import {ListingService} from "./interfaces/ListingService";
      import {ListingServiceImpl} from "../services/ListingServiceImpl";

      const myContainer = new Container();
      myContainer.bind<ListingController>(TYPES.ListingController).to(ListingControllerImpl);
      myContainer.bind<ListingService>(TYPES.ListingService).to(ListingServiceImpl);
      export { myContainer };



      // router.ts
      import * as express from 'express';
      const app = express();
      import {myContainer} from "../d.i./inversify.config";
      import {TYPES} from "../d.i./Types";
      import {ListingController} from "../d.i./interfaces/ListingController";
      const listingController = myContainer.get<ListingController>(TYPES.ListingController);
      app.post('/', listingController.create);
      export default app;



      export interface ListingController {
      create(req: Request, res: Response): void;
      }



      export interface ListingService {
      create(body: any, id: string): Promise<any>;
      }



      @injectable()
      export class ListingControllerImpl implements ListingController {
      public listingService: ListingService;

      constructor()

      constructor(@inject(TYPES.ListingService) listingService: ListingService) {
      this.listingService = listingService;
      }

      public create(req: Request, res: Response): void {
      this.listingService.create();
      }
      }



      @injectable()
      export class ListingServiceImpl implements ListingService {
      constructor()

      constructor() {

      }

      public all(uid: string, page: number, size): Promise<any> {
      //
      }

      public byId(id: string, uid: string): Promise<any> {
      //
      }

      public create(body: any, userId: string): Promise<any> {
      // do something
      }
      }












      share|improve this question
















      I have followed the guide on npm and github for inversify to configure dependency injection in my Typescript project.



      I have a controller, a service and a router. The service is injected into the controller via constructor injection and the controller is pulled from the dependency injection container directly inside the router.



      I get an error that 'Cannot read property 'listingService' of undefined'.



      It seems the controller is accessed but for some reason when I try to access the service i find it is undefined.



      Can anybody please enlighten me as to what the problem is?



      The relevant skeleton code necessary to provide my working is as follows:






      // ts.config.json
      {
      "compileOnSave": true,
      "compilerOptions": {
      "target": "es5",
      "lib": ["es6"],
      "types": ["reflect-metadata"],
      "module": "commonjs",
      "moduleResolution": "node",
      "experimentalDecorators": true,
      "emitDecoratorMetadata": true
      },
      "include": ["typings.d.ts", "server/**/*.ts"],
      "exclude": ["node_modules"]
      }

      // TYPES.ts
      const TYPES = {
      ListingController: Symbol.for("ListingController"),
      ListingService: Symbol.for("ListingService")
      };
      export { TYPES };



      // inversify.config.ts
      import "reflect-metadata";
      import { Container } from "inversify";
      import {TYPES} from "./Types";
      import {ListingController} from "./interfaces/ListingController";
      import {ListingControllerImpl} from "../controllers/ListingControllerImpl";
      import {ListingService} from "./interfaces/ListingService";
      import {ListingServiceImpl} from "../services/ListingServiceImpl";

      const myContainer = new Container();
      myContainer.bind<ListingController>(TYPES.ListingController).to(ListingControllerImpl);
      myContainer.bind<ListingService>(TYPES.ListingService).to(ListingServiceImpl);
      export { myContainer };



      // router.ts
      import * as express from 'express';
      const app = express();
      import {myContainer} from "../d.i./inversify.config";
      import {TYPES} from "../d.i./Types";
      import {ListingController} from "../d.i./interfaces/ListingController";
      const listingController = myContainer.get<ListingController>(TYPES.ListingController);
      app.post('/', listingController.create);
      export default app;



      export interface ListingController {
      create(req: Request, res: Response): void;
      }



      export interface ListingService {
      create(body: any, id: string): Promise<any>;
      }



      @injectable()
      export class ListingControllerImpl implements ListingController {
      public listingService: ListingService;

      constructor()

      constructor(@inject(TYPES.ListingService) listingService: ListingService) {
      this.listingService = listingService;
      }

      public create(req: Request, res: Response): void {
      this.listingService.create();
      }
      }



      @injectable()
      export class ListingServiceImpl implements ListingService {
      constructor()

      constructor() {

      }

      public all(uid: string, page: number, size): Promise<any> {
      //
      }

      public byId(id: string, uid: string): Promise<any> {
      //
      }

      public create(body: any, userId: string): Promise<any> {
      // do something
      }
      }








      // ts.config.json
      {
      "compileOnSave": true,
      "compilerOptions": {
      "target": "es5",
      "lib": ["es6"],
      "types": ["reflect-metadata"],
      "module": "commonjs",
      "moduleResolution": "node",
      "experimentalDecorators": true,
      "emitDecoratorMetadata": true
      },
      "include": ["typings.d.ts", "server/**/*.ts"],
      "exclude": ["node_modules"]
      }

      // TYPES.ts
      const TYPES = {
      ListingController: Symbol.for("ListingController"),
      ListingService: Symbol.for("ListingService")
      };
      export { TYPES };



      // inversify.config.ts
      import "reflect-metadata";
      import { Container } from "inversify";
      import {TYPES} from "./Types";
      import {ListingController} from "./interfaces/ListingController";
      import {ListingControllerImpl} from "../controllers/ListingControllerImpl";
      import {ListingService} from "./interfaces/ListingService";
      import {ListingServiceImpl} from "../services/ListingServiceImpl";

      const myContainer = new Container();
      myContainer.bind<ListingController>(TYPES.ListingController).to(ListingControllerImpl);
      myContainer.bind<ListingService>(TYPES.ListingService).to(ListingServiceImpl);
      export { myContainer };



      // router.ts
      import * as express from 'express';
      const app = express();
      import {myContainer} from "../d.i./inversify.config";
      import {TYPES} from "../d.i./Types";
      import {ListingController} from "../d.i./interfaces/ListingController";
      const listingController = myContainer.get<ListingController>(TYPES.ListingController);
      app.post('/', listingController.create);
      export default app;



      export interface ListingController {
      create(req: Request, res: Response): void;
      }



      export interface ListingService {
      create(body: any, id: string): Promise<any>;
      }



      @injectable()
      export class ListingControllerImpl implements ListingController {
      public listingService: ListingService;

      constructor()

      constructor(@inject(TYPES.ListingService) listingService: ListingService) {
      this.listingService = listingService;
      }

      public create(req: Request, res: Response): void {
      this.listingService.create();
      }
      }



      @injectable()
      export class ListingServiceImpl implements ListingService {
      constructor()

      constructor() {

      }

      public all(uid: string, page: number, size): Promise<any> {
      //
      }

      public byId(id: string, uid: string): Promise<any> {
      //
      }

      public create(body: any, userId: string): Promise<any> {
      // do something
      }
      }





      // ts.config.json
      {
      "compileOnSave": true,
      "compilerOptions": {
      "target": "es5",
      "lib": ["es6"],
      "types": ["reflect-metadata"],
      "module": "commonjs",
      "moduleResolution": "node",
      "experimentalDecorators": true,
      "emitDecoratorMetadata": true
      },
      "include": ["typings.d.ts", "server/**/*.ts"],
      "exclude": ["node_modules"]
      }

      // TYPES.ts
      const TYPES = {
      ListingController: Symbol.for("ListingController"),
      ListingService: Symbol.for("ListingService")
      };
      export { TYPES };



      // inversify.config.ts
      import "reflect-metadata";
      import { Container } from "inversify";
      import {TYPES} from "./Types";
      import {ListingController} from "./interfaces/ListingController";
      import {ListingControllerImpl} from "../controllers/ListingControllerImpl";
      import {ListingService} from "./interfaces/ListingService";
      import {ListingServiceImpl} from "../services/ListingServiceImpl";

      const myContainer = new Container();
      myContainer.bind<ListingController>(TYPES.ListingController).to(ListingControllerImpl);
      myContainer.bind<ListingService>(TYPES.ListingService).to(ListingServiceImpl);
      export { myContainer };



      // router.ts
      import * as express from 'express';
      const app = express();
      import {myContainer} from "../d.i./inversify.config";
      import {TYPES} from "../d.i./Types";
      import {ListingController} from "../d.i./interfaces/ListingController";
      const listingController = myContainer.get<ListingController>(TYPES.ListingController);
      app.post('/', listingController.create);
      export default app;



      export interface ListingController {
      create(req: Request, res: Response): void;
      }



      export interface ListingService {
      create(body: any, id: string): Promise<any>;
      }



      @injectable()
      export class ListingControllerImpl implements ListingController {
      public listingService: ListingService;

      constructor()

      constructor(@inject(TYPES.ListingService) listingService: ListingService) {
      this.listingService = listingService;
      }

      public create(req: Request, res: Response): void {
      this.listingService.create();
      }
      }



      @injectable()
      export class ListingServiceImpl implements ListingService {
      constructor()

      constructor() {

      }

      public all(uid: string, page: number, size): Promise<any> {
      //
      }

      public byId(id: string, uid: string): Promise<any> {
      //
      }

      public create(body: any, userId: string): Promise<any> {
      // do something
      }
      }






      typescript dependency-injection dependencies inversifyjs






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 16 '18 at 22:21







      gezinspace

















      asked Nov 16 '18 at 22:03









      gezinspacegezinspace

      321619




      321619
























          1 Answer
          1






          active

          oldest

          votes


















          0














          Ok, so I have found the problem.



          The issue was not actually anything to do with the dependency injection choice or implementation, but in fact was a slight misunderstanding I had of the closure property.



          When I attempted to invoke the listingService's create method from the controller using this.listingService.create() 'this' was not pointing at an instantiation of the controller class.



          By using instance function notation I gained access to the scope I was expecting and can now invoke the service method without any problems.






          public create = (req: Request, res: Response, next: NextFunction): void => {
          this.listingService.create();
          });





          I hope this can help somebody.






          share|improve this answer
























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53346037%2finversify-dependency-injection-not-injecting-dependencies-into-constructor%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            Ok, so I have found the problem.



            The issue was not actually anything to do with the dependency injection choice or implementation, but in fact was a slight misunderstanding I had of the closure property.



            When I attempted to invoke the listingService's create method from the controller using this.listingService.create() 'this' was not pointing at an instantiation of the controller class.



            By using instance function notation I gained access to the scope I was expecting and can now invoke the service method without any problems.






            public create = (req: Request, res: Response, next: NextFunction): void => {
            this.listingService.create();
            });





            I hope this can help somebody.






            share|improve this answer




























              0














              Ok, so I have found the problem.



              The issue was not actually anything to do with the dependency injection choice or implementation, but in fact was a slight misunderstanding I had of the closure property.



              When I attempted to invoke the listingService's create method from the controller using this.listingService.create() 'this' was not pointing at an instantiation of the controller class.



              By using instance function notation I gained access to the scope I was expecting and can now invoke the service method without any problems.






              public create = (req: Request, res: Response, next: NextFunction): void => {
              this.listingService.create();
              });





              I hope this can help somebody.






              share|improve this answer


























                0












                0








                0







                Ok, so I have found the problem.



                The issue was not actually anything to do with the dependency injection choice or implementation, but in fact was a slight misunderstanding I had of the closure property.



                When I attempted to invoke the listingService's create method from the controller using this.listingService.create() 'this' was not pointing at an instantiation of the controller class.



                By using instance function notation I gained access to the scope I was expecting and can now invoke the service method without any problems.






                public create = (req: Request, res: Response, next: NextFunction): void => {
                this.listingService.create();
                });





                I hope this can help somebody.






                share|improve this answer













                Ok, so I have found the problem.



                The issue was not actually anything to do with the dependency injection choice or implementation, but in fact was a slight misunderstanding I had of the closure property.



                When I attempted to invoke the listingService's create method from the controller using this.listingService.create() 'this' was not pointing at an instantiation of the controller class.



                By using instance function notation I gained access to the scope I was expecting and can now invoke the service method without any problems.






                public create = (req: Request, res: Response, next: NextFunction): void => {
                this.listingService.create();
                });





                I hope this can help somebody.






                public create = (req: Request, res: Response, next: NextFunction): void => {
                this.listingService.create();
                });





                public create = (req: Request, res: Response, next: NextFunction): void => {
                this.listingService.create();
                });






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 17 '18 at 12:29









                gezinspacegezinspace

                321619




                321619
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53346037%2finversify-dependency-injection-not-injecting-dependencies-into-constructor%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Bressuire

                    Vorschmack

                    Quarantine