Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to Use Inversify? #131

Open
ccravens opened this issue Apr 28, 2020 · 2 comments
Open

How to Use Inversify? #131

ccravens opened this issue Apr 28, 2020 · 2 comments

Comments

@ccravens
Copy link

ccravens commented Apr 28, 2020

I see references to creating our own ServiceFactory for using other IoC containers like Inversify. I've been working with this for several hours now and can not figure out how it is supposed to work with Inversify. I am successfully binding a service with Inversify that I can use outside of a typescript-rest controller, and I've implemented the following custom class:

import {
  ServiceContext,
  ServiceFactory,
} from 'typescript-rest/src/server/model/server-types';

export class InversifyServiceFactory implements ServiceFactory {
  public create(serviceClass: any, context: ServiceContext) {
    console.log('>>> CREATE SERVICE FACTORY >>>');
    return new serviceClass();
    // return Container.get(serviceClass);
  }

  public getTargetClass(serviceClass: () => {}) {
    console.log('>>> CREATE SERVICE FACTORY >>>');
    if (Array.isArray(serviceClass)) {
      return null;
    }
    let typeConstructor: any = serviceClass;
    if (typeConstructor.name && typeConstructor.name !== 'ioc_wrapper') {
      return typeConstructor as FunctionConstructor;
    }
    typeConstructor = typeConstructor.__parent;
    while (typeConstructor) {
      if (typeConstructor.name && typeConstructor.name !== 'ioc_wrapper') {
        console.log('>>> RETURN 2');
        return typeConstructor as FunctionConstructor;
      }
      typeConstructor = typeConstructor.__parent;
    }
    console.log(
      'Can not identify the base Type for requested target: %o',
      serviceClass
    );
    throw new TypeError('Can not identify the base Type for requested target');
  }
}

And I correctly inject it with:

    Server.registerServiceFactory(new InversifyServiceFactory());

I see that the typescript-rest-ioc does the following:

return Container.get(serviceClass);

However, for Inversify, this is what we're provided:

    get<T>(serviceIdentifier: interfaces.ServiceIdentifier<T>): T;
    getTagged<T>(serviceIdentifier: interfaces.ServiceIdentifier<T>, key: string | number | symbol, value: any): T;
    getNamed<T>(serviceIdentifier: interfaces.ServiceIdentifier<T>, named: string | number | symbol): T;
    getAll<T>(serviceIdentifier: interfaces.ServiceIdentifier<T>): T[];
    getAllTagged<T>(serviceIdentifier: interfaces.ServiceIdentifier<T>, key: string | number | symbol, value: any): T[];
    getAllNamed<T>(serviceIdentifier: interfaces.ServiceIdentifier<T>, named: string | number | symbol): T[];

Which takes an interfaces.ServiceIdentifier.

I'm sure I'm missing something simple, but hoping I can get some quick guidance about how to complete my ServiceFactory since I've seen several places claiming that Inversify is usable, but I keep getting undefined when I inject into the controller.

Thanks!

@ccravens
Copy link
Author

Ok I figure I can pass the Inversify container to my custom ServiceFactory. What I've noticed is that for the following handler:

  public create(serviceClass: any, context: ServiceContext) {
    console.log('>>> CREATE SERVICE FACTORY >>>');
    return return this.container.get(serviceClass);
  }

serviceClass is a handle to the Controller class, not to the injected service. For example, if I'm inject a service into MyController called MyService, the create() method is getting MyController. So when I try and use the Inversify container to get the serviceClass, it obviously doesn't know anything about the controller and I'm given this error:

Error: No matching bindings found for serviceIdentifier: MyController

How do I get the handle for the MyService property so I can get the property rather than the controller? I really wish that there was some sort of example in the documentation or test code or something. Thank you!

@patb23
Copy link

patb23 commented Aug 10, 2020

Ok I figure I can pass the Inversify container to my custom ServiceFactory. What I've noticed is that for the following handler:

  public create(serviceClass: any, context: ServiceContext) {
    console.log('>>> CREATE SERVICE FACTORY >>>');
    return return this.container.get(serviceClass);
  }

serviceClass is a handle to the Controller class, not to the injected service. For example, if I'm inject a service into MyController called MyService, the create() method is getting MyController. So when I try and use the Inversify container to get the serviceClass, it obviously doesn't know anything about the controller and I'm given this error:

Error: No matching bindings found for serviceIdentifier: MyController

How do I get the handle for the MyService property so I can get the property rather than the controller? I really wish that there was some sort of example in the documentation or test code or something. Thank you!

Hi - Were you able to get it working?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants