Skip to content

Instantly share code, notes, and snippets.

@vovkab
Last active April 14, 2019 22:37
Show Gist options
  • Save vovkab/c97b9530a5470336975dde37d8db2ea7 to your computer and use it in GitHub Desktop.
Save vovkab/c97b9530a5470336975dde37d8db2ea7 to your computer and use it in GitHub Desktop.
Example of using Dagger 2 in libraries
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