I'm trying to set up a Provider
for DAOs created using JDBI. JDBI uses a Handle
object (which is a wrapper around a JDBC Connection
) and you can get hold of a DAO by using handle.attach(MyDaoType.class)
. Rather than having to write a separate Provider
implementation for every DAO class I thought it would make sense to do this:
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);
}
}
But it seems tremendously difficult to wire this up with Guice. I have tried using the @Assisted
annotation on the 1st constructor argument as suggested in this answer. I defined a factory like this:
public interface DAOProviderFactory {
<T> DAOProvider<T> create(Class<T> daoType);
}
But it's not clear how I should invoke the FactoryModuleBuilder.implemented
method as the whole point is that I don't want to have to extend my provider class.
It also seems a bit crazy that I'd have a factory that returns a provider that returns the thing I actually want!
It strikes me that this would be really easy to do with the Spring DI container so I want to believe it's possible with Guice. Can anyone point me in the right direction?
Thanks to @condit for pointing me at something that enabled me to solve the issue. It's actually very simple. I changed the Provider
implementation to use field injection for the Handler
like this:
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);
}
}
Then in any module or application where I have specific DAO classes I want to bind I can just do something like this:
bind(UserStore.class).toProvider(new DAOProvider<>(UserStore.class));
bind(MessageStore.class).toProvider(new DAOProvider<>(MessageStore.class));
Guice then injects the Handle
into the DAOProvider
instances automatically.