2014-06-18 57 views
3

返回一个泛型类型我试图设立一个DAO的使用Provider创建JDBI提供者。 JDBI使用Handle对象(它是JDBC Connection的包装器),您可以使用handle.attach(MyDaoType.class)获取DAO。而不是写一个单独的Provider实现每一个DAO类我认为这将是有意义的做到这一点:配置,在吉斯

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); 
    } 
} 

但似乎非常困难与吉斯到这样组装起来。我使用1号构造函数的参数的@Assisted注释试图在this answer建议。我定义了一个工厂是这样的:

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

但它并不清楚我应该怎么调用FactoryModuleBuilder.implemented方法,整个的一点是,我不希望有延长我的供应商类。

它也似乎有点疯狂,我想有一个工厂返回一个提供商返回其实我想要的东西!

它给我的印象,这将是很容易做的春天DI容器,所以我愿意相信这是可能的吉斯。任何人都可以将我指向正确的方向吗?

+1

看看这个可能的解决方案:https://stackoverflow.com/questions/24030609/how-do-i-pass-parameters-into-a-provider-with-guice – condit

+0

@condit这使我能够出来。谢谢。如果您想添加答案,我会接受,否则我会在稍后发布我的解决方案。 –

回答

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)); 

吉斯然后自动喷射HandleDAOProvider实例。

+0

正如一边 - 我不知道你如何管理'Handle',但你可能要考虑使用“按需”方法来检索你的DAO。这样你就不必担心'Handle'没有关闭。你会注入你的'DBI',然后在'get()'方法中调用'dbi.onDemand(daoType)'。 – condit

+0

@condit这是一个非常好的主意,是的。我想我正在泄漏处理所有地方。这只是一个小小的演示应用程序,所以不会引起任何问题,但无论如何都值得思考。 –

-1

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

我能理解为什么您可能不希望注入Handle直接了,所以为什么不只是做一个包装,例如

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

然后:

public class JdbiDaoProvider implements DaoProvider { 
    private final Handle handle; 

    @Inject 
    JdbiDaoProvider(Handle handle) { 
    this.handle = handle; 
    } 

    public <T> T provideDao(Class<T> daoType) { 
    return handle.attach(daoType); 
    } 
} 
+0

对我来说,在我需要DAO的地方,似乎没有注入'Handle'并使用'handle.attach()'的优点。没关系,我猜想,但我希望能够直接注入'UserDAO'或其他任何东西,而Guice应该能够提供一个。这简化了每个需要使用DAO的组件中的代码。 –