Comments (4)
A basic example:
@Module
public class BaseModule {
private Context context;
public BaseModule(Context context) { this.context = context; }
@Provides
@ApplicationScope
public Context providesContext() { return context; }
}
@Module
public class ContextModule {
private Context context;
public ContextModule(Context context) { this.context = context; }
@Provides
@ActivityScope
public Context providesLocalContext() { return context; }
@ApplicationScope
@Component(modules = BaseModule.class)
public interface BaseComponent {
@ApplicationScope
public Context appContext();
}
@Component(dependencies = BaseComponent.class, modules = ContextModule.class)
public interface ActivityComponent {
@ActivityScope
public Context activityContext();
}
The idea for this is that some objects will use an application level context (mainly singletons like Volley) while others might need just the local context (Some business logic class in a fragment). Ideally I'd just be able to specify which I'd like via:
@Inject
public SomePresenter(@ActivityScope Context context) { ... }
or
@Inject
public VolleyHelper(@ApplicationScope Context context) { ... }
from dagger.
Looking at your example, I think you're conflating two concepts - scope and qualification, and are doing so because Android is insane and uses the Context API for both application-level things and activity-level things.
I recommend you either supply @Qualifier
annotations to disambiguate application context from activity context, since these are two different instances, and you want them to be two different bindings,
... or (my recommendation) just drop using Context as a type, and bind Application and Activity, since nearly every usage where you'd consume these will either need to know one from the other, or won't care and will behave correctly for any Context, and so you can feed those methods the appropriate context yourself.
Then you don't have a lot of @Foo Context
things sprinkled around your code. You just have two types - Application
and Activity
- being consumed where appropriate, and being treated as a Context
where relevant. It'll save you a world of hurt.
As to scope validation, I think your problem will likely go away if you use @Qualifier
and @Scope
correctly. Scope goes in one of three places:
When attached to the type of a component interface, that scope annotation represents a constraint such that all bindings reachable by that component (either via included modules, or implicitly via @Inject
constructors must either be unscoped, or be of the same scope as the component. For instance the following means that FooActivity must be @ActivityScoped
as must any objects owned by MyActivityComponent except where it gets them from a dependency (which is a different component, so a different constraint applies). Like this:
@ActivityScope
@Component(...) interface MyActivityComponent {
FooActivity activity()
}
A scope annotation can also go on a @Provides
method or on the type of an injectable object (an object with an @Inject
constructor). Like so:
@ActivityScope
class MyFoo implements Foo {
@Inject MyFoo(Bar bar) {...}
}
@Module class MyModule {
@ActivityScope Bar bar(BarImpl impl) { return impl; }
}
This signals to dagger that these bindings in question are to be memoized in the component that was marked with @ActivityScope
.
Scope in Dagger is far less automagical than in Guice or Spring. Lifetimes are determined by the lifetime of the component's instance - what you get from the component builder. @Scope
annotations don't change that semantic very much, they merely are used as a signal to share an instance across a component, and are used to ensure that you don't declare something in one component that you meant to use in a component with a different lifetime.
from dagger.
All that said, we shouldn't have illegal state exceptions, we should have proper compiler errors. Can you please provide a stack-trace so we can figure out what check we're letting slip through?
from dagger.
We have had several updates since this but was filed - for now I'll close it. Feel free to re-open it if you can replicate the behavior with the latest snapshot.
from dagger.
Related Issues (20)
- Annotate interface with default Bind implementation HOT 2
- Transitive vulnerability from symbol-processing-api HOT 1
- java.lang.IllegalArgumentException: CreationExtras must have a value by `SAVED_STATE_REGISTRY_OWNER_KEY` HOT 4
- Update of different dependency: Error "package javax.annotation.processing is not visible" HOT 4
- Compile time error with KSP with Generics HOT 4
- java.lang.IllegalArgumentException: Multiple entries with same key HOT 4
- Execution failed for task ':app:kaptDebugKotlin'. > A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask$KaptExecutionWorkAction > java.lang.reflect.InvocationTargetException (no error message) HOT 2
- Stackoverflow when exposing parents of Subcomponents HOT 7
- Hilt not working with android testFixtures? HOT 2
- Hilt 2.44.2 - Class not found when use @AndroidEntryPoint at WidgetReceiver HOT 1
- Does Dagger 2.51 support JDK17 and JDK21? HOT 1
- [KSP] Intersection type bounds are not ordered correctly in generated factories HOT 1
- [KSP] KSP mode does not check for `@Provides` on interface methods HOT 1
- [KSP] Multibinding example from developer docs does not compile under Kotlin + KSP HOT 1
- [KSP] How to pass compiler argument to KSP? HOT 4
- The lack of sprite in the Friday Night Funkin character
- Subcomponent MembersInjector error in 2.51 HOT 1
- Does Hilt always execute app module during instrumented test? HOT 3
- [KSP] Dagger-KSP does not see typealiased dagger annotations HOT 3
- Cannot invoke getAnnotationValue because "annotation" is null HOT 14
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dagger.