【问题标题】:Is there a way to ignore binding override in Toothpick?有没有办法忽略牙签中的绑定覆盖?
【发布时间】:2018-03-21 17:25:33
【问题描述】:

假设我有范围 S1,其中包含具有绑定的模块:

bind(Repository.class).to(RepositoryImpl.class).singletonInScope()

然后S2 范围以S1 作为父级(S1 -> S2)打开,S2 定义相同的绑定(因为它是独立的,对S1 一无所知):

bind(Repository.class).to(RepositoryImpl.class).singletonInScope()

默认情况下,Toothpick 会覆盖父范围依赖项,因此 S2 将创建一个新的 RepositoryImpl

问题:有没有办法重用在S1 中创建的绑定并忽略S2 绑定?

此要求来自这样一个事实,即有时存在 独立 应用程序组件,它们驻留在不同的范围内并共享 Repository 依赖项。他们彼此一无所知。这些组件也可以按照不同的顺序创建,具体取决于场景和用例。

所以我要强加的唯一规则是:某个组件(确切地不知道是哪一个)创建 Repository,所有这些都是稍后在当前 子范围中创建的 - 重用它.

【问题讨论】:

    标签: java android dependency-injection toothpick-di


    【解决方案1】:

    要在代码中的任何地方尽早打开范围,您只需使用即可

    Scope s1Scope = Toothpick.openScope('s1-scope-name');
    

    如果 S1 是 S2 的父作用域,您可以使用 getParentScope() 方法来做同样的事情

    Scope s1Scope = s2Scope.getParentScope();
    

    然后从 S1 范围加载所需的单例

    Repository s1Repository = s1Scope.getInstance(Repository.class);
    

    如果你想在 S2 模块中做,你可以简单地做

    bind(Repository.class).toProviderInstance(() -> Toothpick.openScope('s1-scope-name').getInstance(Repository.class));
    

    【讨论】:

    • 所以 S2 必须知道 Repository 是在 S1 中创建的。没有这些知识可以做这个技巧吗?假设我有 S35 想要重用 S1 的存储库,我是否必须以某种方式将 S1 的名称传递给 S35?
    • 如果我理解你的意思,你想在 S35 中注入一个在 S1 中可用的实例,所以 S35 应该知道 S1,不是吗?
    • 另外,你为什么要定义这个绑定,没有它你,你能从S1获取repo吗?
    【解决方案2】:

    当您使用 Toothpick 开发由多个独立组件构建的应用程序时,您可能会朝这个方向发展:

    每个独立的组件,都应该有 2 个牙签模块。

    • 一个处理内部依赖的模块(由模块本身提供)
    • 一个处理外部依赖项的模块(在集成级别提供)

    在第二个中,您将定义输入和输出依赖项,它们将连接到其他独立组件,最终构建一个集成的组件系统。

    【讨论】:

      猜你喜欢
      • 2020-07-02
      • 1970-01-01
      • 1970-01-01
      • 2011-09-10
      • 2010-10-21
      • 2015-04-17
      • 1970-01-01
      • 2018-10-05
      • 1970-01-01
      相关资源
      最近更新 更多