java - Dagger2: Injecting implementation classes provided by modules with component itself -


considering modules shared among one-another through dagger1 specification of complete=false, library=true, can receive elements provided @provides methods through constructor parameter, so.

public class getuserforusernametaskimpl         implements getuserforusernametask {     public static final string tag = getuserforusernametaskimpl.class.getsimplename();      private realm realm;     private userrepository userrepository;      public getuserforusernametaskimpl(realm realm, userrepository userrepository) {         this.realm = realm;         this.userrepository = userrepository;     }      @override     public realmresults<userrlm> getusers() {         try {             realmresults<userrlm> users = userrepository.findall(realm);     ... }  @module(includes = {repositorymodule.class, realmmodule.class}) public class databasetaskmodule {     @provides     public getusersdatabasetask getusersdatabasetask(realm realm, userrepository userrepository) {         return new getusersdatabasetaskimpl(realm, userrepository);     } } 

however, specify 1 dependency (the presenter or customapplication instance) holds component graph, , use component graph inject implementation classes.

public class getuserforusernametaskimpl         implements getuserforusernametask {     public static final string tag = getuserforusernametaskimpl.class.getsimplename();      @inject     public realm realm;     @inject     public userrepository userrepository;      protected presenter presenter;     private boolean isinjected = false;      public getuserforusernametaskimpl(presenter presenter) {         this.presenter = presenter;     }      @override     public realmresults<userrlm> getusers() {         if(!isinjected) {             presenter.getpresentercomponent().inject(this);             isinjected = true;         }         try {             realmresults<userrlm> users = userrepository.findall(realm);             ...     } }  @module(includes = {presentermodule.class}) public class databasetaskmodule {     @provides     public getusersdatabasetask getusersdatabasetask(presenter presenter) {         return new getusersdatabasetaskimpl(presenter);     } } 

and way, you'd have depend on presenter's object graph, , not have mess constructor parameters.

which 1 better approach?

edit: clearer , concrete example have in not-too-well refactored project following:

@module(includes = {contextmodule.class}) public class clientauthmodule {     @provides     public clientauthauthenticator clientauthauthenticator(customapplication customapplication) {         return new clientauthauthenticator(customapplication);     } } 

then

public class customapplication         extends application {     public static class injectorinitializedevent {     }      public static class injectorinitializedeventproducer {         @produce         public injectorinitializedevent produceevent() {             return new injectorinitializedevent();         }     }      private applicationcomponent applicationcomponent;      @override     public void oncreate() {         super.oncreate();         applicationcomponent = injector.instance.initializeapplicationcomponent();         singletonbus.instance.getbus().post(new injectorinitializedevent());         singletonbus.instance.getbus().register(new injectorinitializedeventproducer()); //otto bus, event producer     }      public applicationcomponent getapplicationcomponent() {         return this.applicationcomponent;     } } 

then

public class clientauthauthenticator {     private customapplication customapplication;      @inject     public pemconverter pemconverter;     @inject     public keypaircreator keypaircreator;     @inject     public pkcs10csrcreator pkcs10csrcreator;     @inject     public keypairreader keypairreader;     //...      public clientauthauthenticator(customapplication customapplication) {         this.customapplication = customapplication;         singletonbus.instance.getbus().register(this);     }      @subscribe     public void oninjectorinitializedevent(customapplication.injectorinitializedevent e) {         customapplication.getapplicationcomponent().inject(this);         singletonbus.instance.getbus().unregister(this);     }      ... 

the question: way, dependencies provided application's component when injector ready, rather through constructor. approach? there caveats on long-run?

edit2: had injector here, pretty bad.

the 1 have in other project better constructed.

using constructor injection method annotating classes standard jsr-330 annotations, so:

  • the code decoupled concrete dependency injection library using. if need go to, let's say, old version of dagger, module , component definitions have change, not core classes.

  • your classes not need aware of details of how generated. tomorrow might have different components according scope, or might want component out of presenter classes. core classes should not change because of this.

  • it makes testing modules easier. no need run code generation or replace component instances through application. inject mock or test modules directly in constructor , done.

field , method injection should used in cases lifecycle of module out of control. case of activities or fragments in android environment. outside of use case, methods source of problems.


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -