java - 使用注释处理延迟绑定(bind)到 Dagger2 Graph

标签 java dependency-injection guice dagger dagger-2

在这个问题中我谈论Dagger2 。 Dagger2 基本上由组件和模块组成。这是一个例子:

假设我有一个界面:

public interface MyCoolService {
  void run();
}

以及可能的实现:

public class MyCoolServiceImpl {
   @Override
   void run() {}
}

我可以使用 Dagger2 生成将实现与接口(interface)链接起来:

@Component(modules = {MyModule.class})
@Singleton
public interface Component {    
    MyCoolService getMyCoolService();       
}

@Module
public class MyModule {

    @Provides @Singleton
    MyCoolService provideMyCoolService() {
        return new MyCoolServiceImpl();
    }
}

这是 Dagger2 的简要介绍。现在假设我有以下界面:

public interface MySecondCoolService {
  void doCoolStuff();
}

没有实现MySecondCoolServiceImplMySecondCoolService在代码中。相反,我有一个注释 @JustForCoolStuff标记字段和方法。我创建了一个注释处理器,它收集所有这些注释并生成 MySecondCoolServiceImpl它实现了 MySecondCoolService .

编译器知道新接口(interface) MySecondCoolService在注释处理器运行之前。所以我可以将我的组件更改为:

@Component(modules = {MyModule.class})
@Singleton
public interface Component {    
    MyCoolService getMyCoolService();   
    MySecondCoolService getMySecondCoolService();    
}    

问题是我在代码中还没有实现,并且我不知道 MySecondCoolService 的实现名称它将由注释处理器生成。因此,我无法在 MyModule 中使用正确的实现来连接接口(interface)。 。我能做的就是更改我的注释处理器,以便它为我生成一个新模块。我的注释处理器可以生成一个模块( MyGeneratedModule ),如下所示:

@Module
public class MyGeneratedModule {

    @Provides @Singleton
    MySecondCoolService provide MySecondCoolService() {
        return new MySecondCoolServiceImpl();
    }
}  

再次MyGeneratedModule由注释处理器生成。在运行注释处理器之前我无法访问它,而且我也不知道它的名称。

问题是这样的:注释处理器必须以某种方式告诉 Dagger2 有一个 Dagger2 应该考虑的新模块。由于注释处理器无法更改文件,因此无法扩展 @Component(modules = {MyModule.class})注释并将其更改为这样的内容:@Component(modules = {MyModule.class, MyGeneratedModule.class})

有没有办法添加 MyGeneratedModule以编程方式连接到 dagger2 依赖图?我的注释处理器如何告诉 Dagger2 在接口(interface)和实现之间应该有一个新的连接,正如我上面所描述的?

<小时/>

进军: 我知道类似的事情可以在 Google Guice 中完成和 Google Gin 。这样做的项目是 GWTP 。那里有一个演示者:

public class StartPagePresenter extends ... {
    @NameToken("start")
    public interface MyProxy extends ProxyPlace<StartPagePresenter> {
    }
    ...
}

其中有 @NameToken ProxyPlace 的注释界面。在你的AbstractPresenterModule您将 View 与演示者和代理连接起来:

public class ApplicationModule extends AbstractPresenterModule {

        bindPresenter(StartPagePresenter.class,
                StartPagePresenter.MyView.class, StartPageView.class,
                StartPagePresenter.MyProxy.class);
       ...
}

因此可以看到 MyProxy 没有实现给出了接口(interface)。由生成器创建的实现(类似于注释处理器,但适用于 GWT)。有 Generator 生成 StartPagePresenter.MyProxy 的实现并将其添加到guide/gin系统中:

public class StartPagePresenterMyProxyImpl extends com.gwtplatform.mvp.client.proxy.ProxyPlaceImpl<StartPagePresenter> implements buddyis.mobile.client.app.start.StartPagePresenter.MyProxy, com.gwtplatform.mvp.client.DelayedBind {

  private com.gwtplatform.mvp.client.ClientGinjector ginjector;
    @Override
    public void delayedBind(Ginjector baseGinjector) {
      ginjector = (com.gwtplatform.mvp.client.ClientGinjector)baseGinjector;
      bind(ginjector.getPlaceManager(),
          ginjector.getEventBus());
      presenter = new CodeSplitProvider<StartPagePresenter>( ginjector.getbuddyismobileclientappstartStartPagePresenter() );
    ...
    }
  }
<小时/>

最佳答案

Is there a way to add MyGeneratedModule programmatically to the dagger2 dependency graph?

是的。在模块中使用构造函数参数。

@Module
public class MyModule {
  private final MyCoolService serviceImpl;

  public MyModule(MyCoolService serviceImpl) {
    this.serviceImpl = serviceImpl;
  }

  @Provides @Singleton
  MyCoolService provideMyCoolService() {
    return new MyCoolServiceImpl();
  }
}

在构建图表时初始化 serviceImpl 已完成:

DaggerComponent.builder().myModule(new MyModule(serviceImpl)).build();

关于java - 使用注释处理延迟绑定(bind)到 Dagger2 Graph,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29836221/

相关文章:

java - Java Robot 类的一些问题

java - 是否有适合 Java 1.4 和 SE (Swing) 应用程序的优秀 DI 框架?

java - 如何根据程序启动时生成的数据初始化全局矩阵?

dependency-injection - CaSTLe - 使用构造函数注入(inject)类型工厂注入(inject)组件时,属性注入(inject)无法解析依赖关系

javascript - Angularjs 缩小最佳实践

Java Guice : If you inject the same dependency multiple times, 是该依赖项注入(inject)的同一个实例吗?

java - 导入中缺少 Guice 多重绑定(bind)包

java - 将 GuiceServletContextListener 连接到现有的注入(inject)器

java - C++ 中的 typedef 关键字是否有 Java 等效项或方法?

java - 返回动态语言用户的基本 Java 库和实用程序是什么?