Comments (19)
Hello, I've been thinking on a similar problem. Based on your example, is there really need to create a component? May be it can be done as following:
public class LastSearchesContentProvider {
//some fields to be injected
//mark that fields should be injected in constructor
@Inject
LastSearchesContentProvider() {}
}
public class MyActivity extends Activity {
@Inject LastSearchesContentProvider mSearchesProvider;
public onCreate(Bundle b) {
ActivityComponent ac = Dagger_ActivityComponent.builder()
.finnApplicationComponent(...)
.build();
ac.inject(this);
}
}
@Component(dependencies=FinnApplicationComponent.class)
public interface ActivityComponent {
void inject(MyActivity activity);
}
As I understand, Provider's dependencies and Provider itself (as dependency) would be injected as long as they can be found in component (ActivityComponent in example).
from dagger.
That doesn't work. If I change the LastSearchesContentProvider from:
@Singleton
@Component(dependencies = FinnApplicationComponent.class)
interface LastSearchesComponent {
void inject(LastSearchesContentProvider target);
}
to inject(ParentClass target); the graph isn't correctly built, and the inject method does not inject the needed classes.
from dagger.
What I meant is, get rid of method in component (and therefore component itself)
void inject(LastSearchesContentProvider target);
And use constructor injection
public class LastSearchesContentProvider {
private final A mDependencyA;
private final B mDependencyB;
//mark that fields should be injected in constructor
@Inject
LastSearchesContentProvider(A a, B b) {
this.mDependencyA = a;
this.mDependencyB = b;
}
}
And inject this provider where needed.
from dagger.
Hm, I can probably do that for an awful lot of classes.. The contentprovider not being one of them of course, since it's constructed by the system and needs an empty constructor ;)
from dagger.
Looking at my code the components are required in many places due to contentproviders/activities/fragments, all of which require empty constructors.
from dagger.
You can have default empty constructor with @Inject
annotation. But, this object can't be created directly (if you want to avoid manual inject(...)
invocation), only injected. If it's a system component like activity, then yes, only way is to create component, I suppose.
from dagger.
I'd imagine that's the most used case for most of the android users though. Activities/Fragments/Views/Contentproviders/Actionproviders are all built around empty/preset constructors, and will be constructed by the system. Hence the need for quite many components ;)
from dagger.
I agree that it's most used case.
In my apps there no components which consist only of one activity/fragment
with one inject method, so I haven't experienced the problem you've
described.
May be such components will occur later.
15.01.2015 10:17 пользователь "andaag" [email protected] написал:
I'd imagine that's the most used case for most of the android users
though. Activities/Fragments/Views/Contentproviders/Actionproviders are all
built around empty/preset constructors, and will be constructed by the
system. Hence the need for quite many components ;)—
Reply to this email directly or view it on GitHub
#100 (comment).
from dagger.
Is there any progress on this? I imagine, this could be solved by supporting sort of profiles: predefined Dagger configs with lists of classes, that can't be created (and are illegal to use) in object graphs and should have components automatically created for them (Activities and ContentProviders on Android, Servlets in server environments etc.) The question is: how does one specify, which modules to use when creating each in typesafe way? Would it be possible to do that with something like old ObjectGraph, but with Oracle Tree Api instead of reflection for validation?
from dagger.
If you have a number of components with one inject method and with same number of modules, than you can create base class (activity, fragment, etc.) and base component injecting instances of this base class.
from dagger.
@marwinxxii, that'd be cool, but not really related to this issue. Similar Activities (with same dependencies) can be just refactored into single activity with multiple fragments. The real problem appears in any huge application, once number of framework-managed objects becomes big enough, that writing component for each one turns annoying. The annoying part is: invocation of inject
method of old ObjectGraph
already contained all information necessary to generate an empty component at compile time, it just has to be extracted somehow.
from dagger.
Ok - I am not 100% following the need here - I think this would really benefit from a little example project - one that may not work, but shows the shape of the code you would wnat to see, so we can figure out what that looks like.
from dagger.
Had the same issue as @andaag when implementing Dagger2 in my android apps.
Not a big deal, but ended up writing a small annotation processor that generates simple components: https://github.com/lukaspili/auto-dagger2
Is this something we could see in Dagger2, or is it out of scope?
from dagger.
It's been discussed, and it's not 100% off the table, but we're seeing what
evolves in the android and server spaces around this before deciding what
to implement in dagger core.
On Sat, 30 May 2015 at 15:19 Lukas Piliszczuk [email protected]
wrote:
Had the same issue as @andaag https://github.com/andaag when
implementing Dagger2 in my android apps.
Not a big deal, but ended up writing a small annotation processor that
generates simple components: https://github.com/lukaspili/auto-dagger2Is this something we could see in Dagger2, or is it out of scope?
—
Reply to this email directly or view it on GitHub
#100 (comment).
from dagger.
Ok, makes sense. Thanks for the details.
from dagger.
I don't think we're going to support this specific request. As @lukaspili found, it's easy enough to write a processor that does this if you want to, but I'm not sure that's the pattern everyone should use.
It's not difficult for each of your activity or fragment classes to have a nested component interface, which can either be used as a supertype of one big activity component or annotated with @Component
itself:
class LastSearchesContentProvider extends ContentProvider {
@Component(dependencies = FinnApplicationComponent.class)
interface Injector {
void inject(MyActivity myActivity);
}
}
We are planning to write documentation on the different ways to construct an Android application with Dagger, and the tradeoffs. We'll definitely discuss the issues you're raising here.
from dagger.
Frankly, you could even (if you really felt the need to reduce two more
lines of code) make
interface GenericInjector<T> {
void inject(T t);
}
And then do
class LastSearchesContentProvider extends ContentProvider {
@Component(dependencies = FinnApplicationComponent.class)
interface Injector extends GenericInjector<MyActivity> {}
}
Though frankly, I'm not even sure that it's worth the two lines, since it
reduces the readability at the declaration site and makes it require more
implicit knowledge when reading that code.
c.
On Tue, 8 Dec 2015 at 14:25 David P. Baker [email protected] wrote:
I don't think we're going to support this specific request. As @lukaspili
https://github.com/lukaspili found, it's easy enough to write a
processor that does this if you want to, but I'm not sure that's the
pattern everyone should use.It's not difficult for each of your activity or fragment classes to have a
nested component interface, which can either be used as a supertype of one
big activity component or annotated with @component itself:class LastSearchesContentProvider extends ContentProvider {
@component(dependencies = FinnApplicationComponent.class)
interface Injector {
void inject(MyActivity myActivity);
}
}We are planning to write documentation on the different ways to construct
an Android application with Dagger, and the tradeoffs. We'll definitely
discuss the issues you're raising here.—
Reply to this email directly or view it on GitHub
#100 (comment).
from dagger.
That works as well. It means you can't use those types as supertypes of a big component that implements them all, though, since one type can't implement both GenericInjector<Foo>
and GenericInjector<Bar>
.
from dagger.
True. As I said, there's limits to its usefulness. I see that pattern, at
best, useful for an android application scenario where you are making One
individual subcomponent per activity.
On Wed, 9 Dec 2015 at 06:59 David P. Baker [email protected] wrote:
That works as well. It means you can't use those types as supertypes of a
big component that implements them all, though, since one type can't
implement both GenericInjector and GenericInjector.—
Reply to this email directly or view it on GitHub
#100 (comment).
from dagger.
Related Issues (20)
- [KSP] dagger-android unresolved generated subcomponent for internal module methods used across gradle modules HOT 3
- Unable to build with 2.48.1 - 2.49 and 2.50 HOT 2
- KSP processing does not see member injections from typealiased superclass in 2.50 HOT 2
- Regression "warning: [cast] redundant cast to Map" when updating from 2.49 to 2.50 HOT 1
- Dagger-Hilt 2.49: Activity onCreate() and onDestroy() code is generated, but our base Activity class has these final HOT 3
- Dagger 2.50 produces code that calls deprecated method HOT 1
- Feature Request: lint rule for EarlyAccessPoint classes to prevent @Inject abuse HOT 13
- no
- Feature request: Add support for K2 compiler. HOT 2
- @HiltViewModel Unit test problem. HOT 2
- WorkerAssistedFactories are not created on APK builds HOT 5
- Getting `Unexpected annotation value: TransformedVisibilityMarker` error during unit test HOT 5
- @BindsInstance on Component.Factory supertype lambda parameters HOT 1
- SecurityException when trying to run UI test with hilt and Jetpack Compose on Android 14 HOT 3
- BadParcelableException in Activity onCreate HOT 3
- Dagger 2.50 KSP fails to generate field in implementation for a @Named field HOT 2
- Conflicting documentation for dagger.android and Hilt optional inject HOT 3
- [KSP] dagger-android hanging indefinitely on a large multi module project HOT 2
- Optional bindings in a parent component can sometimes use bindings from child components HOT 2
- NullPointerException dagger.spi.shaded.androidx.room.compiler.processing.XTypeElement.getAnnotation HOT 6
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.