如何使用Dagger创建自定义范围?
有指导方针吗?我没找到他们.
我正在开发一个Vaadin应用程序,需要一个自定义范围.像UiScoped这样的东西.
最好的祝福
我正在开发一个Android应用程序,我一直在使用Dagger依赖注入.
我现在正试图测试一个具有这些依赖关系的片段,让我们称之为ProductsService.
在我的Robolectric测试中,我有一个覆盖的测试模块ProductsService:
@Module(
includes = ProductsModule.class,
injects = {
Fragment.class,
FragmentTest.class
},
overrides = true
)
static class MockProductsModule {
@Provides
@Singleton
public ProductsService providesProductsService() {
return Mockito.mock(ProductsService.class);
}
}
Run Code Online (Sandbox Code Playgroud)
在我的测试中,为了运行我的片段,我按如下方式构建它(如此处所示如何使用Robolectric测试片段?)
FragmentActivity activity = Robolectric.buildActivity(FragmentActivity.class)
.create()
.start()
.resume()
.get();
FragmentManager fragmentManager = activity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(fragment, null);
fragmentTransaction.commit();
Run Code Online (Sandbox Code Playgroud)
问题是,在创建过程中,它会调用Dagger以满足它的依赖关系:
((MyApplication)getActivity().getApplication()).inject(this);
Run Code Online (Sandbox Code Playgroud)
如何覆盖创建片段时创建的对象图,以便MockProductsModule在我的测试中使用I声明?
我正在尝试使用Dagger注入一个Android Annotated Activity.
java.lang.IllegalArgumentException: No inject registered for members/com.app.server.AddServerActivity_. You must explicitly add it to the 'injects' option in one of your modules.
如果我尝试添加com.app.server.AddServerActivity_到模块,我会得到一个不同的错误
Error: java.lang.ClassCastException: com.sun.tools.javac.code.Attribute$Error cannot be cast to com.sun.tools.javac.code.Attribute$Class
java.lang.RuntimeException: java.lang.ClassCastException: com.sun.tools.javac.code.Attribute$Error cannot be cast to com.sun.tools.javac.code.Attribute$Class
at com.sun.tools.javac.main.Main.compile(Main.java:469)
at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:132)
at org.jetbrains.jps.javac.JavacMain.compile(JavacMain.java:167)
at org.jetbrains.jps.incremental.java.JavaBuilder.compileJava(JavaBuilder.java:364)
at org.jetbrains.jps.incremental.java.JavaBuilder.compile(JavaBuilder.java:276)
at org.jetbrains.jps.incremental.java.JavaBuilder.doBuild(JavaBuilder.java:190)
at org.jetbrains.jps.incremental.java.JavaBuilder.build(JavaBuilder.java:162)
at org.jetbrains.jps.incremental.IncProjectBuilder.runModuleLevelBuilders(IncProjectBuilder.java:1018)
at org.jetbrains.jps.incremental.IncProjectBuilder.runBuildersForChunk(IncProjectBuilder.java:742)
at org.jetbrains.jps.incremental.IncProjectBuilder.buildTargetsChunk(IncProjectBuilder.java:790)
at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunkIfAffected(IncProjectBuilder.java:705)
at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunks(IncProjectBuilder.java:526)
at org.jetbrains.jps.incremental.IncProjectBuilder.runBuild(IncProjectBuilder.java:314)
at org.jetbrains.jps.incremental.IncProjectBuilder.build(IncProjectBuilder.java:179)
at org.jetbrains.jps.cmdline.BuildRunner.runBuild(BuildRunner.java:129)
at org.jetbrains.jps.cmdline.BuildSession.runBuild(BuildSession.java:220)
at org.jetbrains.jps.cmdline.BuildSession.run(BuildSession.java:112)
at org.jetbrains.jps.cmdline.BuildMain$MyMessageHandler$1.run(BuildMain.java:132)
at org.jetbrains.jps.service.impl.SharedThreadPoolImpl$1.run(SharedThreadPoolImpl.java:41) …Run Code Online (Sandbox Code Playgroud) 根据这个链接,我可以创建一个测试应用程序,Robolectric将自动开始在测试中使用.我不能让这个工作.
我使用Dagger进行依赖注入,并为Activity和创建了注入包装类Application.然后我的每个活动都扩展了包装器活动类而不是普通的老类Activity.
我遇到的问题是,在测试中,Application模块提供的依赖关系无法解析,因此测试失败.这是因为我们的大多数测试只是构建一个活动(使用Robolectric.buildActivity())而不是从一个Application.
我希望以某种方式修改Robolectric testrunner来运行我们的测试Application.或者使用上面链接中概述的测试应用程序.
我已经创建了一个测试应用程序,但仍然遇到相同的测试错误,因为测试未在此测试应用程序下运行.我已经尝试将测试应用程序移动到不同的包等,但没有任何改变.
我正在寻找一些关于如何去做我想要的建议.对那些有Dagger经验以及他们如何进行测试的人特别感兴趣.
是否可以将通过dagger暴露的对象注入android.app.IntentService?如果是这样,我该怎么做?
我希望有类似的东西.
public class SomeService extends android.app.IntentService {
@Inject
Synchronizer synchronizer;
public SomeService(String name) {
super(name);
}
@Override
protected void onHandleIntent(Intent intent) {
synchronizer.doSynch();
}
Run Code Online (Sandbox Code Playgroud)
}
我正在尝试使用Dagger对我正在构建的应用程序执行依赖注入,并且当我有一个包的模块时,根据Injector提供的值(可能是由另一个模块提供),在构建正确的DAG时遇到了麻烦.
如果我有一个简单的模块用于一些可配置的变量(例如,我可能想换掉测试环境)
@Module(
injects = DependentModule.class,
)
public class ConfigModule {
@Provides @Named("ConfigOption") String provideConfigOption() {
return "This Module's configurable option!";
}
}
Run Code Online (Sandbox Code Playgroud)
另一个模块取决于它,例如
@Module(
injects = {
TopLevelClass.class
}
)
public class DependentModule {
@Inject @Named("ConfigOption") String configOption;
public DependentModule() {
ObjectGraph.create(this).inject(this);
doSomethingWithConfig(configOption);
}
@Provides @Singleton UsefulValue provideUsefulValue() {
// Whatever this module needs to do...
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试在构造函数中引导注入的行失败了,它抱怨我没有injects在适当的模块中指定显式行.
通过反复试验,我看到如果@Module我添加一行就会消失include = ConfigModule.class,但这会让我觉得语义错误,因为a)我将创建的DAG现在将包含两个模块的值,而不仅仅是一个, b)它首先会破坏DI的目的/灵活性,以便链接特定的模块,而不是简单地让Dagger注入适当的值.
我假设我不应该创建一个this只注入它的对象图?但后来我遇到了没有链接特定模块的问题......
简洁:
addsTovs. …在开发Android应用程序时,我偶然发现了一个问题.我刚刚开始使用Dagger,所以我知道一些基本概念,但是当在教程范围之外使用它时,它们的用例变得不那么清楚了.
所以要明白这一点.在我的应用程序中,我正在使用MVP,如本博客文章中所述:http://antonioleiva.com/mvp-android/
所以起初我将Interactor类(处理数据的类)注入Presenter类,一切正常.但后来我实现了使用SQLite数据库的方法,所以现在需要在我的Interactor类中使用Context.
我无法弄清楚我该如何正确地做到这一点?我的临时修复是将Dagger从我的应用程序中排除,并在创建Presenter类时在构造函数中传递Context变量,然后在presenter中传递Interactor类,但我想使用Dagger.
所以我目前的应用看起来有点像这样.
MyActivity implements MyView {
MyPresenter p = new MyPresenter(this, getApplicationContext());
}
Run Code Online (Sandbox Code Playgroud)
MyPresenter中的构造函数
MyPresenter(MyView view, Context context) {
this.view = view;
MyInteractor i = new MyInteractor(context);
}
Run Code Online (Sandbox Code Playgroud)
在构造函数中MyInteractor我分配Context给一个私有变量.
我只需要注入MyInteractor来MyPresenter,因为这是应用程序,需要针对不同的实现进行测试的一部分.但是,如果它也将是可以注入MyPresenter到MyActivity,那将是巨大的:)
我希望有人对我想要实现的目标有一些经验:)
我是Dagger 2的新手,试图将一个(相当)复杂的应用程序移植到它.
我们对'common'库有几个依赖(与其他项目共享).那些"常见"库有时依赖于其他"常见"库.每个库都公开一个模块.
一个例子:
@Module
public class JsonModule {
@Provides
public Mapper provideMapper(ObjectMapper objectMapper) {
return new DefaultMapper(objectMapper);
}
@Provides
public ObjectMapper provideObjectMapper() {
return ObjectMapperFactory.build();
}
}
Run Code Online (Sandbox Code Playgroud)
我们的HttpModule依赖于JsonModule:
@Module(includes = {JsonModule.class})
public class HttpModule {
public HttpHelper provideHttpHelper(ObjectMapper objectMapper) {
return new DefaultHttpHelper(objectMapper);
}
}
Run Code Online (Sandbox Code Playgroud)
最后在我的应用程序中,我依赖于这两个模块:
@Module(includes = {JsonModule.class, HttpModule.class})
public class MyAppModule {
public Service1 provideService1(ObjectMapper objectMapper) {
return new DefaultService1(objectMapper);
}
public Service2 provideService2(Mapper mappper) {
return new DefaultService2(mappper);
}
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个依赖于我的MyAppModule的组件:
@Component(modules = MyAppModule.class)
@Singleton
public …Run Code Online (Sandbox Code Playgroud) 我有主持人
class PhonePresenter @Inject constructor(
private val preference: DataPreference,
private val ioScheduler: Scheduler = Schedulers.io())
Run Code Online (Sandbox Code Playgroud)
ioScheduler是默认参数。我只想注射preference: DataPreference. 现在我有例外
[dagger.android.AndroidInjector.inject(T)] io.reactivex.Scheduler cannot be provided without an @Provides-annotated method.
Run Code Online (Sandbox Code Playgroud)
有什么方法可以定义我想在构造函数中注入的参数吗?
我正在尝试使用 Dagger Hilt 和 Robolectric 运行测试:
@RunWith(RobolectricTestRunner::class)
@UninstallModules(LevelModule::class, AppModule::class)
@Config(sdk = [16, 28], application = HiltTestApplication::class)
@LooperMode(LooperMode.Mode.PAUSED)
@HiltAndroidTest
class LevelFragmentTest {
@get:Rule
var rule = HiltAndroidRule(this)
@Test
fun testShowGameOverWhenTapAMine() {
launchActivity<GameActivity>().onActivity { activity ->
ShadowLooper.runUiThreadTasks()
...
}
}
Run Code Online (Sandbox Code Playgroud)
测试失败,GameActivity.onCreate因为带有 @Inject 的 GameActivity 的所有字段都为空。
游戏活动是:
@AndroidEntryPoint
class GameActivity : AppCompatActivity()
Run Code Online (Sandbox Code Playgroud)
这些模块是:
@Module
@InstallIn(ActivityComponent::class)
open class LevelModule { ... }
Run Code Online (Sandbox Code Playgroud)
@Module
@InstallIn(ActivityComponent::class)
class TestLevelModule {
Run Code Online (Sandbox Code Playgroud)
@Module
@InstallIn(ApplicationComponent::class)
class AppModule() { ... }
Run Code Online (Sandbox Code Playgroud)
@Module
@InstallIn(ApplicationComponent::class)
class TestAppModule() { ... }
Run Code Online (Sandbox Code Playgroud)
它在我运行应用程序时有效,但是当我运行测试时, …