【问题标题】:How to override services injected to angular component如何覆盖注入到角度组件的服务
【发布时间】:2019-03-20 16:26:28
【问题描述】:

我们正在使用 Angular 构建一个 cms 驱动的应用程序框架。我们提供多个包,客户可以使用这些包来进一步定制用户界面或逻辑。出于这个原因,组件会将其逻辑委托给服务,以便客户可以提供自定义服务(我们正在避免组件继承)。

组件是动态放置的,并使用唯一的数据集进行初始化,保存 CMS 数据。提供的服务将从组件注入器继承此数据。这很好用,但是,当提供自定义服务时(使用InjectionToken),我们面临两个问题:

  1. 服务不再是非单例的,多个组件实例将提供同一个自定义服务
  2. 服务将不再从组件中继承数据值,因为它被注入到不同的作用域中

还有其他人遇到过类似的架构挑战吗?

【问题讨论】:

  • @Component 装饰器有一个provider 属性:从那里提供服务会在每个新组件实例上创建一个新实例。你试过了吗?
  • 这正是我们正在做的。然而,我们需要能够通过自定义服务覆盖标准服务。这可以通过工厂实现,但是它们提供在不同的喷射器范围内,这导致了我描述的两个问题。
  • 如果服务只需要在相关组件中,你为什么要让它们可注入?只需创建一个类,然后在您的服务中创建一个新实例。这样,您就可以摆脱注入令牌、提供程序、依赖注入以及所有您似乎不需要的 Angular 上下文。
  • 请注意:“有意向的客户可以提供定制服务”。我们在 npmjs 上的库中发布组件,客户需要提供自己的逻辑。

标签: angular angular-components angular-dependency-injection


【解决方案1】:

看起来你想要的不是直接的提供者。似乎您想要的是一个工厂,它将是实际的提供者,然后它将具有一个 create 方法,该方法将为您返回一个不是单例的实际服务的实例。

类似

@Injectable()
export class MyPFactory {
  public create(): MyP {
    return new MyP();
  }
}

通过这种方式,您可以实现可重用的服务,而无需考虑重写并且可能更清洁的单元测试。我不会说这严格来说是一种解决方案,只是我多次使用过的一种方法来解决您的问题。

通过这种方式,MyP 不需要被装饰为 Injectable,因为工厂将通过在将要使用它的组件/指令中调用 create 方法来创建它。

https://en.wikipedia.org/wiki/Factory_method_pattern

【讨论】:

  • 谢谢,我确实已经开始尝试这个了。不喜欢的2个原因: 1. 需要自定义配置,类似于InjectionToken 2. 客户可能会引入自己的依赖,我们在工厂创建服务时需要引入 同意吗?或者你有什么聪明的想法?
  • 不能肯定地说,因为我不熟悉你正在构建的架构是如何工作的,但如果这些依赖项已经在 IoC 容器中,工厂可以将它们作为正常的依赖并为服务提供他需要的东西?而且我知道它需要很多样板,但是如果您认为单元测试,这会让您省去很多麻烦。
  • 如果您的工厂从 IoC 容器中获取服务,并为其提供组件实例特定的数据,那么该服务不能被重用,因为它是所有将被初始化的组件的单例。
  • 我明白了,我认为您需要来自应用程序的单身人士,我不明白来自客户的内容也应该在该组件的范围内,我的错。
猜你喜欢
  • 2023-03-16
  • 1970-01-01
  • 2021-04-18
  • 2018-11-15
  • 1970-01-01
  • 2016-10-15
  • 2018-07-05
  • 2018-11-23
  • 1970-01-01
相关资源
最近更新 更多