如何在Dagger2环境下向Type Converter注入Context实例?
解决Dagger2注入Context到Room TypeConverter的问题
我之前也碰到过一模一样的情况——Room默认会自己实例化TypeConverter,直接用@Inject的话Dagger根本没法接管这个实例的创建。不过咱们可以通过让Dagger提前创建好Converter实例,再手动传递给Room的方式解决,完全不用依赖静态Context。
下面是具体的实现步骤:
1. 让DateConverter成为可注入类
先改造你的DateConverter,给构造函数加上@Inject注解。这里推荐直接注入FoobarManager而非通过静态App.get()获取,更贴合依赖注入的设计原则:
class DateConverter { private final FoobarManager foobarManager; // 让Dagger直接注入FoobarManager(前提是你的Component已经能提供这个实例) @Inject public DateConverter(FoobarManager foobarManager) { this.foobarManager = foobarManager; } @TypeConverter public Foobar toFoobar(String str) { // 直接用注入好的FoobarManager,彻底摆脱对Context和静态App的依赖 return foobarManager.convert(str); } }
如果确实需要保留Context依赖,也可以这么写(但还是优先推荐上面的方式):
class DateConverter { private final Context mContext; private final FoobarManager foobarManager; @Inject public DateConverter(Context context, FoobarManager foobarManager) { mContext = context; this.foobarManager = foobarManager; } @TypeConverter public Foobar toFoobar(String str) { return foobarManager.convert(str); } }
2. 在Dagger Component中声明提供DateConverter
确保你的AppComponent(或者对应子Component)能提供DateConverter实例,Dagger会自动处理它的依赖注入:
@Singleton @Component(modules = {AppModule.class, ...}) public interface AppComponent { // 声明提供DateConverter的方法 DateConverter dateConverter(); // 其他需要提供的依赖... // 比如如果需要提供Context,要在AppModule里写@Provides方法: // @Provides // @Singleton // Context provideContext(Application app) { return app; } }
3. 将Dagger创建的Converter传递给Room Database
修改你的Room Database类,添加一个静态创建方法,接收Dagger注入好的DateConverter,然后在构建器中添加这个转换器:
@Database(entities = {YourEntityClass.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract YourDao yourDao(); // 静态方法,接收Dagger提供的DateConverter实例 public static AppDatabase create(Context context, DateConverter dateConverter) { return Room.databaseBuilder(context, AppDatabase.class, "your_database_name") .addTypeConverter(dateConverter) // 把注入好的转换器交给Room .build(); } }
4. 在Application中初始化Dagger并创建Database
最后在你的Application类(或其他初始化入口)里,用Dagger获取DateConverter实例,再创建Room Database:
public class YourApp extends Application { private AppComponent appComponent; @Override public void onCreate() { super.onCreate(); // 初始化Dagger Component appComponent = DaggerAppComponent.builder() .appModule(new AppModule(this)) // 如果你的Module需要Application参数 .build(); // 用Dagger提供的DateConverter创建Database AppDatabase database = AppDatabase.create(this, appComponent.dateConverter()); } }
为什么这种方式可行?
Room默认会尝试用无参构造实例化TypeConverter,但咱们通过addTypeConverter()手动传入了Dagger已经注入好的实例,绕开了Room的自动实例化逻辑,让Dagger完全接管了DateConverter的依赖注入,完美避免了静态Context的使用。
内容的提问来源于stack exchange,提问作者WongDao
相关产品推荐
相关产品推荐

