toothpick
A scope tree based Dependency Injection (DI) library for Java / Kotlin / Android.
Top Related Projects
A fast dependency injector for Android and Java.
Guice (pronounced 'juice') is a lightweight dependency injection framework for Java 11 and above, brought to you by Google.
Koin - a pragmatic lightweight dependency injection framework for Kotlin & Kotlin Multiplatform
Uber's cross-platform mobile architecture framework.
Quick Overview
Toothpick is a dependency injection (DI) library for Android and Java applications. It provides a lightweight, annotation-based approach to dependency injection, focusing on simplicity and performance. Toothpick aims to offer a more straightforward alternative to other DI frameworks like Dagger.
Pros
- Lightweight and fast, with minimal runtime overhead
- Easy to learn and use, especially for developers new to dependency injection
- Supports both Android and Java applications
- Offers runtime and compile-time checks for dependency graph consistency
Cons
- Smaller community and ecosystem compared to more established DI frameworks
- Limited documentation and examples available
- May require more manual configuration for complex dependency graphs
- Not as widely adopted in large-scale enterprise applications
Code Examples
- Basic dependency injection:
public class Coffee {
@Inject
public Coffee() {}
}
public class CoffeeMaker {
@Inject
Coffee coffee;
@Inject
public CoffeeMaker() {}
}
Scope scope = new Toothpick.openScope("CoffeeApp");
CoffeeMaker coffeeMaker = scope.getInstance(CoffeeMaker.class);
- Binding an interface to an implementation:
public interface Heater {
void heat();
}
public class ElectricHeater implements Heater {
@Inject
public ElectricHeater() {}
@Override
public void heat() {
// Implementation
}
}
Scope scope = Toothpick.openScope("CoffeeApp");
scope.installModules(new Module() {{
bind(Heater.class).to(ElectricHeater.class);
}});
- Providing a singleton instance:
public class CoffeeBean {
@Inject
public CoffeeBean() {}
}
Scope scope = Toothpick.openScope("CoffeeApp");
scope.installModules(new Module() {{
bind(CoffeeBean.class).singleton();
}});
Getting Started
To use Toothpick in your Android project, add the following dependencies to your build.gradle
file:
dependencies {
implementation 'com.github.stephanenicolas.toothpick:toothpick-runtime:3.1.0'
implementation 'com.github.stephanenicolas.toothpick:smoothie-androidx:3.1.0'
annotationProcessor 'com.github.stephanenicolas.toothpick:toothpick-compiler:3.1.0'
}
Then, initialize Toothpick in your application class:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Toothpick.setConfiguration(Configuration.forProduction().disableReflection());
}
}
Now you can start using Toothpick for dependency injection in your Android application.
Competitor Comparisons
A fast dependency injector for Android and Java.
Pros of Dagger
- More mature and widely adopted in the industry
- Extensive documentation and community support
- Better performance for large-scale applications
Cons of Dagger
- Steeper learning curve and more complex setup
- Requires more boilerplate code
- Compile-time code generation can increase build times
Code Comparison
Dagger:
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(MainActivity activity);
}
@Module
class AppModule {
@Provides
SomeService provideSomeService() {
return new SomeServiceImpl();
}
}
Toothpick:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Toothpick.openScope(this).installModules(new AppModule());
}
}
class AppModule extends Module {
public AppModule() {
bind(SomeService.class).to(SomeServiceImpl.class);
}
}
Both Dagger and Toothpick are dependency injection frameworks for Java and Android, but they differ in their approach and complexity. Dagger offers more features and is better suited for large-scale projects, while Toothpick aims for simplicity and ease of use in smaller to medium-sized applications.
Guice (pronounced 'juice') is a lightweight dependency injection framework for Java 11 and above, brought to you by Google.
Pros of Guice
- More mature and widely adopted in the Java ecosystem
- Extensive documentation and community support
- Supports a broader range of injection scenarios and advanced features
Cons of Guice
- Heavier footprint and slower startup time
- More complex configuration, especially for larger projects
- Not optimized for Android development
Code Comparison
Guice:
public class RealBillingService implements BillingService {
@Inject
public RealBillingService(CreditCardProcessor processor,
TransactionLog transactionLog) {
// ...
}
}
Toothpick:
public class RealBillingService {
@Inject CreditCardProcessor processor;
@Inject TransactionLog transactionLog;
public RealBillingService() {
// ...
}
}
Guice uses constructor injection by default, while Toothpick typically uses field injection. Toothpick's approach can lead to simpler code in some cases, but may sacrifice some compile-time safety.
Both libraries aim to provide dependency injection for Java applications, but Toothpick is specifically designed with Android in mind, offering faster initialization and a smaller footprint. Guice, on the other hand, provides a more comprehensive set of features for larger Java applications but may be overkill for simpler Android projects.
Koin - a pragmatic lightweight dependency injection framework for Kotlin & Kotlin Multiplatform
Pros of Koin
- Lightweight and easy to set up, with minimal boilerplate code
- Seamless integration with Kotlin coroutines and Android Jetpack
- Extensive documentation and community support
Cons of Koin
- Lacks compile-time safety, relying on runtime dependency resolution
- May have performance overhead in large-scale applications
- Limited support for advanced dependency injection features
Code Comparison
Koin:
val myModule = module {
single { MyService() }
factory { MyViewModel(get()) }
}
startKoin {
modules(myModule)
}
Toothpick:
Toothpick.openScope(this)
.installModules(new MyModule());
class MyModule extends Module {
public MyModule() {
bind(MyService.class).singleton();
bind(MyViewModel.class).toProvider(MyViewModelProvider.class);
}
}
Key Differences
- Koin is designed specifically for Kotlin, while Toothpick supports both Java and Kotlin
- Toothpick offers compile-time dependency validation, whereas Koin relies on runtime resolution
- Koin's syntax is more concise and Kotlin-friendly, while Toothpick follows a more traditional Java-style approach
- Toothpick provides more advanced features like scopes and lazy loading, which may be beneficial for larger projects
Uber's cross-platform mobile architecture framework.
Pros of RIBs
- Comprehensive architecture framework for large-scale apps
- Built-in support for cross-platform development (iOS and Android)
- Extensive documentation and tutorials provided by Uber
Cons of RIBs
- Steeper learning curve due to complex architecture
- May be overkill for smaller projects or simpler apps
- Tightly coupled with Uber's specific architectural decisions
Code Comparison
RIBs (Router implementation):
class SomeRouter(
interactor: Interactor<SomeInteractor.SomePresenter, SomeRouting>,
component: SomeBuilder.Component
) : ViewRouter<SomeView, SomeInteractor, SomeBuilder.Component>(interactor, component)
Toothpick (Dependency injection):
@Inject
public SomeClass(@Named("someParam") String param) {
// Constructor injection
}
Key Differences
- RIBs focuses on a complete architectural pattern, while Toothpick is primarily a dependency injection framework
- RIBs is more opinionated about app structure, whereas Toothpick is more flexible and can be integrated into various architectures
- Toothpick has a simpler API and is easier to adopt in existing projects
- RIBs provides more built-in tools for navigation and state management
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Toothpick (a.k.a T.P. like a teepee)
|
|
Visit TP wiki ! |
What is Toothpick ?
Toothpick is a scope tree based Dependency Injection (DI) library for Java.
It is a full-featured, runtime based, but reflection free, implementation of JSR 330.
What does Toothpick offer ?
//a typical Toothpick scope tree during the execution of an Android app.
@ApplicationScope
/ | \
/ | \
/ | \
@ViewModelScope | Service 2
/ |
/ Service 1
/
@Activity1Scope
/
/
Activity 1
/ \
/ Fragment 2
/
Fragment 1
Scopes offer to compartmentalize memory during the runtime of an app and prevent memory leaks. All dependencies created via Toothpick, and available for injections, will be fully garbage collected when this scope is closed. To learn more about scopes, read TP wiki.
Toothpick is :
- pure java (Android support is provided: "Smoothie", Kotlin support is provided by "KTP")
- fast, it doesn't use reflection but annotation processing
- TP supports incremental annotation processing (isolating).
- simple, flexible, extensible & powerful, robust & tested
- thread safe
- documented & Open Source
- scope safe : it enforces leak free apps
- test oriented : it makes tests easier
- is a candidate of choice for Android or any other context based framework (such as web containers)
Examples
This is the example:
Setup
The latest version of TP is provided by a badge at the top of this page.
For Android :
#android setup using gradle 5.5.1
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.x'
}
}
...
#for java
dependencies {
implementation 'com.github.stephanenicolas.toothpick:toothpick-runtime:3.x'
// and for android -> implementation 'com.github.stephanenicolas.toothpick:smoothie-androidx:3.x'
annotationProcessor 'com.github.stephanenicolas.toothpick:toothpick-compiler:3.x'
//highly recommended
testImplementation 'com.github.stephanenicolas.toothpick:toothpick-testing-junit5:3.x'
testImplementation 'mockito or easymock'
}
#for kotlin
dependencies {
implementation 'com.github.stephanenicolas.toothpick:ktp:3.x'
kapt 'com.github.stephanenicolas.toothpick:toothpick-compiler:3.x'
//highly recommended
testImplementation 'com.github.stephanenicolas.toothpick:toothpick-testing-junit5:3.x'
testImplementation 'mockito or easymock'
}
For java:
<!--java setup with maven -->
<dependencies>
<dependency>
<groupId>com.github.stephanenicolas.toothpick</groupId>
<artifactId>toothpick-compiler</artifactId>
<version>3.x</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.stephanenicolas.toothpick</groupId>
<artifactId>toothpick-runtime</artifactId>
<version>3.x</version>
<scope>compile</scope>
</dependency>
<!-- highly recommended-->
<dependency>
<groupId>com.github.stephanenicolas.toothpick</groupId>
<artifactId>toothpick-testing</artifactId>
<version>3.x</version>
<scope>test</scope>
</dependency>
<dependency>
<easymock or mockito>
</dependency>
</dependencies>
Support
TP is actively maintained and we provide support to questions via the Toothpick-di tag on Stack Over Flow.
Ask questions on Stack Over Flow while keeping the GitHub issue board for real issues. Thx in advance !
Talks & Articles
- A Dependency Injection Showdown - Pro Android Dev article
- Toothpick 3 â a hidden gem in the DI world - Medium article
- How I learned to love unit testing with Toothpick - Groupon's medium blog article
- Droidcon, Boston 2017 - Slides & Video
- Migrating off RoboGuice 3 (to Toothpick) - Part 1 & Part 2
- Mobius, Saint Petersburg 2017 - Slides
- Mobius, Saint Petersburg 2017 - DI frameworks & Internals Slides
- Android Makers, Paris 2017 - Slides & Video
- DroidCon, Kaigi 2017 - Slides
- Andevcon, San Francisco 2016 - Slides
- DroidCon, Krakow 2016 - TP Vs Dagger 2 Talk from Danny Preussler slides
- Mobile Era, Oslo 2016 - Slides
- Droidcon, Berlin 2016 - Slides - Sketch notes
- Android Leaks 2016 - podcast in French
- DevFest Belgium 2016 - video in French
- DevFest Siberia 2017 - video in Russian
- DevFest North 2017 - video in Russian
- Toothpick: a simple DI for Android development (Russian)
Wanna know more ?
Visit Toothpick's wiki !
Alternative Dependency Injection (DI) engines for Android
RoboGuice(deprecated)Dagger 1(deprecated)- Dagger 2
- transfuse
- lightsaber
tiger(deprecated)- feather
- proton
- koin
- Kodein-DI
Libs / Apps using TP 2
- Okuki is a simple, hierarchical navigation bus and back stack for Android, with optional Rx bindings, and Toothpick DI integration.
- KotlinWeather is a simple example of using ToothPick with Kotlin and gradle integration using kapt.
Credits
TP 1 & 3 have been developped by Stephane Nicolas and Daniel Molinero Reguera. Most of the effort on version 2 has been actively supported by Groupon. Thanks for this awesome OSS commitment !
Top Related Projects
A fast dependency injector for Android and Java.
Guice (pronounced 'juice') is a lightweight dependency injection framework for Java 11 and above, brought to you by Google.
Koin - a pragmatic lightweight dependency injection framework for Kotlin & Kotlin Multiplatform
Uber's cross-platform mobile architecture framework.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot