Auto-Dagger2 icon indicating copy to clipboard operation
Auto-Dagger2 copied to clipboard

Using superinterfaces generates invalid component.

Open dan-dr opened this issue 9 years ago • 4 comments

If I have

@AutoComponent(
        dependencies = ApplicationComponent.class,
        modules = MainModule.class)
@AutoInjector
@PerActivity
public class MainActivity extends Activity {
}

@AutoComponent(
        superinterfaces = MainActivity.class,
        modules = {MainModule.class},
        dependencies = { ApplicationComponent.class }
)
@AutoInjector
@PerActivity
public class MyFragment extends Fragment {
}

This generates the following component:

@Generated("autodagger.compiler.AnnotationProcessor")
@Component(
    dependencies = ApplicationComponent.class,
    modules = {
        MainModule.class
    }
)
public interface MyFragmentComponent extends MainActivity {
  void inject(MyFragment myFragment);
}

Notice it extends MainActivity instead of MainActivityComponent

If i try to do superinterfaces = MainActivityComponent.class I'm getting an error: Error:(37, 8) error: Invalid value: superinterfaces cannot reference generated class. Use the class that applies the @AutoComponent annotation.

dan-dr avatar Dec 14 '15 11:12 dan-dr

Yes it cannot work like that. superinterfaces is a no brainer that adds the extends Interface on the generated component.

I didn't add the support for extending a component because I think it's not something that you would do. If the parent component contains some inject(...) methods, you don't want to inherit them, but only the exposed dependencies.

What I do is to create the exposed dependencies in a separated interface.

public interface ApplicationDependencies {
   MyDep1 myDep1();
   MyDep2 myDep2();
}

@Component
public interface ApplicationComponent extends ApplicationDependencies {
   void inject(Application app);
}

The children components will extend the ApplicationDependencies and not the component itself. Like this you avoid to inherit the method void inject(Application app)

@Component(dependencies = ApplicationComponent.class)
public interface ActivityComponent extends ApplicationDependencies {
   void inject(Activity activity);
}

And with auto component:

@AutoComponent(dependencies = ApplicationComponent.class, superinterfaces = ApplicationDependencies.class)
public class MyActivity extends Activity {

}

I'm assuming this is the right way to do it, but I may be wrong.

lukaspili avatar Dec 14 '15 16:12 lukaspili

Gotcha. Okay I guess you're right in this use case but I won't necessarily have an inject method to inherit, so it might be okay to support it - I mean I don't think this library should impose the way you write DI classes, but give you the power to mix it up a bit.

Thanks, great library:)

dan-dr avatar Dec 14 '15 18:12 dan-dr

Valid point. I'll include the support in the next version, beginning of January, as I'm quite busy right now. Thanks for the feedback!

lukaspili avatar Dec 14 '15 19:12 lukaspili

+1 for that feature

arok avatar Mar 20 '16 18:03 arok