Dependency Injection
that decides at call time.
DDI lets plain Java logic pick the implementation on every
@Inject.
Pricing tiers, quotas, roles, feature flags, multi-tenancy, mocks —
without a single if in your domain code.
@Inject@ResponsibleFor(ReportGenerator.class)
class ReportPolicy implements ClassResolver<ReportGenerator> {
public Class<? extends ReportGenerator> resolve(Class<ReportGenerator> i) {
var user = SecurityContext.current(); // e.g. jSentinel
if (user.quotaExceeded()) return ThrottledReport.class;
return switch (user.plan()) {
case FREE -> BasicReport.class;
case PRO -> FullReport.class;
case ENTERPRISE -> FullReportWithSLA.class;
};
}
}Why DDI
A nano library with one big idea: cross-cutting decisions belong in the resolver, not in your services.
Dynamic Resolution
ClassResolver runs on every @Inject — pick the impl with whatever Java logic you need.
Read more →Nano Footprint
Five public classes in the core. No XML, no annotation processor, no container.
Read more →Mock by Design
Tests use the same resolver mechanism — no Mockito, no PowerMock, no surprises.
Read more →Mutation-proven
Over 90% PIT mutation coverage. The library tests itself the way you should test yours.
Read more →When is the implementation chosen?
Classic DI containers bind at startup. CDI matches qualifiers statically. DDI hands the decision to your own code — every single time the field is injected.
How ClassResolver works →| Framework | Bound when? | Runtime change? |
|---|---|---|
| Spring | Container refresh | Profile flip + restart |
| Guice | Injector build | New injector |
| CDI / Weld | Qualifier match (static) | Hard-coded in annotation |
| DDI | Per @Inject lookup | Your own Java logic |
Drop it into your build
- ✓ JDK 21+, runs in any plain-Java process — CLI, Lambda, Vaadin, JavaFX.
- ✓ Five public classes in the core. No container, no XML.
- ✓ Reflections-based classpath scan; bootstrap is one method call.
- ✓ Licensed under EUPL 1.2 — friendly to commercial use.
<dependency>
<groupId>com.svenruppert</groupId>
<artifactId>ddi</artifactId>
<version>06.01.01</version>
</dependency>DI.activatePackages("com.example");
MyService svc = DI.activateDI(MyService.class);Plan-aware architecture, done right
Workshops, architecture reviews and pair-programming for teams introducing per-user / per-plan logic into Java backends — without rewriting their domain layer.
Learn more →Support continued maintenance
DDI is open source. Sponsoring keeps releases predictable and the roadmap public.
Become a sponsor →