I've recently learned the merits of dependency injection but am wondering if I should be using it in my project since I don't even require a full blown mvc. Now that I'm using it I'm realizing the extra overhead in each page that I write. For example...
require_once '../../include/session.class.php';
require_once '../../include/db.class.php';
require_once '../../include/account.class.php';
$objSession = new Session();
$objDb = new Db();
$objAccount = new Account( $objSession, $objDb );
account.class.php
class Account {
...
public function __construct( Session $objSession, Db $objDb ) {
$this->session = $objSession;
$this->db = $objDb;
}
}
...the Account class will always need Db and Session and I'll only ever have one class of each. So my question is, should I be using DI in a situation like this or should I just use...
account.class.php
require_once '../../include/session.class.php';
require_once '../../include/db.class.php';
class Account {
...
public function __construct() {
$this->session = new Session();
$this->db = new Db();
}
}
...?
The dependency injection technique enables you to improve this even further. It provides a way to separate the creation of an object from its usage. By doing that, you can replace a dependency without changing any code and it also reduces the boilerplate code in your business logic.
If you have a really small project with 12 classes, then a DI framework is almost certainly overkill. As a rule of thumb, the point where it becomes truly useful is when you find yourself repeatedly writing code that wires up object graphs with multiple dependencies and have to think about where to put that code.
This provides a developer with the freedom to create a computer object with different components without having to extend classes and override constructors. Sometimes this is also referred to as inversion of control.
Dependency injection is a procedure where one object supplies the dependencies of another object. Dependency Injection is a software design approach that allows avoiding hard-coding dependencies and makes it possible to change the dependencies both at runtime and compile time.
Dependency Injection has nothing to do with MVC. It is really good at making unit tests easier to write and ultimately I have found that it makes me really think about the resources that I'm using and whether or not that implementation should be using that resource.
I personally don't see the harm in creating the injected object, so you've got a couple lines where you have to create an object? It tells the user a lot more about what's going on. I'd rather have clarity as compared to magic.
Personally, I think most of the clutter in the code is coming from the require
statements. I'd say an autoloader would solve some of that problem.
I really enjoyed this Google Clean Code Talk on DI. It helped me grasp the concept and its benefits a little better.
You've read about the merits of dependency injection. Why did you start using it?
Was it because of the ability to swap out those particular dependencies for testing or different environments? Was it to isolate and make explicit the order of a circular chain of dependencies?
Suppose, for example, that it was the desire to inject different classes for testing purposes (the merit of DI that made me use it). How do you handle that without DI?
Look at your Account class. You can either modify the constructor with an if check on some predicate testMode(), or you can modify the Db and Session constructors, or you could possibly change a configuration file. Whatever non DI solution you opt for, are you ok with that? What about other dependencies (emailer, logger, etc)? Do you have any interfaces to external systems that you should mock for testing?
Anyway, the answer could be that you are satisfied without the DI solution and that your app is small enough to manage without it. But it's important to ask yourself the question anyway.
Similarly, apply that same line of questioning to the other merits of DI that motivated you to start using it.
Incidentally, do you have one instance of Db in Account and another in each of your other classes? Could you have just one instance? DI helps with that. You can have singleton classes without actually coding them as singletons by always injecting the same instance.
Out of curiosity, why are you doing your own dependency injection instead of using a DI library? Half of the benefit of using DI is that it is cleanly abstracted away by other people's implementations. Only write the code you need to and let the libraries take care of doing the injection for you. This is similar to drrcknlsn's suggestion, but without writing the actual implementation of the DependencyInjectionContainer class:
$account = DependencyInjectionContainer::build('Account');
and screw the rest.
A good DI library should see the constructor for Account, realize it needs a Db and a Session, and march up the chain of constructors (in this case, it ends there since both have empty constructors). That translates to having the same amount of code as the non DI case (plus the arguments to the constructor, minus the calls to the constructors inside, but no extra crap at top), with whatever benefits brought you to DI in the first place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With