Lecture
Dependency injection (DI) is the process of providing external dependency to a software component. It is a specific form of “inversion of control” (English Inversion of control , IoC), when it is applied to dependency management. In full accordance with the principle of a single duty, the object gives care to build the dependencies required by it to an external, specially designed general mechanism [1] .
JNDI service requests, when an object requests a service by name, only partially implement dependency injection.
In the current implementation of dependencies, the object is passive and does not take any steps at all to clarify dependencies, but provides for this the setters and / or accepts with its designer the arguments by which the dependencies are implemented [1] .
The operation of the framework that provides dependency injection is described as follows. The application, regardless of the design, is executed inside the IoC container provided by the framework. Some objects in the program are still created in the usual way of a programming language, and some are created by the container based on the configuration provided to it.
Conventionally, if an object needs to access a certain service, the object assumes responsibility for access to this service: it either receives a direct link to the location of the service, or refers to the well-known “service locator” and requests a link to the implementation of a certain type of service. Using the same dependency injection, the object simply provides a property that is able to store a reference to the desired type of service; and when an object is created, a reference to the implementation of the desired type of service is automatically inserted into this property (field) using the medium.
Dependency injection is more flexible, because it becomes easier to create alternative implementations of this type of service, and then specify which implementation should be used in, for example, the configuration file, without changes in the objects that use this service. This is especially useful in vunit testing, because it is very easy to insert the implementation of the service stub into the object under test.
On the other hand, excessive use of dependency injection can make applications more complex and difficult to maintain: since to understand the program's behavior, the programmer needs to look not only at the source code, but also at the configuration, and the configuration is usually invisible to the IDE, which support link analysis and refactoring if support for frameworks with dependency injection is not explicitly indicated.
When using dependency injection, as a rule, there is a configuration mechanism or architecture that determines the expediency of choosing one or another implementation depending on the goals set.
public interface icar {
public float getSpeed ();
public void setPedalPressure (final float PEDAL_PRESSURE);
}
public interface IEngine {
public float getEngineRotation ();
public void setFuelConsumptionRate (final float FUEL_FLOW);
}
public class DefaultEngineImpl implements IEngine
{
private float engineRotation = 0;
public float getEngineRotation ()
{
return engineRotation;
}
public void setFuelConsumptionRate (final float FUEL_FLOW)
{
engineRotation = ...;
}
}
public class DefaultCarImpl implements ICar
{
private IEngine engine = new DefaultEngineImpl ();
public float getSpeed ()
{
return engine.getEngineRotation () * ...;
}
public void setPedalPressure (final float PEDAL_PRESSURE)
{
engine.setFuelConsumptionRate (...);
}
}
public class MyApplication
{
public static void main (String [] args)
{
Icar car = new DefaultCarImpl ();
car.setPedalPressure (5);
float speed = car.getSpeed ();
System.out.println ("Speed of the car is" + speed);
}
}
public class DefaultCarImpl implements ICar {
private IEngine engine;
public DefaultCarImpl (final IEngine engineImpl) {
engine = engineImpl;
}
public float getSpeed () {
return engine.getEngineRotation () * ...;
}
public void setPedalPressure (final float PEDAL_PRESSURE) {
engine.setFuelConsumptionRate (...);
}
}
public class CarFactory {
public static icar buildCar () {
return new DefaultCarImpl (new DefaultEngineImpl ());
}
}
public class MyApplication {
public static void main (String [] args) {
Icar car = CarFactory.buildCar ();
car.setPedalPressure (5);
float speed = car.getSpeed ();
System.out.println ("Speed of the car is" + speed);
}
}
<service-point id = "CarBuilderService">
<invoke-factory>
<construct class = "Car">
<service> DefaultCarImpl </ service>
<service> DefaultEngineImpl </ service>
</ construct>
</ invoke-factory>
</ service-point>
/ ** Implicit implementation ** /
public class MyApplication {
public static void main (String [] args) {
Service service = (Service) DependencyManager.get ("CarBuilderService");
Icar car = (icar) service.getService (Car.class);
car.setPedalPressure (5);
float speed = car.getSpeed ();
System.out.println ("Speed of the car is" + speed);
}
}
PHP Laravel example
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Routing\Controller; class UserController extends Controller { /** * Store a new user. * * @param Request $request * @return Response */ public function store(Request $request) { $name = $request->input('name'); // } }
Comments
To leave a comment
Software and information systems development
Terms: Software and information systems development