TypeScript InversifyJS:接口多种实现的复杂绑定

问题描述 投票:0回答:1

抱歉,如果标题含糊不清..

我有以下接口实现

ILogProvider
MultiLogProvider
LogInjector
AppInsightsLogger
ConsoleLogger

我也有课

DeviceInfoManager
..

预期的行为是:

  1. MultiLogProvider 接受一组

    ILogProvider
    ,在本例中,
    AppInsightsLogProvider
    ConsoleLogger

  2. MultiLogProvider
    被注入到
    LogInjector
    DeviceInfoManager
    (仅供参考,
    LogInjector
    依赖于
    DeviceInfoManager
    ,因此很复杂)

  3. 任何其他要求

    ILogProvider
    的事情都应该得到
    LogInjector

我尝试了

.when
.whenNoAncestorMatches
和其他几个
.when*
函数的几种不同变体,但我要么最终得到循环依赖,要么由于一些看似不确定的解析循环而导致请求永远不会解析。

我相当确定这两行是正确的:

this.container.bind<ILogProvider>(TYPES.ILogProvider).to(ConsoleLogger).inSingletonScope().whenInjectedInto('MultiLogProvider');

this.container.bind<ILogProvider>(TYPES.ILogProvider).to(AppInsightsLoggingProvider).inSingletonScope().whenInjectedInto('MultiLogProvider');

我不知道以下 2 使用什么

.when
函数:

this.container.bind<ILogProvider>(TYPES.ILogProvider).to(MultiLogProvider).inSingletonScope().when*????

this.container.bind<ILogProvider>(TYPES.ILogProvider).to(LogInjector).inSingletonScope().when*????

感谢任何帮助。

typescript dependency-injection inversion-of-control inversifyjs
1个回答
0
投票

让我们分解每个要求:

A)

MultiLogProvider
接受一组
ILogProvider
,在本例中为
AppInsightsLogProvider
ConsoleLogger

我假设您正在使用

multiInject

@multiInject(TYPES.ILogProvider) loggers: ILogProvider[]`

您的绑定看起来正确:

this.container.bind<ILogProvider>(TYPES.ILogProvider).to(ConsoleLogger)
    .inSingletonScope()
    .whenInjectedInto('MultiLogProvider');

this.container.bind<ILogProvider>(TYPES.ILogProvider).to(AppInsightsLoggingProvider)
    .inSingletonScope()
    .whenInjectedInto('MultiLogProvider');

B)

MultiLogProvider
被注入到
LogInjector
DeviceInfoManager
(仅供参考,
LogInjector
依赖于
DeviceInfoManager
,因此很复杂)

这意味着我们有这些依赖关系(左边有右边的依赖关系):

  • LogInjector
    -->
    MultiLogProvider
  • DeviceInfoManager
    -->
    MultiLogProvider

您可以使用两种绑定:

this.container.bind<ILogProvider>(TYPES.ILogProvider)
    .to(MultiLogProvider)
    .inSingletonScope()
    .whenInjectedInto('LogInjector');
this.container.bind<ILogProvider>(TYPES.ILogProvider)
    .to(MultiLogProvider)
    .inSingletonScope()
    .whenInjectedInto('DeviceInfoManager');

或者将两者组合成一个自定义绑定:

import { typeConstraint } from "inversify";

this.container.bind<ILogProvider>(TYPES.ILogProvider)
    .to(MultiLogProvider)
    .inSingletonScope()
    .when(request => 
        typeConstraint(LogInjector)(request.parentRequest) ||
        typeConstraint(DeviceInfoManager)(request.parentRequest)
    );
  • LogInjector
    -->
    DeviceInfoManager
this.container.bind<DeviceInfoManager>(TYPES.DeviceInfoManager)
    .to(DeviceInfoManager)
    .inSingletonScope()

C)

任何其他要求

ILogProvider
的事情都应该得到
LogInjector

LogInjector
应该用在任何需要
ILogProvider
的地方,除了需要
MultiLogProvider
的情况(您已在 B 中处理过)。

import { typeConstraint } from "inversify";

this.container.bind<ILogProvider>(TYPES.ILogProvider)
    .to(LogInjector)
    .inSingletonScope()
    .when(request => 
        !typeConstraint(LogInjector)(request.parentRequest) &&
        !typeConstraint(DeviceInfoManager)(request.parentRequest)
    );
© www.soinside.com 2019 - 2024. All rights reserved.