2015-04-07 11 views
23

Ho chiesto (e ho risposto) la stessa domanda per Dagger 1 here. Come potrei fare qualcosa di simile per Dagger 2, ora che ObjectGraph.inject non esiste più.Come faccio a iniettare in un servlet con Dagger 2?

questa domanda potrebbe essere generalizzata a:

come si fa membri iniezione se l'oggetto deve essere creato da un quadro diverso? (in questo caso, un contenitore Servlet).

risposta

7

Ho cercato di rispondere a questa stessa domanda. I penso Mi sono avvicinato a come "dovrebbe" funzionare idealmente, ma sto solo derpando attorno al progetto GitHub e cercando di capirlo in base a frammenti di informazioni lì, come molta documentazione per Dagger 2 è ancora in fase di scrittura (da questa settimana).

Il mio codice di esempio qui sotto è in realtà per un'attività Android, ma credo che questo stesso approccio dovrebbe funzionare per il servlet che stai chiedendo.

Aggiungere un elemento per i membri < ...> all'interfaccia @Component; per esempio, nel componente di seguito ho aggiunto uno per la mia classe MainActivity:

package ...; 

import javax.inject.Singleton; 
import dagger.Component; 
import dagger.MembersInjector; 

@Singleton 
@Component(modules = { PlaygroundModule.class }) 
public interface MainComponent { 
    Wizard createWizard(); 
    MembersInjector<MainActivity> mainActivityInjector(); 
} 

E poi nella classe che si desidera essere membro-iniettato, in un luogo appropriato, dopo la creazione di oggetti, ma prima è necessario utilizzare i membri iniettato, è necessario creare il componente e utilizzare l'iniezione membro:

package ...; 

// other imports 
import javax.inject.Inject; 
import dagger.MembersInjector; 

public class MainActivity extends ActionBarActivity { 

    @Inject 
    Wizard wizard; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     MainComponent c = DaggerMainComponent.create(); 
     c.mainActivityInjector().injectMembers(this); 

     // other code... 
    } 
} 

l'unica cosa che non sono chiare su è se questo modello di creazione del componente all'interno dell'oggetto che dovrebbe essere iniettato in è corretta. Non sembra giusto, ma è ancora molto flessibile dato che si sta vincolando solo strettamente al componente e non ai moduli. Quindi forse questo è l'approccio corretto, ma forse è un po 'fuori.

+2

Ah; è anche possibile creare un metodo di annullamento nell'interfaccia del componente che accetta un oggetto e eseguirà l'iniezione di membri su di esso. Sarebbe un po 'più semplice del codice sorgente fornito qui, ma funzionalmente lo stesso. Ecco la documentazione pertinente: https://google.github.io/dagger/api/2.0/dagger/Component.html –

0

Anche se non sono molto contento di questo dato che devo scrivere codice boilerplate, qualcosa come questo funziona con servlet.

public class MyServlet extends HttpServlet { 

    @Inject 
    MyService service; 

    @Override 
    public void init(ServletConfig config) throws ServletException { 
    super.init(config); 
    this.service = MyDaggerComponent.create().injectMyService(); 
    } 
} 

Si può considerare la creazione dell'istanza MyDaggerComponent in ServletContext e quindi ottenere in questo modo nel metodo init():

((MyDaggerComponent)config.getServletContext().getAttribute("MyDaggerComponent")).injectMyService()