Git Product home page Git Product logo

Comments (19)

marwinxxii avatar marwinxxii commented on April 28, 2024

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.

andaag avatar andaag commented on April 28, 2024

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.

marwinxxii avatar marwinxxii commented on April 28, 2024

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.

andaag avatar andaag commented on April 28, 2024

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.

andaag avatar andaag commented on April 28, 2024

Looking at my code the components are required in many places due to contentproviders/activities/fragments, all of which require empty constructors.

from dagger.

marwinxxii avatar marwinxxii commented on April 28, 2024

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.

andaag avatar andaag commented on April 28, 2024

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.

marwinxxii avatar marwinxxii commented on April 28, 2024

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.

Alexander-- avatar Alexander-- commented on April 28, 2024

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.

marwinxxii avatar marwinxxii commented on April 28, 2024

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.

Alexander-- avatar Alexander-- commented on April 28, 2024

@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.

cgruber avatar cgruber commented on April 28, 2024

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.

lukaspili avatar lukaspili commented on April 28, 2024

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.

cgruber avatar cgruber commented on April 28, 2024

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-dagger2

Is 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.

lukaspili avatar lukaspili commented on April 28, 2024

Ok, makes sense. Thanks for the details.

from dagger.

netdpb avatar netdpb commented on April 28, 2024

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.

cgruber avatar cgruber commented on April 28, 2024

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.

netdpb avatar netdpb commented on April 28, 2024

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.

cgruber avatar cgruber commented on April 28, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.