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 {}
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]);
}
我将要使用 multi-provider 将我的依赖项的依赖项与其自身一起导出,以便它们可以立即注入到组件中。
对于组件
import {Component} from 'angular2/core';
import { FOO_PROVIDERS } from './foo';
@Component({
selector: 'app',
providers: [FOO_PROVIDERS]
})
export class App {}
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]);
}