我正在构建一个必须使用provider
配方的模块,因为它需要在运行时之前进行配置。我对模块化代码很感兴趣,所以我想向提供者注入一些服务。我知道将providers
注入其他providers
很简单,但对于我想要实现的内容似乎有些过分,所以我想注入一个factory
。
根据我的理解,在运行时期间使用$injector
使我们可以通过angular instanceCache
方法访问createInternalInjector
,该方法返回已实例化的服务。
在配置阶段使用$injector
时,您可以访问保存未实例化服务的providerCache
。
我觉得这个假设必须是不正确的。在下面的代码中,$injector
正在提供程序中使用,但是通过在应用程序运行阶段调用的函数。我希望能够访问instanceCache
,但我只能通过providerCache
方法访问$injector.get
。
_tudModule.factory('wfTabletUsageDataCache', [
function () {
return {
addToLog: fn () { … }
}
}
])
_tudModule.provider('$tabletUsageData', [
'$injector', function $tabletUsageDataProvider ($injector) {
function getCacheFactory() {
return $injector.get('wfTabletUsageDataCacheProvider').$get();
}
function logInteraction(state, buttonId) {
getCacheFactory().addToLog(); // fn() called
}
]);
$injector
中provider
禁止访问instanceCache
怎么办?即使在config
阶段期间没有运行提供程序中的方法?
另外,我之前没有看到我使用$injector.get('wfTabletUsageDataCacheProvider').$get()
的方法。虽然它有效,但这是一种实现这种功能的坏方法吗?
感谢任何方向。
答案 0 :(得分:2)
在配置阶段,(config()
阻止或提供商)您可以注入提供商和常量,而不是工厂,服务或值。如果提供商对您来说太过分了,您可以使用常量。
这样的事情可以起作用
_tudModule.constant('wfTabletUsageDataCache', {
addToLog: function () { ... }
});
_tudModule.provider('$tabletUsageData', [ 'wfTabletUsageDataCache',
function (wfTabletUsageDataCache) {
wfTabletUsageDataCache.addToLog(...)
}
]);
在配置阶段使用
$injector
时,您可以访问保存未实例化服务的providerCache
。
看来你是对的,但这种用法没有记载,一般不鼓励。 $injector
是一项服务,不应将其注入提供商。
另外,我之前没有看到我使用
$injector.get('...').$get()
的方法。
提供商是定义Angular服务的最低级别方式。可以使用.service()
重写所有.factory()
,.value()
或.provider()
定义。根据定义,当实例化提供程序时,它必须公开一个$get
方法,该方法是可注入的并负责返回服务实例。
这就是你在这里看到的。您正在使用$injector.get(...)
检索(并实例化)提供程序,然后使用$get()
方法创建服务实例。但是,通常会在幕后发生,而$get()
方法并不是手动调用的。
您实际上是在试图破解在运行阶段之前不允许实例化服务的限制。不建议这样做。
答案 1 :(得分:1)
你的假设是正确的。您错过的是服务提供商和服务实例有两种不同的注入器。一旦您将提供者注入器注入provider
,即使在配置阶段之后它也会继续处理提供者。您也可以查看this answer以获得澄清。
使用$injector.get('someProvider').$get()
将返回与instanceCache
无关且不是单身的新服务实例。即
$injector.get('someProvider').$get() !== $injector.get('someProvider').$get();
$get
背后没有魔法,它只是一个构造函数,并且注入器没有办法或理由来跟踪它的调用。
可以安全地使用当前代码factory
代替provider
。如果必须在config
中配置提供程序,则所有与实例相关的代码都应转到$get
(因为factory
只是provider
的单一$get
的糖语法方法)。