2016-04-06 120 views
2

我有一个独立的类叫做Poller。我想将共享配置的这个类的实例注入到不同的组件中。例如,如果我尝试以下方法:Angular 2依赖注入单例

export const QuickPollingService = new OpaqueToken('quickPoller'); 
export let quickPollingServiceProvider = provide(QuickPollingService, { 
    useFactory:() => { 
     return new Poller(200); 
    }, 
}); 
export const SlowPollingService = new OpaqueToken('slowPoller'); 
export let slowPollingServiceProvider = provide(SlowPollingService, { 
    useFactory:() => { 
     return new Poller(1000); 
    }, 
}); 

注射象下面这样(用正确的导入路径)给了我一个名称未找到错误:

export class ImageComponent { 
    constructor(
     private element: ElementRef, 
     private poller: QuickPollingService 
    ) {} 
} 

什么是注入一个配置类的正确方法Angular 2中的实例?

回答

1

你需要使用@Inject装饰器在你的情况下注入你的依赖!

export class ImageComponent { 
    constructor(
    private element: ElementRef, 
    @Inject(QuickPollingService) private poller: Poller 
) {} 
} 

你的情况QuickPollingService对应于一个不透明的令牌,而不是要注入的类型(A类)。您想注入一种Poller,该类型是使用注册了不透明令牌QuickPollingService的提供者创建的。

事实上,以下就足够了:

export let quickPollingServiceProvider = provide(Poller, { 
    useFactory:() => { 
    return new Poller(200); 
    } 
}); 

在这种情况下,你可以使用以下命令:

export class ImageComponent { 
    constructor(
    private element: ElementRef, 
    private poller: Poller 
) {} 
} 
+0

谢谢,这解决了这个问题。我已经扩展了问题中的代码示例,以阐明我的目标。 –

2

使用@Inject()OpaqueToken

如果使用

provide(SomeOpaqueToken ... 

,那么你需要像

export class ImageComponent { 
    constructor(
     private element: ElementRef, 
     // v added decorator 
     @Inject(SomeOpaqueToken) private poller: QuickPollingService 
    ) {} 
} 

使用类型,而不是OpaqueToken

注入

否则这样注册

export let quickPollingServiceProvider = provide(Poller, { 
    useFactory:() => { 
     return new Poller(200); 
    }, 
}); 

(不要在这种情况下使用OpaqueToken

而且供应商确保你的地方添加提供商像

bootstrap(AppComponent, [quickPollingServiceProvider]); 

典型使用案例OpaqueToken

当你不能或不想使用特定类型来注册和请求依赖时,可以使用。

而不是OpaqueToken你也可以使用一个字符串。

如果你想注入一个原始值,如果类型不够独特,你必须使用OpaqueToken或者一个字符串。例如,当你想注入一些配置值。

@Injectable() 
class Poller { 
    constructor(@Inject('pollingInterval' private interval:number) {} 
} 

bootstrap(AppComponent, [ 
    provide('pollingInterval': {useValue: 200}), 
    Poller]); 

这样,你的供应商将被简化,你并不需要使用一个工厂,因为Pollerinterval依赖由Angulars DI提供。

+0

感谢您详细的解答。我已经扩展了问题中的代码示例,以阐明我的目标。似乎有多种方式来实现这一点。 –

+1

在你的例子中(更新的代码)使用'OpaqueToken'非常合适。无法按类型区分慢速和快速实例。另一种方法是创建不同的类,如'类PollerBase','类SlowPoller extends PollerBase'和'类QuickPoller extends PollerBase',然后你可以按类型提供它们,但是如果你这样做,我不会考虑改进你当前的代码这仅适用于DI。 –