Contexts And Dependency Injection
   HOME

TheInfoList



OR:

In
software engineering Software engineering is a branch of both computer science and engineering focused on designing, developing, testing, and maintaining Application software, software applications. It involves applying engineering design process, engineering principl ...
, dependency injection is a programming technique in which an
object Object may refer to: General meanings * Object (philosophy), a thing, being, or concept ** Object (abstract), an object which does not exist at any particular time or place ** Physical object, an identifiable collection of matter * Goal, an a ...
or function receives other objects or functions that it requires, as opposed to creating them internally. Dependency injection aims to separate the concerns of constructing objects and using them, leading to
loosely coupled In computing and systems design, a loosely coupled system is one # in which components are weakly associated (have breakable relationships) with each other, and thus changes in one component least affect existence or performance of another compo ...
programs. The pattern ensures that an object or function that wants to use a given
service Service may refer to: Activities * Administrative service, a required part of the workload of university faculty * Civil service, the body of employees of a government * Community service, volunteer service for the benefit of a community or a ...
should not have to know how to construct those services. Instead, the receiving "
client Client(s) or The Client may refer to: * Client (business) * Client (computing), hardware or software that accesses a remote service on another computer * Customer or client, a recipient of goods or services in return for monetary or other valuable ...
" (object or function) is provided with its dependencies by external code (an "injector"), which it is not aware of. Dependency injection makes implicit dependencies explicit and helps solve the following problems: * How can a
class Class, Classes, or The Class may refer to: Common uses not otherwise categorized * Class (biology), a taxonomic rank * Class (knowledge representation), a collection of individuals or objects * Class (philosophy), an analytical concept used d ...
be independent from the creation of the objects it depends on? * How can an application, and the objects it uses support different configurations? Dependency injection is often used to keep code in-line with the dependency inversion principle. In statically typed languages using dependency injection means that a client only needs to declare the
interfaces Interface or interfacing may refer to: Academic journals * ''Interface'' (journal), by the Electrochemical Society * '' Interface, Journal of Applied Linguistics'', now merged with ''ITL International Journal of Applied Linguistics'' * '' Inter ...
of the services it uses, rather than their concrete implementations, making it easier to change which services are used at runtime without recompiling. Application frameworks often combine dependency injection with inversion of control. Under inversion of control, the framework first constructs an object (such as a controller), and then passes
control flow In computer science, control flow (or flow of control) is the order in which individual statements, instructions or function calls of an imperative program are executed or evaluated. The emphasis on explicit control flow distinguishes an '' ...
to it. With dependency injection, the framework also instantiates the dependencies declared by the application object (often in the constructor method's parameters), and passes the dependencies into the object. Dependency injection implements the idea of "inverting control over the implementations of dependencies", which is why certain Java frameworks generically name the concept "inversion of control" (not to be confused with inversion of control flow).


Roles

Dependency injection involves four roles: services, clients, interfaces and injectors.


Services and clients

A service is any class which contains useful functionality. In turn, a client is any class which uses services. The services that a client requires are the client's ''dependencies''. Any object can be a service or a client; the names relate only to the role the objects play in an injection. The same object may even be both a client (it uses injected services) and a service (it is injected into other objects). Upon injection, the service is made part of the client's
state State most commonly refers to: * State (polity), a centralized political organization that regulates law and society within a territory **Sovereign state, a sovereign polity in international law, commonly referred to as a country **Nation state, a ...
, available for use.


Interfaces

Clients should not know how their dependencies are implemented, only their names and
API An application programming interface (API) is a connection between computers or between computer programs. It is a type of software interface, offering a service to other pieces of software. A document or standard that describes how to build ...
. A service which retrieves
email Electronic mail (usually shortened to email; alternatively hyphenated e-mail) is a method of transmitting and receiving Digital media, digital messages using electronics, electronic devices over a computer network. It was conceived in the ...
s, for instance, may use the
IMAP In computing, the Internet Message Access Protocol (IMAP) is an Internet standard protocol used by email clients to retrieve email messages from a mail server over a TCP/IP connection. IMAP is defined by . IMAP was designed with the goal of per ...
or
POP3 In computing, the Post Office Protocol (POP) is an application-layer Internet standard protocol used by e-mail clients to retrieve e-mail from a mail server. Today, POP version 3 (POP3) is the most commonly used version. Together with IMAP, i ...
protocols behind the scenes, but this detail is likely irrelevant to calling code that merely wants an email retrieved. By ignoring implementation details, clients do not need to change when their dependencies do.


Injectors

The injector, sometimes also called an assembler, container, provider or factory, introduces services to the client. The role of injectors is to construct and connect complex object graphs, where objects may be both clients and services. The injector itself may be many objects working together, but must not be the client, as this would create a circular dependency. Because dependency injection separates how objects are constructed from how they are used, it often diminishes the importance of the new keyword found in most
object-oriented languages Object-oriented programming (OOP) is a programming paradigm based on the concept of '' objects''. Objects can contain data (called fields, attributes or properties) and have actions they can perform (called procedures or methods and impleme ...
. Because the framework handles creating services, the programmer tends to only directly construct value objects which represents entities in the program's domain (such as an Employee object in a business app or an Order object in a shopping app).


Analogy

As an analogy,
car A car, or an automobile, is a motor vehicle with wheels. Most definitions of cars state that they run primarily on roads, seat one to eight people, have four wheels, and mainly transport people rather than cargo. There are around one billio ...
s can be thought of as services which perform the useful work of transporting people from one place to another. Car engines can require
gas Gas is a state of matter that has neither a fixed volume nor a fixed shape and is a compressible fluid. A ''pure gas'' is made up of individual atoms (e.g. a noble gas like neon) or molecules of either a single type of atom ( elements such as ...
, diesel or
electricity Electricity is the set of physical phenomena associated with the presence and motion of matter possessing an electric charge. Electricity is related to magnetism, both being part of the phenomenon of electromagnetism, as described by Maxwel ...
, but this detail is unimportant to the client—a passenger—who only cares if it can get them to their destination. Cars present a uniform interface through their pedals, steering wheels and other controls. As such, which engine they were 'injected' with on the factory line ceases to matter and drivers can switch between any kind of car as needed.


Advantages and disadvantages


Advantages

A basic benefit of dependency injection is decreased coupling between classes and their dependencies. By removing a client's knowledge of how its dependencies are implemented, programs become more reusable, testable and maintainable. This also results in increased flexibility: a client may act on anything that supports the intrinsic interface the client expects. More generally, dependency injection reduces
boilerplate code In computer programming, boilerplate code, or simply boilerplate, are sections of code that are repeated in multiple places with little to no variation. When using languages that are considered ''verbose'', the programmer must write a lot of boile ...
, since all dependency creation is handled by a singular component. Finally, dependency injection allows concurrent development. Two developers can independently develop classes that use each other, while only needing to know the interface the classes will communicate through. Plugins are often developed by third-parties that never even talk to developers of the original product.


Testing

Many of dependency injection's benefits are particularly relevant to unit-testing. For example, dependency injection can be used to externalize a system's configuration details into configuration files, allowing the system to be reconfigured without recompilation. Separate configurations can be written for different situations that require different implementations of components. Similarly, because dependency injection does not require any change in code behavior, it can be applied to legacy code as a
refactoring In computer programming and software design, code refactoring is the process of restructuring existing source code—changing the '' factoring''—without changing its external behavior. Refactoring is intended to improve the design, structure, ...
. This makes clients more independent and are easier to
unit test Unit testing, component or module testing, is a form of software testing by which isolated source code is tested to validate expected behavior. Unit testing describes tests that are run at the unit-level to contrast testing at the integration ...
in isolation, using stubs or
mock object In computer science, a mock object is an object that imitates a production object in limited ways. A programmer might use a mock object as a test double for software testing. A mock object can also be used in generic programming. Analogy A mo ...
s, that simulate other objects not under test. This ease of testing is often the first benefit noticed when using dependency injection.


Disadvantages

Critics of dependency injection argue that it: * Creates clients that demand configuration details, which can be onerous when obvious defaults are available. * Makes code difficult to trace because it separates behavior from construction. * Is typically implemented with reflection or dynamic programming, hindering IDE automation. * Typically requires more upfront development effort. * Encourages dependence on a framework.


Types of dependency injection

There are several ways in which a client can receive injected services: * Constructor injection, where dependencies are provided through a client's class constructor. * Method Injection, where dependencies are provided to a method only when required for specific functionality. * Setter injection, where the client exposes a setter method which accepts the dependency. * Interface injection, where the dependency's interface provides an injector method that will inject the dependency into any client passed to it. In some frameworks, clients do not need to actively accept dependency injection at all. In
Java Java is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea (a part of Pacific Ocean) to the north. With a population of 156.9 million people (including Madura) in mid 2024, proje ...
, for example, reflection can make private attributes public when testing and inject services directly.


Without dependency injection

In the following
Java Java is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea (a part of Pacific Ocean) to the north. With a population of 156.9 million people (including Madura) in mid 2024, proje ...
example, the Client class contains a Service
member variable In object-oriented programming Object-oriented programming (OOP) is a programming paradigm based on the concept of '' objects''. Objects can contain data (called fields, attributes or properties) and have actions they can perform (called ...
initialized in the constructor. The client directly constructs and controls which service it uses, creating a hard-coded dependency. public class Client


Constructor injection

The most common form of dependency injection is for a class to request its dependencies through its constructor. This ensures the client is always in a valid state, since it cannot be instantiated without its necessary dependencies. public class Client


Method Injection

Dependencies are passed as arguments to a specific method, allowing them to be used only during that method's execution without maintaining a long-term reference. This approach is particularly useful for temporary dependencies or when different implementations are needed for various method calls. public class Client


Setter injection

By accepting dependencies through a setter method, rather than a constructor, clients can allow injectors to manipulate their dependencies at any time. This offers flexibility, but makes it difficult to ensure that all dependencies are injected and valid before the client is used. public class Client


Interface injection

With interface injection, dependencies are completely ignorant of their clients, yet still send and receive references to new clients. In this way, the dependencies become injectors. The key is that the injecting method is provided through an interface. An assembler is still needed to introduce the client and its dependencies. The assembler takes a reference to the client, casts it to the setter interface that sets that dependency, and passes it to that dependency object which in turn passes a reference to itself back to the client. For interface injection to have value, the dependency must do something in addition to simply passing back a reference to itself. This could be acting as a factory or sub-assembler to resolve other dependencies, thus abstracting some details from the main assembler. It could be reference-counting so that the dependency knows how many clients are using it. If the dependency maintains a collection of clients, it could later inject them all with a different instance of itself. public interface ServiceSetter public class Client implements ServiceSetter public class ServiceInjector public class ExampleService implements Service public class AnotherExampleService implements Service


Assembly

The simplest way of implementing dependency injection is to manually arrange services and clients, typically done at the program's root, where execution begins. public class Program Manual construction may be more complex and involve builders,
factories A factory, manufacturing plant or production plant is an industrial facility, often a complex consisting of several buildings filled with machinery, where workers manufacture items or operate machines which process each item into another. Th ...
, or other construction patterns.


Frameworks

Manual dependency injection is often tedious and error-prone for larger projects, promoting the use of frameworks which automate the process. Manual dependency injection becomes a dependency injection framework once the constructing code is no longer custom to the application and is instead universal. While useful, these tools are not required in order to perform dependency injection. Some frameworks, like Spring, can use external configuration files to plan program composition: import org.springframework.beans.factory.BeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Injector Even with a potentially long and complex object graph, the only class mentioned in code is the entry point, in this case Client.Client has not undergone any changes to work with Spring and remains a POJO. By keeping Spring-specific annotations and calls from spreading out among many classes, the system stays only loosely dependent on Spring.


Examples


AngularJS

The following example shows an
AngularJS AngularJS (also known as Angular 1) is a discontinued free and open-source JavaScript-based web framework for developing single-page applications. It was maintained mainly by Google and a community of individuals and corporations. It aimed to si ...
component receiving a greeting service through dependency injection. function SomeClass(greeter) SomeClass.prototype.doSomething = function(name) Each AngularJS application contains a service locator responsible for the construction and look-up of dependencies. // Provide the wiring information in a module var myModule = angular.module('myModule', []); // Teach the injector how to build a greeter service. // greeter is dependent on the $window service. myModule.factory('greeter', function($window) ); We can then create a new injector that provides components defined in the myModule module, including the greeter service. var injector = angular.injector( myModule', 'ng'; var greeter = injector.get('greeter'); To avoid the service locator antipattern, AngularJS allows declarative notation in HTML templates which delegates creating components to the injector.
function MyController($scope, greeter) The ng-controller directive triggers the injector to create an instance of the controller and its dependencies.


C#

This sample provides an example of constructor injection in C#. using System; namespace DependencyInjection; // Our client will only know about this interface, not which specific gamepad it is using. interface IGamepadFunctionality // The following services provide concrete implementations of the above interface. class XboxGamepad : IGamepadFunctionality class PlaystationJoystick : IGamepadFunctionality class SteamController : IGamepadFunctionality // This class is the client which receives a service. class Gamepad class Program


Go

Go does not support classes and usually dependency injection is either abstracted by a dedicated library that utilizes reflection or generics (the latter being supported since Go 1.18). A simpler example without using dependency injection libraries is illustrated by the following example of an MVC web application. First, pass the necessary dependencies to a router and then from the router to the controllers: package router import ( "database/sql" "net/http" "example/controllers/users" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "github.com/redis/go-redis/v9" "github.com/rs/zerolog" ) type RoutingHandler struct // connection, logger and cache initialized usually in the main function func NewRouter( log *zerolog.Logger, db *sql.DB, cache *redis.Client, ) (r *RoutingHandler) func (r *RoutingHandler) SetupUsersRoutes() Then, you can access the private fields of the
struct In computer science, a record (also called a structure, struct, or compound data type) is a composite data structure a collection of fields, possibly of different data types, typically fixed in number and sequence. For example, a date could b ...
in any method that is its pointer receiver, without violating encapsulation. package users import ( "database/sql" "net/http" "example/models" "github.com/go-chi/chi/v5" "github.com/redis/go-redis/v9" "github.com/rs/zerolog" ) type Controller struct func NewController(log *zerolog.Logger, db *sql.DB, cache *redis.Client) *Controller func (uc *Controller) Get(w http.ResponseWriter, r *http.Request) Finally you can use the database connection initialized in your main function at the data access layer: package models import ( "database/sql" "time" ) type ( UserStorage struct User struct ) func NewUserStorage(conn *sql.DB) *UserStorage func (us *UserStorage) Get(name string) (user *User, err error)


See also

*
Architecture description language Architecture description languages (ADLs) are used in several disciplines: system engineering, software engineering, and enterprise modelling and engineering. The system engineering community uses an architecture description language as a langua ...
* Factory pattern * Inversion of control * Mock trainwreck *
Plug-in (computing) In computing, a plug-in (also spelled plugin) or add-in (also addin, add-on, or addon) is a software component that extends the functionality of an existing software system without requiring the system to be software build, re-built. A plug-in ...
*
Strategy pattern In computer programming, the strategy pattern (also known as the policy pattern) is a behavioral software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives runtime ins ...
*
Service locator pattern The service locator pattern is a design pattern used in software development to encapsulate the processes involved in obtaining a service with a strong abstraction layer. This pattern uses a central registry known as the "service locator", which ...
*
Parameter (computer programming) In computer programming, a parameter, a.k.a. formal argument, is a variable that represents an argument, a.k.a. actual argument, a.k.a. actual parameter, to a subroutine call.. A function's signature defines its parameters. A call invocation inv ...
* Quaject


References


External links


Composition Root by Mark Seemann

A beginners guide to Dependency Injection

Dependency Injection & Testable Objects: Designing loosely coupled and testable objects
- Jeremy Weiskotten;
Dr. Dobb's Journal ''Dr. Dobb's Journal'' (often shortened to ''Dr. Dobb's'' or DDJ) was a monthly magazine published in the United States by UBM Technology Group, part of UBM. It covered topics aimed at computer programmers. When launched in 1976, DDJ was the fi ...
, May 2006.
Design Patterns: Dependency Injection -- MSDN Magazine, September 2005


* ttp://martinfowler.com/eaaCatalog/plugin.html P of EAA: Plugin* - Andrew McVeigh - A detailed history of dependency injection.
What is Dependency Injection?
- An alternative explanation - Jakob Jenkov
Writing More Testable Code with Dependency Injection -- Developer.com, October 2006

Managed Extensibility Framework Overview -- MSDN

Old fashioned description of the Dependency Mechanism by Hunt 1998

Refactor Your Way to a Dependency Injection Container



You Don't Need a Dependency Injection Container
{{DEFAULTSORT:Dependency Injection Component-based software engineering Software architecture Software design patterns Articles with example Java code