Assume the following Service classes:
class A {}
class B {}
class C {}
Now Class A gets a dependency on Class B. So i just inject Class B.
Later in the development my Class A needs Class C too.
(This could go on and on...)
Is it better to inject the Dependency Container to be able to use all services as needed. Or keep the service classes small by only injecting those classes i need?
Whats the best practice here, and why?
Currently i tend to inject each dependent service i need, mainly to see the dependency in one place (the DI annotation in the header).
Please don't close as "opinion based" this questions is for best
Practice, this have to be a opinion, but when a majority of users have
the same opinion then its a best practice.
I advise against injecting whole service container. If you do so, class dependencies get blurry (eg. you have to go through whole class code to see what dependencies this class needs) and it may lead to a mess.
Inject these dependencies you need directly. If you noticed that there are a lot dependencies in your class, it should be an alert for you that this class is doing too much (or have too many responsibilities) and you should split it (or separate responsibilities).
Don't inject the container. This is the service locator pattern, and it is usually looked at as an anti-pattern.
Reasons:
injecting the container couples your code to the container, which is bad because if you want to change the container you use, you have lots of classes that needs to be changed
it also hides the dependencies your class needs: dependencies are no longer explicit. Say I want to use your class, how do I know which dependencies I need to set in the container for your class to work?
what happens if you inject the container, and then your class gets a dependency but the dependency doesn't exist: exception
This is not just an opinion, there are good reasons justifying dependency injection over service location.
Injecting concrete classes is contradictory to Dependency Inversion Principle (DIP). In you case, class A (relatively higher class) should not depend on class B (relatively lower class); both should depend on an abstraction instead. So, the abstract class or an interface which is inherited or implemented by class B, should be injected into class A. The same is true for class A and class C.
IMHO, injecting the whole Dependency Container introduces an extra overhead to the injected class. So the class should be injected with those abstractions only as needed. In order to achieve that, it is also needed to design the class accordingly from the very beginning.
Related
In my Domain layer I have contract Hashing. One of my domain services depends on this contract. At the moment I have injected it within a __construct method.
In infrastructure layer I have implementation of this contract. I have written something looks like IoC container, which creates services with auto wiring injecting.
It all works. But I know that service's dependencies will grow up. I will add much more UseCases to them. And there is another one problem -- container injects all dependencies, but we could use only one UseCase, so it will do excess job.
Is it ok, if I will inject IoC container itself instead of many parameters, and use it in UseCases.
IoC contract also lies in Domain Layer contracts namespace
Is it ok, if I will inject IoC container itself instead of many parameters
No, it is not okay. Supplying any class outside your Composition Root with access to an unbounded set of dependencies is considered an anti-pattern. This anti-pattern is called Service Locator.
Injecting the container causes the class to take a dependency on a redundant component (the container) and makes it non-obvious what the class's dependencies are. This complicates testing and makes the class dishonest about its level of complexity.
You might be tempted to inject the container to prevent the class's constructor from keep changing, but this is a sign of another problem. Classes that keep getting new dependencies likely violate the Single Responsibility Principle. You will end up with classes with many constructor arguments—a code smell called Constructor over-injection.
Two design patterns namely Dependency Injection and Dependency Inversion exist out there, Articles are there in the net trying to explain the difference. But the need to explain it in easier words is still there. Any one out there to come up to ?
I need to understand it in PHP.
(Note: This answer is language-agnostic, although the question specifically mentions PHP, but being unfamiliar with PHP, I have not provided any PHP examples).
Terminology - Dependencies and Coupling
In the context of Object-Oriented Programming, a dependency is any other object type which a class has a direct relationship with. When a class depends directly upon another object type, it can be described as being coupled to that type.
In general, any type used by a class is a dependency to some extent. There are many different ways for a class to depend upon another type, including:
Object types used by Instance variables
Object types used by Constructor parameters
Object types used by Accessor/Mutator methods
Constructors (And sometimes methods) which create new objects directly
Inheritance
The stronger the relationship between a class and its dependency, the tighter the coupling; therefore when a class depends directly upon another concrete class (such as the case with inheritance creating a direct dependency on a base class, or the case where a constructor creates new objects for its instance variables), any future changes to that direct dependency are more likely to "ripple" across in a Butterfly-effect style.
Difference Between Injection vs Inversion
Dependency Injection is an Inversion of Control technique for supplying objects ('dependencies') to a class by way of the Dependency Injection Design Pattern. Typically passing dependencies via one of the following:
A constructor
A public property or field
A public setter
The Dependency Inversion Principle (DIP) is a software design guideline which boils down to two recommendations about de-coupling a class from its concrete dependencies:
'High-level modules should not depend on low-level modules. Both should depend on abstractions.'
'Abstractions should not depend upon details. Details should depend upon abstractions.'
Or, to put it even more succinctly:
Dependency Injection is an implementation technique for populating instance variables of a class.
Dependency Inversion is a general design guideline which recommends that classes should only have direct relationships with high-level abstractions.
Dependency Injection and Inversion of Control (IoC)
Dependency Injection applies the IoC principle by ensuring classes are never responsible for creating or supplying their own dependencies (and therefore aren't responsible for the lifetime of those dependencies either).
However, IoC is not Dependency Injection - indeed, IoC as a principle has nothing particularly to do with dependencies or dependency injection per-se; Dependency Injection is a design pattern based around the principle of IoC.
IoC is seen in many other contexts, including those totally unrelated to object creation or dependencies, such as message passing via a Mediator or Message pump to trigger event handlers. Other (unrelated) examples of IoC include:
A windowed application using event handler functions/methods to handle mouse/keyboard input events.
An MVC web application using Controller Actions to handle HTTP requests.
(Updated from the original answer as a separate explanation about IoC)
Dependency Injection Pattern
Dependency Injection is a design pattern which applies the IoC principle to ensure that a class has absolutely no involvement or awareness in the creation or lifetime of objects used by its constructor or instance variables -- the "common" concern about object creation and populating instance variables is deferred to a framework instead.
That is to say, a class may specify its instance variables, but does not do any work to populate those instance variables (with the exception of using constructor parameters as a "pass-through")
A class which is designed with Dependency Injection in mind may look like this:
// Dependency Injection Example...
class Foo {
// Constructor uses DI to obtain the Meow and Woof dependencies
constructor(fred: Meow, barney: Woof) {
this.fred = fred;
this.barney = barney;
}
}
In this example, Meow and Woof are both dependencies injected via the Foo constructor.
On the other hand, a Foo class which is designed without Dependency Injection might simply create the Meow and Woof instances itself, or perhaps use some kind of service locator/factory:
// Example without Dependency Injection...
class Foo {
constructor() {
// a 'Meow' instance is created within the Foo constructor
this.fred = new Meow();
// a service locator gets a 'WoofFactory' which in-turn
// is responsible for creating a 'Woof' instance.
// This demonstrates IoC but not Dependency Injection.
var factory = TheServiceLocator.GetWoofFactory();
this.barney = factory.CreateWoof();
}
}
So dependency injection simply means that a class has deferred responsibility of obtaining or providing its own dependencies; instead that responsibility resides with whatever wants to create an instance. (Which is usually an IoC Container)
Dependency Inversion Principle (DIP)
Dependency Inversion is broadly about de-coupling concrete classes by preventing those classes having any direct reference to each other.
The DIP is primarily concerned with ensuring that a class only depends upon higher-level abstractions. For example, interfaces exist at a higher level of abstraction than a concrete class.
The DIP is not about injecting dependencies, although the dependency injection pattern is one of many techniques which can help provide the level of indirection needed to avoid depending on low-level details and coupling with other concrete classes.
Note: Dependency Inversion is often more explicit in statically typed programming languages such as C# or Java, because those languages enforce strict type-checking on variable names. On the other hand, Dependency Inversion is already passively available in dynamic languages such as Python or JavaScript because variables in those languages do not have any particular type restrictions.
Consider a scenario in a statically typed language where a class requires the ability to read a record from the application's database:
// class Foo depends upon a concrete class called SqlRecordReader.
class Foo {
reader: SqlRecordReader;
constructor(sqlReader: SqlRecordReader) {
this.reader = sqlReader;
}
doSomething() {
var records = this.reader.readAll();
// etc.
}
}
In the above example, and despite the use of Dependency Injection, class Foo still has a hard dependency on SqlRecordReader, yet the only thing it really cares about is that there exists a method called readAll() which returns some records.
Consider the situation where SQL database queries are later refactored out into separate micro-services requiring a change to the codebase; the Foo class would need to read records from a remote service instead. Or alternatively, a situation where Foo unit tests need to read data from an in-memory store or a flat file.
If, as its name suggests, the SqlRecordReader contains database and SQL logic, any move to microservices would need the Foo class to change.
Dependency Inversion guidelines suggest that SqlRecordReader should be replaced with a higher-level abstraction which only provides the readAll() method. i.e:
interface IRecordReader {
Records[] getAll();
}
class Foo {
reader: IRecordReader;
constructor(reader: IRecordReader) {
this.reader = reader;
}
}
As per DIP, the IRecordReader is a higher-level abstraction than SqlRecordReader, and forcing Footo depend onIRecordReaderinstead ofSqlRecordReader` satisfies DIP guidelines.
Why DIP Guidelines are Useful
The keyword is guideline - dependency inversion adds indirection to the design of your program. The obvious disadvantage of adding any kind of indirection is that the complexity (i.e. the cognitive "load" required for a human to understand what's going on) increases.
In many cases, indirection can make code easier to maintain (fix bugs, add enhancements) however:
In this last example, Foo might receive a SqlRecordReader, or maybe a SoapRecordReader, or perhaps a FileRecordReader, or maybe even for unit testing a MockRecordReader - the point is that it doesn't know or care anything about different possible implementations of IRecordReader - provided of course those implementations live up to the Liskov Substitution Principle.
Furthermore, it avoids the potentially dirty scenario where a developer who is in a rush to get something working might consider trying to "fudge" the Liskov principle by inheriting the SoapRecordReader or FileRecordReader from a base class SqlRecordReader.
Worse still, an inexperienced developer might even change the SqlRecordReader itself so that class has logic not only for SQL but also for SOAP endpoints, The Filesystem, and anything else which might be needed. (This kind of thing happens too often in the real world - especially in poorly maintained code, and is nearly always a Code Smell.)
See this article here
The author differentiates these two in simple words. Dependency Injection == “Gimme it” and Dependency Inversion == “Someone take care of this for me, somehow.”. In dependency inversion principle, high level module is the owner of the abstraction. Thus the detail(implementation of the abstraction) is depends on the abstraction and hence depends on the high level module. Dependency inverted!.. Dependency injection is different. The abstraction might not be kept by the high level module. Thus an abstraction given to the higher level object might not be limited to the needs of the high level module.
Dependency inversion :
You have a higher level module X and an abstraction Y which is defined by X. Z implements Y and is given to X. Thus Z is dependent of X(via the abstraction Y defined by X).
Dependency injection:
You have an higher level module X which needs functionalities A and B. Y is an abstraction which contains the functionalities A, B and C. Z implements Y. Since Z implements Y and hence have functionalities A and B, Z is given to X. Now X is dependent of Y.
Dependancy injection is ability of object to supply depndcies of other object. in simple words it means something else is dependent on something else. Example Class A uses few functions of Class B now Class A needs to create the instance of Class B here the use of DI comes in to use.
IOC is to invert the different resposibilities for example you need to work at home but you need to cook to eat now listed cooking at home you can order it online and it is available to your door step which means you can focus on your work. Here you inverted cooking responsibilities to online restorent.
The Dependency Inversion Principle (DIP) states that high level modules should not depend on low level modules; both should depend on abstractions. Abstractions should not depend on details. Details should depend upon abstractions.
Dependency Injection is one way to achieve Inversion of Control (which I am assuming you are referring to as Dependency Inversion), so the two aren’t really in competition as much as DI is a specialization of IoC. Other commonly seen ways to achieve IoC include using factories or the Service Locator pattern.
I'm writing a little application from scratch, and I wanted to use some packages from packagist. For DI I choosed Auryn.
Now, one of the first thing that I learnt about Auryn is that it tries to avoid to be a Dependency Container and it is explicitily wrote in the docs that you should not use the instance of Auryn as a container, passing it through the various classes of your app.
I'm fine with that, but, because I have a "main" class as a wrapper for all of the backbone of the app, I think that I should have in the constructor of this main class only the dependency of an Injector object (That's the main Auryin object), then in the constructor of the class I should wire everything to be ready for DI and reflection.
The other way around is to not use a main class, and just use clean procedural code in my index file, wiring all togheter at the same way with Auryn.
What do you advice is the best way to proceed?
The idea behind dependency injection is to gather all the information how your various classes are "wired up" in one place (your DI container class / DI config file), instead of spreading and duplicating it all over your code. I presume your "Main"-class is only instanciated once in your Index.php, so it makes no noticeable difference whether you pass the Auryn instance to Main's constructor or use Auryn to get an instance of Main.
My understanding:
A dependency is when an instance of ClassA requires an instance of ClassB to instantiate a new instance of ClassA.
A dependency injection is when ClassA is passed an instance of ClassB, either through a parameter in ClassA's constructor or through a set~DependencyNameHere~(~DependencyNameHere~ $param) function. (This is one of the areas I'm not completely certain on).
An IoC container is a singleton Class(can only have 1 instance instantiated at any given time) where the specific way of instantiating objects of those class for this project can be registered. Here's a link to an example of what I'm trying to describe along with the class definition for the IoC container I've been using
So at this point is where I start trying use the IoC container for more complicated scenarios. As of now it seems in order to use the IoC container, I am limited to a has-a relationship for pretty much any class I want to create that has dependencies it wants to define in the IoC container. What if I want to create a class that inherits a class, but only if the parent class has been created in a specific way it was registered in the IoC container.
So for example: I want to create a child class of mysqli, but I want to register this class in the IoC container to only instantiate with the parent class constructed in a way I've previously registered in the IoC container. I cannot think of a way to do this without duplicating code (and since this is a learning project I'm trying to keep it as 'pure' as possible). Here are some more examples of what I am trying to describe.
So here are some of my questions:
Is what I'm trying to do above possible without breaking some principle of OOP? I know in c++ I could use dynamic memory and a copy constructor to accomplish it, but I haven't been able to find that sort of functionality in php. (I will admit that I have very little experience using any of the other magic methods besides __construct, but from reading and __clone if I understood correctly, I couldn't use in the constructor it to make the child class being instantiated a clone of an instance of the parent class).
Where should all my dependency class definitions go in relation to the IoC? (Should my IoC.php just have a bunch of require_once('dependencyClassDefinition.php') at the top? My gut reaction is that there is a better way, but I haven't come up with one yet)
What file should I be registering my objects in? Currently doing all the calls to IoC::register() in the IoC.php file after the class definition.
Do I need to register a dependency in the IoC before I register a class that needs that dependency? Since I'm not invoking the anonymous function until I actually instantiate an object registered in the IoC, I'm guessing not, but its still a concern.
Is there anything else I'm overlooking that I should be doing or using? I'm trying to take it one step at a time, but I also don't want to know that my code will be reusable and, most importantly, that somebody who knows nothing about my project can read it and understand it.
Put simply (because it's not a problem limited to OOP world only), a dependency is a situation where component A needs (depends on) component B to do the stuff it's supposed to do. The word is also used to describe the depended-on component in this scenario. To put this in OOP/PHP terms, consider the following example with the obligatory car analogy:
class Car {
public function start() {
$engine = new Engine();
$engine->vroom();
}
}
Car depends on Engine. Engine is Car's dependency. This piece of code is pretty bad though, because:
the dependency is implicit; you don't know it's there until you inspect the Car's code
the classes are tightly coupled; you can't substitute the Engine with MockEngine for testing purposes or TurboEngine that extends the original one without modifying the Car.
It looks kind of silly for a car to be able to build an engine for itself, doesn't it?
Dependency injection is a way of solving all these problems by making the fact that Car needs Engine explicit and explicitly providing it with one:
class Car {
protected $engine;
public function __construct(Engine $engine) {
$this->engine = $engine;
}
public function start() {
$this->engine->vroom();
}
}
$engine = new SuperDuperTurboEnginePlus(); // a subclass of Engine
$car = new Car($engine);
The above is an example of constructor injection, in which the dependency (the depended-on object) is provided to the dependent (consumer) through the class constructor. Another way would be exposing a setEngine method in the Car class and using it to inject an instance of Engine. This is known as setter injection and is useful mostly for dependencies that are supposed to be swapped at run-time.
Any non-trivial project consists of a bunch of interdependent components and it gets easy to lose track on what gets injected where pretty quickly. A dependency injection container is an object that knows how to instantiate and configure other objects, knows what their relationship with other objects in the project are and does the dependency injection for you. This lets you centralize the management of all your project's (inter)dependencies and, more importantly, makes it possible to change/mock one or more of them without having to edit a bunch of places in your code.
Let's ditch the car analogy and look at what OP's trying to achieve as an example. Let's say we have a Database object depending on mysqli object. Let's say we want to use a really primitive dependency indection container class DIC that exposes two methods: register($name, $callback) to register a way of creating an object under the given name and resolve($name) to get the object from that name. Our container setup would look something like this:
$dic = new DIC();
$dic->register('mysqli', function() {
return new mysqli('somehost','username','password');
});
$dic->register('database', function() use($dic) {
return new Database($dic->resolve('mysqli'));
});
Notice we're telling our container to grab an instance of mysqli from itself to assemble an instance of Database. Then to get a Database instance with its dependency automatically injected, we would simply:
$database = $dic->resolve('database');
That's the gist of it. A somewhat more sophisticated but still relatively simple and easy to grasp PHP DI/IoC container is Pimple. Check its documentation for more examples.
Regarding OP's code and questions:
Don't use static class or a singleton for your container (or for anything else for that matter); they're both evil. Check out Pimple instead.
Decide whether you want your mysqliWrapper class extend mysql or depend on it.
By calling IoC from within mysqliWrapper you're swapping one dependency for another. Your objects shouldn't be aware of or use the container; otherwise it's not DIC anymore it's Service Locator (anti)pattern.
You don't need to require a class file before registering it in the container since you don't know if you're going to use an object of that class at all. Do all your container setup in one place. If you don't use an autoloader, you can require inside the anonymous function you register with the container.
Additional resources:
Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler
Don't look for things -- a Clean Code Talk about IoC/DI
i have been trying to get my head round factory patterns and dependency injection and i understand the concepts and basics behind both patterns and that there can be a slight cross over. But before i start coding it up, i just want to check my flow method would be correct.
My intended flow would be...
create a config file with all the properties needed for my 'core classes' in the format
$config['core.classname']['property_name']=$value;
create a factory class that will create an instance of all my core classes and run through the config file injecting the properties in to each class
when my app needs an instance of a class, it uses the factory class to clone the required class which has had its dependencies injected.
As i understand it this would decouple my core classes, allowing for them to be swapped in and out of my code easier.
What you are calling a 'factory' is really more of a dependency injection container. A factory traditionally only creates one type of object.
In general you should avoid creating any core instances until your app actually needs one. You may have 100 core classes defined of which any given app request might only need a couple.
In many cases your app will want to share the same instance or a core class so automatic cloning is probably not quite what you want.
Consider reading through the Service (what you call core) chapter in the Symfony2 framework package for ideas:
http://symfony.com/doc/current/book/service_container.html