I have some code that looks like this (simplified):
public Reader newInstance(Catalog catalog) {
Mapper mapper = new Mapper(catalog);
return new Reader(mapper)
}
public main() {
// expensive operation
Catalog catalog = readCatalogFromDatabase();
Reader reader = Reader.newInstance(catalog);
// do stuff with reader
}
How can I redesign this so that I still create Catalog, but Guice creates Reader and Mapper? I tried using assisted injections, but since Catalog isn’t a direct dependency of Reader, I can’t figure out how to get a factory method that accepts a catalog object.
There are two ways to do this:
Have Guice bind your Catalog. This may mean passing the Catalog instance into your Module, but Modules can take any number of constructor arguments, so that’s no problem. In your module this will look like:
If you really need to create a Reader based on an unknown or changeable instance of Catalog, then your hunch is right to use assisted injection. This is how I would make it look:
Then you can just inject
Reader.Factoryand get your reader by callingreaderFactory.create(catalog);. Note thatcreatecan be named anything, and theFactorycan be in any location with any name–those are just the names and locations I prefer.Now, in the AssistedInject documentation you’ll see that they also call
implement. You’ll only need to do this ifReaderis an interface, so Guice knows what kind of concrete class to build to satisfycreate‘s return type.Hope this helps!