I'm trying to resolve a dependency from a service class, the problem surge because a class has an "Http" constructor parameter (it uses this parameter for WebAPI requests.)
Resolve correctly the dependency and to use the represented object methods
I have a console error that says :
Error: No matching bindings found for serviceIdentifier: Http
Please see my Gist :)
https://gist.github.com/agomezgu/28f6de25624f035557bbee460c60003e
I can't resolve any dependency from a concrete object that recibe a Http injectable parameter constructor. (Please see my Gist)
Error: Uncaught (in promise): Error: No matching bindings found for serviceIdentifier: Http↵Error: No matching bindings found for serviceIdentifier: Http↵ at _createSubRequests (http://localhost:4200/vendor.bundle.js:150398:19) [angular]↵ at Object.plan (http://localhost:4200/vendor.bundle.js:150417:5) [angular]↵ at http://localhost:4200/vendor.bundle.js:150113:37 [angular]↵ at Container._get (http://localhost:4200/vendor.bundle.js:150106:44) [angular]↵ at Container.get (http://localhost:4200/vendor.bundle.js:150065:21) [angular]↵ at new ReportComponent (http://localhost:4200/main.bundle.js:7735:95) [angular]↵ at createClass (http://localhost:4200/vendor.bundle.js:10996:26) [angular]↵ at createDirectiveInstance (http://localhost:4200/vendor.bundle.js:10832:37) [angular]↵ at createViewNodes (http://localhost:4200/vendor.bundle.js:12182:49) [angular]↵ at createRootView (http://localhost:4200/vendor.bundle.js:12087:5) [angular]↵ at Object.createProdRootView [as createRootView] (http://localhost:4200/vendor.bundle.js:12665:12) [angular]↵ at ComponentFactory_.create (http://localhost:4200/vendor.bundle.js:10023:46) [angular]↵ at ComponentFactoryBoundToModule.create (http://localhost:4200/vendor.bundle.js:3638:29) [angular]↵ at ComponentFactoryBoundToModule.create (http://localhost:4200/vendor.bundle.js:3638:29) [angular]↵ at resolvePromise (http://localhost:4200/polyfills.bundle.js:903:31) [angular]↵ at resolvePromise (http://localhost:4200/polyfills.bundle.js:874:17) [angular]↵ at http://localhost:4200/polyfills.bundle.js:951:17 [angular]↵ at Object.onInvokeTask (http://localhost:4200/vendor.bundle.js:4327:37) [angular]↵ at ZoneDelegate.webpackJsonp.1486.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.bundle.js:604:36) [angular]↵ at Zone.webpackJsonp.1486.Zone.runTask (http://localhost:4200/polyfills.bundle.js:404:47) [
+1
+1
i have same problem.
What imports has 3. CONCRET OBJECT?
My first guess is that because of @injectable() inversify tries to inject Http into the constructor. But that is not added to myContainer.
An example project containing only the important code could be helpful :)
Sidenote:
Please don´t add +1 or I have the same problem. If you are interested in the topic click Subscribe. Then you get notifications. Thanks :)
Hi Lholznagel ,
Off course you are right ... i need inject the Http class , but i don't know what is the correct way to inject it , because this library is part of "@angular" Core.
Can you give me some advice?
Thank for all.
Hm without testing it I would say something like:
myContainer.bind<Http>(TYPES.Http).to(Http)
I always used the angular dependency injection so, I don´t know how to handle this the best way, sorry.
Would this work?
@agomezgu sorry for the bad news but Angular has been designed to work with its own IoC containers and it is quite difficult to replace it by other IoC containers like InversifyJS.
The Http source code can be found here. As we can see the constructor looks as follows:
@Injectable()
export class Http {
constructor(protected _backend: ConnectionBackend, protected _defaultOptions: RequestOptions) {}
// ...
The @injectable() annotation in that source code comes from angular not from inversify. We need to add a second annotation @injectable() from inversify. The problems is that we can't use a decorator because we are not the authors of this class. There is a solution for this problem mentioned by @AltekkeE in the previous comment:
import { decorate, injectable } from "inversify";
import { Http } from "@angular/http";
decorate(injectable(), Http);
Then we can declare a binding:
container.bind<Http>(Http).toSelf();
And finally we can try to resolve:
const http = container.get<Http>(Http);
The problem is that the Http class needs two dependencies: ConnectionBackend and RequestOptions.
You can search for the source code of these two classes two see if they are public or private. If there are private there is nothing we can do (without ugly hacks). If they are public we can annotate them and declare bindings:
import { RequestOptions, ConnectionBackend } from "@angular/htttp";
decorate(injectable(), RequestOptions);
decorate(injectable(), ConnectionBackend);
container.bind<RequestOptions>(ConnectionBackend).toConstantValue(ConnectionBackend);
container.bind<RequestOptions>(RequestOptions).toSelf();
Note that ConnectionBackend uses toConstantValue because it is an abstract class (I know this because saw this in the source code).
Then we would have to repeat the operation for the dependencies of RequestOptions and ConnectionBackend and keep going. The worst part is that it is very likely that at some point you would find something private and you will not be able to continue.
In summary: I'm afraid that if your choice is angular, you will have to stick to the angular IoC container.
I actually asked about this to the Angular team when InversifyJS was in its early days: https://github.com/angular/angular/issues/6885
Hi Guys..
Finally I found a very usefull tool named InjectionToken , you can resolve dependencies using Interfaces, the principal advantage is, using InjectionToken you're using Angular Core and no external Libraries
Most helpful comment
What imports has
3. CONCRET OBJECT?My first guess is that because of
@injectable()inversify tries to injectHttpinto the constructor. But that is not added tomyContainer.An example project containing only the important code could be helpful :)
Sidenote:
Please don´t add
+1orI have the same problem. If you are interested in the topic clickSubscribe. Then you get notifications. Thanks :)