Ngrx Store 作为提供者中的依赖关系导致循环依赖
Posted
技术标签:
【中文标题】Ngrx Store 作为提供者中的依赖关系导致循环依赖【英文标题】:Ngrx Store as dependency in providers causes cyclic dependency 【发布时间】:2022-01-09 08:41:36 【问题描述】:我试图通过提供应该注入ngrx存储的工厂函数来覆盖默认角度ErrorHandler
:
import ErrorHandler from "@angular/core";
[...]
provide: ErrorHandler,
useFactory: (store: Store<AppState>) =>
return Sentry.createErrorHandler(
showDialog: true,
dialogOptions: ,
);
,
deps: [Store],
,
但我得到循环依赖错误:
main.ts:42 Error: NG0200: Circular dependency in DI detected for Store. Find more at https://angular.io/errors/NG0200
at throwCyclicDependencyError (core.js:216)
at R3Injector.hydrate (core.js:11434)
at R3Injector.get (core.js:11257)
at injectInjectorOnly (core.js:4751)
at ɵɵinject (core.js:4755)
at injectArgs (core.js:4832)
at Object.factory (core.js:11522)
at R3Injector.hydrate (core.js:11438)
at R3Injector.get (core.js:11257)
at injectInjectorOnly (core.js:4751)
如何省略这个问题?我需要提供从商店到创建错误处理程序的工厂函数 (Sentry.createErrorHandler
)。
【问题讨论】:
您是否尝试过注入Injector
而不是Store
?然后,如果我没记错的话,你可以使用injector.get(Store)
获取商店。
【参考方案1】:
我发现的最简单方法是实现自定义错误处理程序,因为 ngrx-store
使用 Angulars EventHandler
例如
SentryErrorHandler
import ErrorHandler, Injectable from "@angular/core";
import * as Sentry from "@sentry/angular";
import Integrations from "@sentry/tracing";
@Injectable()
export class SentryErrorHandler implements ErrorHandler
constructor()
Sentry.init(
dsn: "https://[your-sentry-dsn-here]",
integrations: [
new Integrations.BrowserTracing(
tracingOrigins: ["localhost", "other-test-urls"],
routingInstrumentation: Sentry.routingInstrumentation
)
]
);
handleError(error: Error)
Sentry.captureException(error);
然后在你的app.module
providers: [
provide: ErrorHandler,
useClass: SentryErrorHandler
]
要测试一个示例,可以在调用服务的 Effect
中创建一个不正确的 url,而不是 catchError
,以查看它是否在 Sentry 中弹出,例如
@Injectable()
export class SettingsEffects
constructor(private actions$: Actions,
private settingsService: settingsService)
loadSettings$ = createEffect(() => this.actions$
.pipe(
ofType(settingsActions.loadSettings),
mergeMap(() => this.settingsService.get()
.pipe(
map((response) => settingsActions.loadSettingsSuccess( payload: response)),
//catchError((error) => of(settingsActions.loadSettingsFailed( payload: error))) //commented out should go to Sentry instead
))
));
更新
似乎ErrorHandler
是在提供者之前的生命周期的早期创建的,因此通过添加Injector
作为构造函数参数来尝试
@Injectable()
export class SentryErrorHandler implements ErrorHandler
//store property to use in handleError
private get _store()
return this.injector.get(Store);
constructor(private injector: Injector)
.......
看到这个答案Injecting services in custom ErrorHandler causes "Cannot instantiate cyclic dependency!" error, how can I fix this?
【讨论】:
是的,但我想做的是提供 Store 以检索一些用户数据并用它预填充哨兵对话框。 @Memke 更新了我的答案以上是关于Ngrx Store 作为提供者中的依赖关系导致循环依赖的主要内容,如果未能解决你的问题,请参考以下文章
发生未处理的异常:不支持:关键字“id”,使用“$id”作为模式 ID - Angular 13 中的“ng add @ngrx/store”
如何在 @ngrx/store 的 createAction 中使用数组作为参数