How can I inject parameter through constructor in

2019-05-10 17:55发布

问题:

This question is probably exact duplicate of this one Pass parameter to constructor with Guice

Difference is that I use roboguice for android, not just Guice, so answers there does not work for me.

Question is - how can I pass initialize parameters into created object? I.e. I have injected interface which should be initialize with some parameter which roboguice does not know.

What I see in link I provide, I should create factory interface and register it like this

  void configure(Binder binder) {
   binder.install(new FactoryModuleBuilder()
         .implement(FooInterface.class, Foo.class)
         .build(FooFactory.class));
  }


But I can't find FactoryModuleBuilder class. I use Intellij IDEA, it can show me every class which I can access at current place and I can be 100% sure that there is no classes which starts with 'Factory' word.

How can I create my factory using roboguice?

UPDATED

I forgot to download guice-assistedinject. But still I can't figure out where should I register this factory.

UPDATE 2

Why I need that? Because there should be situation where some abstraction has dependency which could not be resolved by Roboguice. This dependency could be any type, even simple string or number.

In my case I have NumberPicker control on UI and I want to move all UI specific tasks in MyNumberPickerWrapper class. And when I create this wrapper I inject its dependency (this control) through constructor.

It's not the point if I am right with such approach, but that there could be a plenty of another more applicable example where constructor injection needed and this injected classes could not be created by Roboguice

回答1:

I followed the steps of the answer given in Pass parameter to constructor with Guice and did slight modifications to run it under roboguice. Works completely fine for me.

  1. add guice-assistinject library to gradle script

    dependencies { compile 'com.google.inject.extensions:guice-assistedinject:4.+' }
    
  2. Create Factory interface that with create method that accepts parameters the object constructor requires and returns object's interface

    public interface ICustomObjectFactory {
        ICustomObject create(String queueName);
    } 
    
  3. Add @Inject annotation to constructor of the object and @Assisted annotation to each parameter coming from factory.

    public class CustomObject implements ICustomObject {
        protected String name;
    
        @Inject
        public CustomObject(@Assisted String name){
           this.name = name;
        }
    }
    
  4. Add binding into the Module that you are using

    public class SomeModule extends AbstractModule {
    
        @Override
        protected void configure() {
             install(new FactoryModuleBuilder()
                .implement(ICustomObject.class, CustomObject.class)
                .build(ICustomObjectFactory.class));
        }
    }
    
  5. Inject factory and create instances of your object

    public class SomeClass {
    
        @Inject ICustomObjectFactory factory;
    
        public SomeClass () {
            ICustomObject first = this.factory.create("first");
            ICustomObject second = this.factory.create("second");
        }
    }
    


回答2:

I faced this same problem and I succeed thanks to Pavel's answer. I only have had to struggle with some errors, and I don't know if it's due to the versions of the libraries used, but for me didn't work without modifying the annotation of the constructor, replacing @Inject by @AssistedInject. With that, the code of the class that implements the interface looks like this.

public class CustomObject implements ICustomObject {
    protected String name;

    @AssistedInject
    public CustomObject(@Assisted String name){
       this.name = name;
    }
}