The dependency injection design pattern improves the configurability, testability, and maintainability of object-oriented applications by decoupling components from both the concrete implementations of their dependencies and the strategy employed to select those implementations. In recent years, a number of libraries have emerged that provide automated support for constructing and connecting dependency-injected objects. Our experience developing systems with these tools has led us to identify two shortcomings of existing dependency injection solutions: the mechanisms for specifying component implementations often make it difficult to write and configure systems of arbitrarily-composable components, and the toolkit implementations often provide limited capabilities for inspection and static analysis of the object graphs of dependency-injected systems. We present Grapht, an new dependency injection container for Java that addresses these issues by providing context-aware policy, allowing component implementation decisions to depend on where in the object graph a component is required, and using a design that allows for static analysis of configured object graphs. To achieve its objectives, Grapht is built on a mathematical representation of dependency injection and object graphs that facilitates static analysis and straightforward implementation, and forms a basis for further consideration of the capabilities of dependency injection. The mathematical representation includes context-aware policy that we show to be strictly more expressive than the qualified dependencies used in many current toolkits. We demonstrate the utility of our approach with a case study showing how Grapht has aided in the development of the LensKit recommender systems toolkit.
[1]
Shrinidhi Hudli,et al.
A Verification Strategy for Dependency Injection
,
2013
.
[2]
Michael D. Ekstrand.
Towards Recommender Engineering: Tools and Experiments in Recommender Differences
,
2014
.
[3]
Ewan Tempero,et al.
An Empirical Study into Use of Dependency Injection in Java
,
2008
.
[4]
Matthias Noback.
The Dependency Inversion Principle
,
2018
.
[5]
Dhanji R. Prasanna,et al.
Dependency Injection
,
2009
.
[6]
Esteban Walter Gonzalez Clua,et al.
Smart composition of game objects using dependency injection
,
2009,
CIE.
[7]
Naranker Dulay,et al.
Specifying Distributed Software Architectures
,
1995,
ESEC.
[8]
David S. Janzen,et al.
Effects of dependency injection on maintainability
,
2007,
ICSE 2007.
[9]
Shigeru Chiba,et al.
Aspect-Oriented Programming Beyond Dependency Injection
,
2005,
ECOOP.
[10]
John Riedl,et al.
Rethinking the recommender research ecosystem: reproducibility, openness, and LensKit
,
2011,
RecSys '11.