Comments (6)
Do you have an example where this is a problem? Generally speaking, I've seen being able to use a Provider
to break a cycle as a fairly commonly used feature. I've also rarely seen it result in an actual infinite loop at runtime as this mostly would happen when you call Provider.get()
in the constructor, which is itself kind of a weird thing to do whether or not it is part of a cycle.
Also, if you want to implement this yourself though, it doesn't have to be built-in to Dagger. You can write an SPI plugin that does the check in your code.
from dagger.
In my case, on Android, we use Lazy
to avoid the injection of fairly heavy hierarchies used by a small percentage of users (e.g. logout, as it doesn't happen for most app sessions). The problem appears when in this hierarchy, a cycle is accidentally added later during the development. I can prepare a sample project to visualize it, if needed.
Those cases often are caught in testing, but a combination of feature flags, country-specific behaviors, app variants, etc makes it easy to miss.
I'll check out SPI plugins, thank you for the suggestion. However, I'd still appreciate your opinion on the solution proposed in #4300. One can argue that dependency cycles, even hidden behind a Provider
, are code smells, as mentioned in the original issue, and thus should be warned against.
from dagger.
SPI did solve my issue, thanks!
However, if possible, I'd still love to see this check as an (optional) part of Dagger itself. With SPI the responsibility of Lazy cycle checks is duplicated between Dagger internals and consumer's plugins.
from dagger.
The problem appears when in this hierarchy, a cycle is accidentally added later during the development. I can prepare a sample project to visualize it, if needed.
AFAIK though, in order to complete the cycle, you'd have to have a situation where you do a Lazy.get()
in the constructor? No need for a full sample project, but do you have an example of when you would do that? Usually if you have a Lazy
, you shouldn't use it in the constructor.
The problem with such a check is that there are numerous valid use cases. So the check isn't useful unless there is an exemption mechanism, since otherwise once the valid use case is in, you have to turn off the check letting other cases in. Normally in an SPI plugin that is specific to your project, you can hardcode various lists like package lists, binding lists, etc to match your needs. If this is built-in, I'd have to build something standard like that and make it work probably through annotations on bindings, but it almost definitely won't meet every need as convenient exemptions often have to match the use case. For example, maybe some thing has a lot of these legitimate cycles and now you need regexes or some matcher whereas in your own plugin you can just look for a particular pattern.
(An example of a normal legitimate use case is often in the case of some handler. You have a Map<Key, Provider<Handler>>
where you look up like how do I handle this request and then handle it. But then one handler might be a composite type and needs to break down a request into multiple requests and go back through the map.)
from dagger.
in order to complete the cycle, you'd have to have a situation where you do a Lazy.get() in the constructor?
Isn't it also possible to encounter a cycle when using the retrieved class? Regardless of whether it's injected in the constructor, or not. As a simple example (irl this loop can be hidden between layers of abstraction making it hard to notice)
class A {
val b : Lazy<B>
fun execA() {
b.get().execB()
}
}
class B {
val a: Lazy<A>
fun execB() {
a.get().execA()
}
}
All in all, thanks for the explanation. Since this doesn't seem like a popular request, and SPI solves it, I assume that a built-in matcher wouldn't be worth the effort. I'll close this issue and the related PR, thanks again for your help!
from dagger.
Ah okay, I wasn't thinking of that kind of cycle because that is actually an infinite loop in logic. I was trying to think of cases where Dagger causes you to have an infinite loop in an otherwise valid logical case, where something about the mechanisms of Dagger injecting dependencies creates a loop (i.e. some sort of case you could fix if you just weren't using Dagger at all).
from dagger.
Related Issues (20)
- [Dagger-Hilt] Can't get viewModel in composable by Hilt HOT 1
- Why does Provides in a Companion Object work? HOT 6
- Update Dagger guava dependency to address CVE-2023-2976 HOT 2
- Add KMP support for @HiltViewModel annotation HOT 2
- Dagger resolution and dynamic feature module HOT 1
- Feature request: Manually regenerate application component HOT 1
- Using TestContainer.com HOT 2
- error when ksp.useKSP2=true HOT 2
- Suppress annotation on @Inject is not honored on the Factory HOT 1
- [KSP2] Dagger and Hilt incompatibility with KSP2 HOT 2
- [KSP2] NullPointerException: null cannot be cast to non-null type androidx.room.compiler.processing.XType HOT 1
- App crashing with NPE for some classes when Lazy Class Key is used HOT 6
- OutOfMemoryError with Maven HOT 1
- DaggerAppComponent not creating in the version 2.51.1 HOT 3
- java.lang.ClassNotFoundException: dagger.spi.shaded.androidx.room.compiler.processing.javac.JavacBasicAnnotationProcessor. Hilt 2.49+ HOT 1
- how to manually generate module HOT 1
- Explain how to add dagger jar files manually to the android project HOT 2
- Annotate interface with default Bind implementation HOT 2
- Transitive vulnerability from symbol-processing-api HOT 1
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.