groostav
07/27/2016, 8:36 PMI wish some kotlin magic could have a better solution for that
some kind of dslso the line
bindFactory<(UUID) -> Account>()
should be do-able, with a little kotlin magic. I'm looking into As soon as you need to be more flexible, though - again, consider cases requiring laziness, pooling, etc. - you'd need to shift to more standard techniques anywayThe beautiful thing about guice assisted inject is that you're setting your code up to take a regular interface to a factory anyways. I actually encountered this problem where guice's assisted inject factories were simply too slow (they do a full reflection-filled dependency tree walk every time you ask them for an instance), so I whipped up an instance to do the really obvious thing:
class MyFastFactory extends IMyFactory{
@Inject Dep1 dep1;
@Inject Dep2 dep2;
public InstanceType create(Dep1 dep1, Dep2 dep2, RuntimeDep3 dep3){
return new InstanceType(dep1, dep2, dep3);
}
}
and then simply bind(IMyFactory.class).to(MyFastFactory.class)
Also, the most tedious thing for me is that guice has a hard cut between static dependencies and dynamic dependencies. So this means that if you have a user flow A to B to C to D to E, where each of these are steps or screens or menus or whatever, and A resolves som dependency Dep3
, where B and C and D and E all want an instance of Dep3, then you would need to use assisted inject factories for all of them.
Our solution is to have multiple Bootstrappers
that each create their own module, but these bootstrappers themselves will have runtime dependencies (eg BootstrapperBCDE takes a Dep3
as a ctor argument) that they then, in turn, register as pseudo-static dependencies with guice. Any instance created by the resulting injector can now access `Dep3`as a regular dependency. The only problem with this strategy is deciding when its worth simply using factories repeatedly and when its worth creating a new bootstrapper with a new module. Unfortunately, creating modules is still fairly verbose.