替换Guice为Dagger 2时,如何自定义实现MembersInjector<Type>?
解决Dagger 2中无法修改类的自定义注入问题
我完全理解你的困境——在从Guice迁移到Dagger 2时,遇到这种完全无法修改的第三方类,常规的@Inject注解方案根本用不了。你尝试自定义MembersInjector的思路是对的,但Dagger 2对MembersInjector的处理有特定规则,直接用@Provides返回lambda的方式会和它的内部机制冲突,咱们可以用两种方式解决:
方案一:自定义注入器接口(推荐,更清晰)
既然MembersInjector是Dagger专为带@Inject注解的类设计的,咱们没必要硬套它,直接自己定义一个注入器接口,逻辑更清晰也避免冲突:
- 先定义自己的注入器接口:
interface TypeInjector { void inject(Type instance); }
- 在模块里提供这个接口的实现,利用Dagger注入A和B的实例:
@Module class MyModule { @Provides TypeInjector provideTypeInjector(A a, B b) { return instance -> instance.initialize(a, b); } }
- 在组件里暴露这个注入器:
@Component(modules = MyModule.class) interface MyComponent { TypeInjector getTypeInjector(); }
使用的时候就很简单了:
// 拿到组件实例 MyComponent component = DaggerMyComponent.create(); // 获取注入器 TypeInjector injector = component.getTypeInjector(); // 初始化第三方框架创建的Type实例 Type typeInstance = thirdPartyFramework.getTypeInstance(); injector.inject(typeInstance);
方案二:正确绑定自定义MembersInjector(如果一定要用Dagger的接口)
如果你坚持要使用Dagger的MembersInjector,需要让Dagger明确使用你自定义的实现,而不是尝试生成默认的空实现。这里要避免直接用lambda,而是创建一个实现类:
- 实现
MembersInjector<Type>接口:
class CustomTypeMembersInjector implements MembersInjector<Type> { private final A a; private final B b; // 让Dagger注入A和B的依赖 @Inject CustomTypeMembersInjector(A a, B b) { this.a = a; this.b = b; } @Override public void injectMembers(Type instance) { // 调用Type的初始化方法 instance.initialize(a, b); } }
- 在模块里绑定这个实现到
MembersInjector<Type>:
@Module abstract class MyModule { @Binds abstract MembersInjector<Type> bindTypeMembersInjector(CustomTypeMembersInjector injector); }
注意这里要用抽象模块和
@Binds,Dagger会自动处理依赖注入,比@Provides更高效。
- 组件可以选择暴露
MembersInjector,或者直接定义inject方法:
@Component(modules = MyModule.class) interface MyComponent { // 方式一:直接暴露注入器 MembersInjector<Type> getTypeMembersInjector(); // 方式二:直接提供注入方法,Dagger会用你绑定的MembersInjector实现 void inject(Type typeInstance); }
为什么你之前的方案不生效?
你之前用@Provides返回lambda的方式,Dagger可能无法正确识别这个泛型接口的实现类型;而且如果组件里定义了Type inject(Type t);,Dagger会尝试生成默认的注入逻辑,这时候就会和你提供的MembersInjector产生冲突。用上面的两种方式,要么绕过MembersInjector,要么明确绑定自定义实现,就能解决问题。
内容的提问来源于stack exchange,提问作者Steffen
相关产品推荐
相关产品推荐

