1

Without AssistedInjection, I have the following

interface IA { ... }
class B implements IA { 
        B (String p)
}
class C implements IA { 
        C (String p)
}

interface IAFactory {
  IA create(String p)
}
class BFactory implements IAFactory { ... }
class CFactory implements IAFactory { ... }

But to use AssistedInjection, I'd need

class UberFactory {
        B createB(@Assisted("stringB") String p)
        C createC(@Assisted("stringC") String p)
}

and the corresponding changes in B and C.

There are 2 problems with this:

  1. Application code has to understand whether to call createB or createC
  2. The UberFactory cuts across my package structure to instantiate instances of IA

It seems to me that a more intuitive API would be:

install(new FactoryModuleBuilder()
     .implement(IA.class, B.class)
     .annotatedWith(BFactoryQualifier.class)
     .build(IAFactory.class));
install(new FactoryModuleBuilder()
     .implement(IA.class, C.class)
     .annotatedWith(CFactoryQualifier.class)
     .build(IAFactory.class));

That way I can simply annotate the IAFactory instance I inject into my application code.

But as far as I can see, there's no such API. So,

  1. Is there something I'm missing that makes such an API unreasonable?
  2. Is there a way to approximate this behavior given the currently available features?
SANDeveloper
  • 560
  • 2
  • 7
  • 22
  • 1
    In my opinion, there is no benefit to being able to annotate the Factory instance you inject. That's the same as your problem #1 - the application code needs to know what instance to inject .It's just configuring it based on an annotation, but that's effectively the same as calling `createB` vs `createC`. Or knowing to inject/use `BFactory` vs `CFactory`. This is related to #2... knowing what type you need is a cross cutting concern that needs to be dealt with somewhere. – Daniel Bickler Jul 07 '17 at 18:35
  • Yes, but isn't using Annotations to do that more consistent with Guice's syntax? – SANDeveloper Jul 11 '17 at 15:43
  • While annotations are more consistent with Guice's syntax, I think it would help to take a broader look at your design. The factory pattern as used by Guice is to mix injected parameters and caller-passed parameters. The normal factory pattern is used to create objects based on an interface. Why not have 1 factory with 1 create method that instantiates `B` or `C` based on logic contained in the create() method? Then the calling code wouldn't need to know whether it's creating a `B` or a `C`. – Daniel Bickler Jul 11 '17 at 16:01
  • If you can provide some more context for your classes and details as to your end goal is, I can try to write up an answer of how I would implement this if you'd like. – Daniel Bickler Jul 11 '17 at 16:02
  • Having the single factory creating all required objects is definitely one option (assuming the required parameters can be passed by the calling code). We'd be pushing the decision we make in the Module setup to the Factory.create code. But if I did not use AssistedInject, it would be cleaner to keep the Factories separate. I'll be able to use annotated factories. It doesn't seem right to combine the factories to be able to use AssistedInject. – SANDeveloper Jul 11 '17 at 19:36

0 Answers0