配置在Guice中返回泛型类型的Provider

时间:2014-06-18 13:42:29

标签: java dependency-injection guice jdbi

我尝试为使用JDBI创建的DAO设置Provider。 JDBI使用Handle对象(它是JDBC Connection的包装器),您可以使用handle.attach(MyDaoType.class)来获取DAO。而不是必须为每个DAO类编写单独的Provider实现,我认为这样做是有道理的:

public class DaoProvider<T> implements Provider<T> {

  private final Class<T> daoType;
  private final Handle handle;

  @Injected 
  public DaoProvider(Class<T> daoType, Handle handle) {
    this.daoType = daoType;
    this.handle = handle;
  }

  @Override
  public T get() {
    return handle.attach(daoType);
  }
}

但是与Guice联系似乎非常困难。我已经尝试使用this answer中建议的第一个构造函数参数上的@Assisted注释。我定义了这样的工厂:

public interface DAOProviderFactory {
  <T> DAOProvider<T> create(Class<T> daoType);
}

但我不清楚我应该如何调用FactoryModuleBuilder.implemented方法,因为重点是我不想扩展我的提供程序类。

我有一个工厂返回提供商并返回我真正想要的东西,这似乎有点疯狂!

让我感到震惊的是,使用Spring DI容器真的很容易,所以我想相信Guice可以做到这一点。有人能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:3)

感谢@condit为我指出能让我解决问题的东西。它实际上非常简单。我将Provider实现更改为Handler使用字段注入,如下所示:

public class DAOProvider<T> implements Provider<T> {

  private @Inject Handle handle;
  private final Class<T> daoType;

  public DAOProvider(Class<T> daoType) {
    this.daoType = daoType;
  }

  @Override public T get() {
    return handle.attach(daoType);
  }
}

然后在任何我想要绑定的特定DAO类的模块或应用程序中,我可以做这样的事情:

bind(UserStore.class).toProvider(new DAOProvider<>(UserStore.class));
bind(MessageStore.class).toProvider(new DAOProvider<>(MessageStore.class));

然后,Guice会自动将Handle注入DAOProvider个实例。

答案 1 :(得分:0)

我认为你这太复杂了。当您调用get()方法时,您将结果存储在引用中,这意味着您知道特定DAO的类型,这意味着您可以在知道DAO类的情况下编写代码。我的意思是,想想Guice本身是如何工作的,你调用Injector.getInstance(Class<?> type) ...换句话说,这样的方法无论如何都不能推断出Class,所以传递{{1当你使用它时!

我可以理解为什么你可能不想直接注入Class,所以为什么不做一个包装器,例如。

Handle

然后:

public interface DaoProvider {
  <T> T provideDao(Class<T> daoType);
}