Angular 2 个用于导出依赖项依赖项的多提供程序

Angular 2 multi-provider for exporting depencency's dependencies

我将要使用 multi-provider 将我的依赖项的依赖项与其自身一起导出,以便它们可以立即注入到组件中。

对于组件

import {Component} from 'angular2/core';
import { FOO_PROVIDERS } from './foo';

@Component({
  selector: 'app',
  providers: [FOO_PROVIDERS]
})
export class App {}

following

import {Inject, Injectable, provide} from 'angular2/core';
import {Http, HTTP_PROVIDERS} from 'angular2/http';

export class Foo {
  constructor(@Inject(Http) http) {}
}

export const FOO_PROVIDERS = [
  provide(Foo, { useClass: Foo, multi: true }),
  provide(Foo, { useValue: HTTP_PROVIDERS, multi: true })
];

将导致

No provider for Http! (App -> Foo -> Http)

this

import {Inject, provide} from 'angular2/core';
import {Http, HTTP_PROVIDERS} from 'angular2/http';

class Foo {
  constructor(@Inject(Http) http) {}
}

export const FOO_PROVIDERS = [Foo, HTTP_PROVIDERS];

会很好地工作,而我希望他们能做类似的工作。

在这种情况下是否正确使用多供应商?

当你注册时 provide(Foo, ...), 你可以

constructor(foo:Foo)

通过 multi: true 您将通过所有注册为 Foo

的提供商
constructor(foo:any)

export const FOO_PROVIDERS = [
  provide(Foo, { useClass: Foo, multi: true }),
  provide(Foo, { useValue: HTTP_PROVIDERS, multi: true })
];

constructor(@Inject(Foo) foo:Foo[])

您将被传递给 foo 一个包含 Foo 实例的数组和作为第二项的提供者列表(这些包含在 HTTP_PROVIDERS 中)

更新

也许您对应该发生的事情有不同的期望。我看不出 @Inject(Http) http 在这里有什么关系。 HTTP_PROVIDERS 仅注册为 Foo 的值。当提供商被解析时,你传递给 useValue 的值是无关紧要的。 DI 查找 Foo 的提供程序并传递分配的值,根本不关心该值是什么。在您的示例中没有 Http 的提供程序,因此 Foo 本身无法注入 Http。您需要注册 Http,这是在您将 HTTP_PROVIDERS 直接添加到提供程序(而不是 useValue 中)时完成的,因为 HTTP_PROVIDERS 包含 Http(等效至 provide(Http, {useClass: Http})

update2

// An injected service that itself needs to get passed in a dependency
@Injectable()
class Foo {
  constructor(private http:Http);
}

// container for a bunch of dependencies    
@Injectable()
class MyProviders {
  // add everything you want to make available in your components
  constructor(public foo:Foo, public bar:Bar, ...);
}

class MyComponent {
  // inject just MyProviders and use the dependencies it provides
  constructor(private providers: MyProviders) {
    // access provided values
    providers.foo.doSomething();
    providers.bar.doSomethingElse();
  }
}

// Add all providers to allow DI to resolve all above dependencies
bootstrap(AppComponent, [HTTP_PROVIDERS, Foo, Bar]);

}