使用注释处理器生成Dagger组件

时间:2017-04-01 23:39:00

标签: android dagger-2 annotation-processing

我正在使用遵循MVP架构模式的Android应用程序。在我的所有片段中,我都注入了一个Presenter。因此我的碎片(视图)需要有一个Component,我在其中声明了注入。例如:

@ActivityScope
@Component(
        dependencies = AppComponent.class,
        modules = {
                PresenterModule.class,
                InteractorModule.class
        }
)
public interface ViewInjectorComponent {
    void inject(SelectEventOccurrenceFragment fragment);
    void inject(CreateOpponentFragment fragment);
    void inject(SelectOpponentFragment fragment);
    void inject(TeammatesInvitedFragment fragment);
    ...
}

我添加到我的应用程序(片段)中的每个新视图都需要在此处声明其条目。我想知道是否可以使用某种注释处理器自动生成此代码。该App已经有几个片段,这个组件文件很容易有300多个条目。如果我可以做类似的事情,那就太棒了。

@Injectable
public class MyNewFragment implements MyNewView {
...
}

然后在ViewInjectorComponent文件中自动生成条目。可能吗?我应该在哪里看看?

2 个答案:

答案 0 :(得分:1)

您遇到的情况可能是以不寻常的方式组织模块和组件的结果。特别是,横向分组(一个Component注入所有Presenters)而不是垂直分组(一个组件注入与SelectOpponentActivity相关的功能)是有问题的。

要遵循的一个好例子是Google Android Architecture Blueprints GitHub repo。如果您仔细阅读那里的代码,您将看到他们在一个Java包中组织了与Tasks相关的功能以及单独的Component,Module,Presenter等。这样可以限制类的构造函数的可访问性。包含在其中并实现有效的Java项目13:最小化类和成员的可访问性。

同样,您已将所有模块组合成一个Presenter模块和一个Interactor模块。 Dagger 2官方文档的建议是organise Modules first for testability,然后是功能线。同样,您可以参考Blueprint示例了解如何执行此操作。

最后,请注意,使用大多数DI框架(如Dagger 2)时不可避免地会遇到一些样板。从某种意义上说,您正在交换更大的问题("我如何处理所有这些构造函数?&#34 ;)具有更小,更易于管理的问题("我如何对我的组件进行分组"等等。)

<强>更新 有一个名为Auto Dagger2的库可以为您生成组件。见this Github repo。以下是注释的示例:

@AutoComponent
@Singleton
public class ExampleApplication extends Application { 
}

生成以下代码:

@Component
@Singleton
public interface ExampleApplicationComponent { 
}

如果您对代码生成工具感兴趣,请查看Google Auto

答案 1 :(得分:0)

我不完全确定我要说的是适合答案的,但我会抓住机会。

即使你找到了一种方法来做你想做的事情,也不要在生产中这样做(如果你只是想学习代码生成技术,这很好。)

从这种方法中获得的好处很小(不是写几行简单的代码),但要考虑其缺点:

  1. 需要编写/调试/维护代码生成的逻辑
  2. 这种做法违反了“最不惊讶的原则”
  3. 代码生成是BAD
  4. 注意第三点 - 我的意思是。代码生成的使用总是导致维护开销,因此它应该仅作为最后的手段使用。

    Dagger本身使用代码生成,但有充分的理由 - 性能。但是,在您的情况下,性能不是问题。

    总结一下:您的想法非常有趣,但是这样的方法不应该用于生产应用程序(除非本机将此功能添加到Dagger中)。