Hey guys,
I've got a database (sigh), but its very small and very fast and interfaces as a java.util.Map (yay!) --or rather, the Database object interfaces a Map-Factory.
This means that I get to write the
eminently testable code
public class CoolServiceOrController{
private final Map<UUID, ModelObject> modelStore;
@Inject
public class CoolServiceOrController(Map<UUID, ModelObject> modelStore){
this.modelStore = modelStore;
}
public void megaTransform(){
//load fortran code!
//use weird stupid Intel MKL functions!
//launch CUDA for good measure!
//oops! rollback!
//other complicated domain things!
}
}
which is really awesome because its stupidly easy to stub-out with test data. Very happy with my design decisions here.
What I would like to do is wire guice to resolve any request for a Map<UUID,
Anything> to
new StoreFacade(EventBus eb, SerializerFactory serializerFactory, Class<Anything> modelType, Database bigStupidSingletonThing). In the name principal-of-least-suprise I'm willing to use a BindingAnnotation along the lines of @DatabaseFacade on those maps to differentiate between regular Map<UUID, stuff> and Map<UUID, stuff> that should be using a database facade.
Having learned a little more about type erasure (largely because I was wondering why guice could see the generic types of things so often), I believe this is technically feasible from whiten guice. But it seems like guice's current approach to generics is to avoid them.
So the best approach I've managed to come up with is to manually enumerate those TAnythings with @Provides methods, which works, but is kloogy and requires changing bootstrapping logic for a lot of changes
public class MyModule extends Module{
public void configure(){
install(new FactoryModuleBuilder().implement(
new TypeLiteral<org.mapdb.Serializer<OptimizationModel>>() {},
new TypeLiteral<Serializer.MapDbXStreamBlobSerializer<OptimizationModel>>() {}
).build(new TypeLiteral<MapDBSerializerFactory<OptimizationModel>>() {})
);
install(new FactoryModuleBuilder().implement(
new TypeLiteral<org.mapdb.Serializer<ProjectState>>() {},
new TypeLiteral<Serializer.MapDbXStreamBlobSerializer<ProjectState>>() {}
).build(new TypeLiteral<MapDBSerializerFactory<ProjectState>>() {})
);
//...
}
//...
@Provides
public Map<UUID, OptimizationModel> getOptimizationMatStore(
EventBus eventBus,
MapDBSerializerFactory<OptimizationModel> serializer,
LethargicDatabaseFacade db) {
return new StoreFacade<>(eventBus, serializer, db, OptimizationModel.class);
}
@Provides
public Map<UUID, ProjectState> getHistoryStore(
EventBus eventBus,
MapDBSerializerFactory<ProjectState> serializer,
LethargicDatabaseFacade db){
return new StoreFacade<>(eventBus, serializer, db, ProjectState.class);
}
}
Is there a more elegant way to do this or is this as good as it (currently) gets?
Thanks for any help!
-Geoff