gpt4 book ai didi

dagger-2 - 使用 Dagger 注入(inject)具有不同接口(interface)的相同对象

转载 作者:行者123 更新时间:2023-12-04 14:23:28 24 4
gpt4 key购买 nike

假设我有一个由 Dagger 2 创建的单例,它实现了接口(interface) FooBar .代码中有一些地方使用了Foo ,以及其他使用 Bar 的地方,但是无论注入(inject)哪个接口(interface),我都想要相同的单例。这可能吗?

最佳答案

是的,这很容易做到,但也很容易做错。诀窍是您需要小心制作 @Singleton : Foo、Bar 或 FooBarImpl。

在 Dagger 中,任何特定的绑定(bind)都可以标记为 Singleton,这就是 Dagger 干涉说“让我缓存这个实例”的地方。 Foo 和 Bar 等接口(interface)将在 @Binds 上标记或 @Provides方法,而像 FooBarImpl 这样的具体类将在 @Provides 上标记它方法或具有 @Inject 的实际类注解。

理想:标记你的实现@Singleton

@Singleton public class FooBarImpl implements Foo, Bar { /* ... */ }
// in your module:
@Binds Foo bindFoo(FooBarImpl impl);
@Binds Bar bindBar(FooBarImpl impl);

这样,无论消费者请求 Foo、Bar 还是 FooBarImpl,他们总是会转到 Dagger 的内部双重检查锁定缓存实例(“DoubleCheck”)。 Foo和Bar可以标记 @Singleton也一样,但是有点浪费,因为内部的 FooBarImpl 提供者无论如何都会返回相同的实例。无需在 Foo Provider 或 Bar Provider 上保留单独的副本。

如果 FooBarImpl 是外部的或不在您的控制范围内,您可以标记 @Singleton@Provides代替方法。

不太理想:标记一个并将另一个绑定(bind)到它
/* not Singleton */ public class FooBarImpl implements Foo, Bar { /* ... */ }
// in your module:
@Binds @Singleton Foo bindFoo(FooBarImpl impl);
@Binds Bar bindBar(Foo foo);

假设 Foo 扩展 Bar,您可以将 Bar 绑定(bind)到 Foo。在这里,单例实例保存在 Foo 提供程序中,注入(inject) FooBarImpl 将返回新实例,注入(inject) Bar 每次都会咨询 Foo(及其缓存提供程序)。

这听起来更糟,但有一些有效的用例:想象一下,如果 FooBarImpl 是某种 CacheImpl,并且您希望 Foo 和 Bar 返回一个实例,但 @Named("accounts") ListeningCache@Named("accounts") Cache两者都返回相同的不同实例。

不是你想要的:单独的单例绑定(bind)

为了完整性:
/* not Singleton */ public class FooBarImpl implements Foo, Bar { /* ... */ }
// in your module:
@Binds @Singleton Foo bindFoo(FooBarImpl impl);
@Binds @Singleton Bar bindBar(FooBarImpl impl);

在这里,Foo 和 Bar 将各自返回一个单独的 Singleton 实例,而 FooBarImpl 的注入(inject)每次都会返回一个新实例。这对于您需要两个或更多对象的用例非常有用,但当您尝试实现上述“不太理想”的解决方案时,请注意不要意外实现此解决方案。它们看起来非常相似,但行为却截然不同。

关于dagger-2 - 使用 Dagger 注入(inject)具有不同接口(interface)的相同对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46497001/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com