Last active
April 14, 2019 22:37
-
-
Save vovkab/c97b9530a5470336975dde37d8db2ea7 to your computer and use it in GitHub Desktop.
Example of using Dagger 2 in libraries
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example; | |
import java.lang.annotation.Retention; | |
import javax.inject.Inject; | |
import javax.inject.Scope; | |
import javax.inject.Singleton; | |
import dagger.Binds; | |
import dagger.BindsInstance; | |
import dagger.Component; | |
import dagger.Module; | |
import dagger.Provides; | |
import okhttp3.OkHttpClient; | |
import static java.lang.annotation.RetentionPolicy.RUNTIME; | |
/** | |
* Example of using dagger in libraries. | |
* <p> | |
* Let's say we want to create a library that would provide us with users for specific social network. | |
* We would name this library "UsersLibrary". This library depends on DataLibrary, which contains | |
* domain models and repositories. | |
* <p> | |
* To make social networks pluggable we would need to provide different implementations | |
* of the DataLibrary, for example: | |
* * TwitterDataLibrary | |
* * FacebookDataLibrary | |
* * GoogleDataLibrary, | |
* * etc. | |
* <p> | |
* Each of this libraries would depend on api libraries: | |
* * TwitterApiLibrary | |
* * FacebookApiLibrary | |
* * GoogleApiLibrary | |
*/ | |
public class ExperimentDagger { | |
// | |
// Api library | |
// | |
public static class FacebookApi { | |
@Inject | |
public FacebookApi(OkHttpClient client) { | |
} | |
} | |
interface FacebookApiLibrary { | |
FacebookApi api(); | |
} | |
@Component | |
interface FacebookApiComponent extends FacebookApiLibrary { | |
@Component.Builder | |
interface Builder { | |
@BindsInstance | |
Builder client(OkHttpClient client); | |
FacebookApiComponent build(); | |
} | |
} | |
// | |
// Data Library (domain layer) | |
// | |
public interface UsersData { | |
} | |
public interface UsersDataLibrary { | |
UsersData usersData(); | |
} | |
// | |
// Facebook implementation of the UsersData | |
// | |
public static class FacebookUsersData implements UsersData { | |
@Inject | |
public FacebookUsersData(FacebookApi api) { | |
} | |
} | |
@Module | |
interface FacebookUsersDataModule { | |
@Binds | |
UsersData bindsUsersData(FacebookUsersData data); | |
} | |
@Component( | |
modules = FacebookUsersDataModule.class, | |
dependencies = FacebookApiLibrary.class | |
) | |
interface FacebookUsersDataComponent extends UsersDataLibrary { | |
@Component.Builder | |
interface Builder { | |
Builder apiLibrary(FacebookApiLibrary api); | |
FacebookUsersDataComponent build(); | |
} | |
} | |
// | |
// Main Library that uses Data | |
// | |
public static class UsersApp { | |
@Inject | |
public UsersApp(UsersDataLibrary data) { | |
} | |
public void hello() { | |
System.out.println("Hello!"); | |
} | |
} | |
interface UsersLibrary { | |
UsersApp users(); | |
} | |
@Component(dependencies = UsersDataLibrary.class) | |
interface UsersLibraryComponent extends UsersLibrary { | |
@Component.Builder | |
interface Builder { | |
Builder dataLibrary(UsersDataLibrary dataLib); | |
UsersLibrary build(); | |
} | |
} | |
/** | |
* Using library from application if app is not using Dagger | |
*/ | |
public static void usingLibrary() { | |
OkHttpClient client = new OkHttpClient(); | |
FacebookApiLibrary apiLib = DaggerExperimentDagger_FacebookApiComponent.builder() | |
.client(client) | |
.build(); | |
UsersDataLibrary dataLib = DaggerExperimentDagger_FacebookUsersDataComponent.builder() | |
.apiLibrary(apiLib) | |
.build(); | |
UsersLibrary usersLibrary = DaggerExperimentDagger_UsersLibraryComponent.builder() | |
.dataLibrary(dataLib) | |
.build(); | |
usersLibrary.users().hello(); | |
} | |
// | |
// If client app using dagger, we can create separate module to bind them all. | |
// | |
// Or you could have separate "integration" library that provides module or component. | |
// | |
@Scope | |
@Retention(RUNTIME) | |
public @interface ApiLibScope { | |
} | |
@Module(includes = NetworkModule.class) | |
class FacebookUsersModule { | |
@Provides | |
@Singleton | |
UsersLibrary providesUsersLibrary(UsersDataLibrary data) { | |
return DaggerExperimentDagger_UsersLibraryComponent.builder() | |
.dataLibrary(data) | |
.build(); | |
} | |
@Provides | |
@Singleton | |
UsersDataLibrary providesUsersDataLibrary(FacebookApiLibrary apiLib) { | |
return DaggerExperimentDagger_FacebookUsersDataComponent.builder() | |
.apiLibrary(apiLib) | |
.build(); | |
} | |
@Provides | |
@Singleton | |
FacebookApiLibrary providesFacebookApiLibrary(@ApiLibScope OkHttpClient client) { | |
return DaggerExperimentDagger_FacebookApiComponent.builder() | |
.client(client) | |
.build(); | |
} | |
} | |
@Module | |
class NetworkModule { | |
@Provides | |
@ApiLibScope | |
OkHttpClient providesOkHttpClient() { | |
return new OkHttpClient(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment