How to use PicoContainer for a constructor with paramenter

2.9k views Asked by At

I am using PicoContainer and I have to add a component which has a constructor with paramenter. So I have

public abstract class IA {

   @Inject
   protected B b;

   public void useB(){
        b.useSomeMethodOfB();
   }
}

public interface IC{}

public class C implements IC{}

public class A extends IA{

     private IC mSomeOtherComponent;

     public A(IC someOtherComponent){
         mSomeOtherComponent = someOtherComponent
     }
}

Now to instatiate this component I have:

MutablePicoContainer context = new PicoBuilder().withAnnotatedFieldInjection().withCaching().build();

then

contex.addComponent(A.class, new A(new C()));

but when I call useB() method in the abstract class it returns null, it doesn't inject anything. I think it's not right the way I added the component. I also tried;

ComponentParameter pr = new ComponentParameter(new C());
context.addComponent(IA.class, A.class, pr);  

and

 ComponentParameter pr = new ComponentParameter(new C());
 context.addComponent(A.class, A.class, pr);  

but it says that "A has unsatisfied dependency for fields B.

How could I solve it?

3

There are 3 answers

2
Abderrazak BOUADMA On

It's not so intuitive

public interface ThreadPool {  
 void setSize(int);  
}  

public class MyComp {  
 private ThreadPool threadPool;
 public MyComp(ThreadPool pool) {  
    threadPool = pool;  
    threadPool.setSize(size);  
 }  
} 

In order to invoke the MyComp(ThreadPool pool) constructor you've to do the following :

DefaultPicoContainer pico = new DefaultPicoContainer();  
pico.addComponent(ThreadPool.class, DefaultThreadPool.class);  
pico.addComponent(MyComp.class, MyComp.class);

MyComp myComp = (MyComp)pico.getInstance(MyComp.class);  

As you notice, the fact that you registred ThreadPool before instantiating MyComp, that will satisfy "greediest" condition to let PicoContainer invoke the parametrized constructor instead of the default one.

more information here

Cheers

0
xeye On

Do you have B in the container? If you can't inject it in the constructor you can use http://picocontainer.codehaus.org/multi-injection.html to inject both field and constructor

1
Shilaghae On

I ended up injecting the constructor

    context.addComponent(IC.class, C.class);

    context.addComponent(A.class, A.class);

and in class A I injected the constructor so:

    @Inject
    private IC c;

So now depending on what I need I can add to the context whatever implementation of C class I need.