Better way to create objects with dependencies in PHP - php

I am currently working on a PHP project where I need to create objects of a class RelevantClass. I am using Dependency Injection via DI Container.
Underlying Structure
Let's suppose I have the following class structure:
class SomeServiceClass {
}
class EntityClass {
}
class RelevantClass {
/**
* #Inject
*/
private SomeServiceClass $service
public function __construct(EntityClass $entity){
$this->service = inject(SomeServiceClass::class)
$this->entity = $entity;
}
public function someMethod() : void
{
...
$this->service->doSomething($this->entity);
$this->entity->doSomething();
...
}
}
The issue here is that my EntityClassObject needs to be modified by my RelevantClass, as in I can't pass in an injected instance of EntityClass into the constructor of RelevantClass.
The Service class includes some helper methods and other functionality, so it can be injected directly.
Now my question is, how should I instantiate my RelevantClass class?
Approach 1
The way it works right now is that I simply call the constructor:
$entity = ... # Getting the entity from the database
$relevantObject = RelevantClass($entity); # here my service is instantiated by explicitly calling the di container
$relevantObject->someMethod();
That way, my Service is set by the constructor via injection container and my entity is passed through the constructor argument.
Approach 2
Although it is working, I am wondering if it were better practice if I structured my RelevantClass in a way that allows me to instantiate it via DI Container, too?
$entity = ... # Getting the entity from the database
$relevantObject = inject(RelevantClass::class); # this would inject my service class as well
$relevantObject->setEntity($entity);
$relevantObject->someMethod();
Briefly summed up, someMethod needs SomeServiceClass to perform some operations on an EntityClass instance. SomeServiceClass can be injected, while EntityClass cannot.
What is the way to go here? I am aware that both approaches woudl work, but which one of them would be best practice? The project I am currently working on barely uses the constructor to instantiate classes, so I am wondering, whether there are any inherent advantages to the second approach?

Related

Dependency Injection prevent dependency on the dependency container

After puzzling around with the Dependency injection I'm worried about getting dependent on the DI container. So I thought I tie everything together with factories. But there seem to be an awful a lot of factories needed (One for every object(?)).
Now what happens is the following:
class houseFactory
{
protected $_di;
public function __construct(\DI $di)
{
$this->_setDI($di)
}
protected function _setDI(\DI $di)
{
$this->_di = $di;
}
public function createObject()
{
return $this->_di->create('house');
}
}
The houseFactory basicly wires the creation and calling code together without having to know how to create a house. But is it really oke to actually call for a new factory for every needed object?
It seems so for now because lets say house isn't so easily resolved by DI container alone but needs certain rules. For example there should be only one instance of it (also known as 'shared'). Those rules would go into the factory.
My questions are:
1) Is this acceptable?
I predict a huge collection of factories and my concern is that it's going to be an overkill/huge drawback/against what it is supposed to do.
2) When is it actually 'ok' to use the 'new' keyword?
I understand why moving the logic to create a new object with dependency is good practice. But it seems circular.
3) Where and how does the dependency injection container come into play in applications?
From what point of do you actually use/call the DI container? It seems like hardcoding the DI container into your application? or is that actually the point?
Hopefully my questions aren't to vague.
Thanks in advance.
The main purpose of DI is having the dependency injected, not injected the object that responsible to resolve / create the object. In your example, say that we want to use houseFactory class to get house class and use it (example the goHome method).
$house = $houseFactory->createObject();
$house->goHome();
The implementation not only makes your caller to dependent on the house class, but it is also dependent to houseFactory class, which is a useless dependency.
As TrueWill said, the only place an application responsible to do object creation is composition root. The composition root is a start point of every application. Unfortunately I don't think there is any composition root in pure php class, however there should be in php frameworks such as CI or Zend.
Why should we do object creation in composition root?
to make the scope of object creation become very small. Composition root usually only contains small logic to start the application. Maybe some other logic to handle general exception but not other else. Therefore it is safe to do object creation because no specific business logic exists there.
the composition root does not being created in other class. It is being called as application startup, so it is safe to create objects in a class there.
To understand more about composition root you can read at Mark Seeman's book or his blog.
Then how do we access the object created in composition root?
Some application has good support to DI, such as ASP.Net MVC, however some not like ASP.Net Webform. In applications that has good support, then you can inject the class directly from composition root. However if not, maybe you can access the composition root DI Container via static class, but only at page's constructor. So it minimize the access to composition root.
EDIT1:
Here is usage example of house class without DI Container written in php (maybe not working, haven't used DI in php).
class houseConsumer{
protected $_house;
public function __construct(\DI $house)
{
$this->_house($house)
}
public function doSomething(){
// do something
$this->_house->goHome();
}
}
class compositionRoot{
public function main(){
$diContainer = // define the DI Container
$houseConsumer = new houseConsumer($diContainer->create('house'));
$houseConsumer->doSomething();
}
}
This is the example in C# console:
public class HouseConsumer{
//constructor
public HouseConsumer(IHouse house){
this.house = house;
}
IHouse house;
public void DoSomething(){
house.GoHome();
}
}
//this is the composition root
public class Program{
public static void Main(string[] args){
List<object> diContainer = new List<object>();
//populate diComponent
HouseConsumer consumer = new HouseConsumer((IHouse)diContainer[0]);
consumer.DoSomething();
}
}
EDIT 2:
Is the DI container actually used outside the 'main' method? How do I create new objects outside the 'main' method? Lets say I am a few Objects deep. How do I create a house there?
What I have exampled above can be used in Asp.Net MVC, where the page is also automatically resolved using an IOC Container. Unfortunately, if you need the DI Container in pages like Asp.Net webforms, you should use static, but assign the objects in constructor only. Example (in C#, I don't know how to use static at php).
public class Page1 : Page{
public Page1(){
this.house = CompositionRoot.DiContainer.Create("house");
}
private IHouse house;
}
This implementation still safe, because the DIContainer only used at constructor level of a page. But make sure do not do this in Service class. Example:
public class Renter : IRenter{
public Renter(){
this.house = CompositionRoot.DiContainer.Create("house");
}
private IHouse house;
}
Is a bad design. The Renter class is dependent on DIContainer. To solve that, inject the IHouse class.
public class Renter : IRenter{
public Renter(IHouse house){
this.house = house;
}
private IHouse house;
}
Then the caller of Renter class should pass the house class. The example is to assign the IRenter class to DIContainer using poor man's.
Dictionary<Type, object> DiContainer = new Dictionary<Type, object>();
IHouse house = new House();
IRenter renter = new Renter(house);
DiContainer.Add(typeof(IHouse), house);
DiContainer.Add(typeof(IRenter), renter);
Then you use it in Page:
public class Page1 : Page{
public Page1(){
this.renter = (IRenter)CompositionRoot.DiContainer[typeof(IRenter)];
}
private IRenter renter;
}

What would be a good DAO pattern to combine with Dependency Injection for a PHP framework?

I am developing a PHP framework, based on dependency injection. My data objects are injectable components, like any others.
I have an abstract DAO class, that each model should extend, that has:
basic crud methods
a reference to DI container, to instantiate objects
Things are, in short, like this
abstract class AbstractDao {
protected $fields;
protected $container; // This is the (injected) DI container, used to create instances.
protected $driver; // The injected database driver (i.e. PDO)
public function insert() {
// Insert implementation
// Insert current instance.
}
public function fetch($id) {
// Fetch implementation
// Fetches a row and sets fields on current instance
}
public function fetchAll() {
// Performs a select * query on database driver
// Iterates through results, and creates an instance
// for each result using $container, like this:
foreach ($results as $row) {
// I can't just make $instances[] = new Something(), or all the
// dependency injection thing would mess up.
$instances[] = $this->container->get('someDao');
}
return $instances;
}
// Other methods.
}
class Book extends AbstractDao {
protected $fields = array('field', 'definition', 'goes', 'here',);
// No special behaviour is needed, so we can keep default
// abstract implementation without overriding.
}
My question: every data object implementation (a book, a person, an user, etc.) must extend my AbstractDao object, therefore it will carry the weight of $driver and $container. Furthermore, since $fields property is defined at instance level, each data object would have its own, adding more overhead.
I fear that when handling big data sets this solution may result in a much expensive one, in terms of performance. I know objects would be just referenced, not cloned, but the overhead could be sadly high.
Couple of solutions i have in mind are
using static method implementations, that may reduce overhead in
subclasses
do not make my Daos extends the above mentioned AbstractDao, that should become a sort of DaoProvider. In this case, for each method, i should pass in the instance (thing that i don't really like)
None of those solutions i like that much... first i don't like using static things, as they conflicts a little with the entire idea of injection. Second, i dont like the idea of removing the dao subclassing pattern.
Any good idea would be really appreciated, thank you.
=== EDIT ===
One more thing that came to my mind. What i don't like in the 2nd approach ("dao provider") is that the provider has to perform operations on Dao fields (set values, set status, set isDirty, etc.), therefore fields have to be made accessible from outside. With the subclassing approach one can keep those protected or private.
=== /EDIT ===
I suggest you create a DAO Interface that declares behavior that a DAO implementation will have to define. Now in each concrete DAO implementation you can define your $driver, $container and $fieldsinstance fields.
After that you might want to create a AbstractModelclass that each concrete model should extend so that both your AbstractModeland concrete models be will 'data access agnostic'. The AbstractModel class will end up looking like this:
/*
* an AbstractModel
*/
abstract class AbstractModel {
protected $daoImpl;
function __construct(DAOInterface $daoImpl) {
$this->daoImpl = $daoImpl;
}
//some other functions that are common to concrete models
}
/*
* a concrete model
*/
class Model extends AbstractModel {
function findAll($params) {
//You can use the $daoImpl of AbstractModel to perform a CRUD operation
$this->daoImpl->findAll($params);
}
}
Now whenever you instantiate a concrete model you will inject a DAO implementation into the model class.
//inject a DAOInterface implementation into Model
$model = new Model(new DAOImpl());
$model->findAll($params);
The advantage here is that you can stub different DAO implementations during testing and perhaps this is where the DI container comes in handy. There's a similar code sample I have created when I was creating my DI container a few days ago.
BTW I don't see the need of putting a $containerobject inside your AbstractDAO why don't you pass in an object that is returned when you invoke a property of the container. That way you can use type hinting to force the object parameters to be of a certain type and encourage a fail-fast mechanism if a wrong object is passed in and you might also find it beneficial to create a Config class to handle your $driver details so that users are free to configure the driver they want to use for the db.

Making the connection between OOP theory and practice with a database driven app example

I'm new to OOP and thought I'd give Silex a try on a small app I'm attempting. I'm looking for some advice as to whether my design falls in line with good object oriented principles.
I have a User object which is basically just a bunch of properties, getters and setters. I then have a UserService object which will contain the logic for authenticating users, getting a user from the database, setting or updating user information, etc. I also have a UserServiceProvder class which is there to provide an instance of the UserService class to the app (which seems to be the best way to create a reusable chunk of code in Silex).
The question I have now is this: I am using the Doctrine DBAL that ships with Silex and when I instantiate the UserService class, I'm tempted to pass in a reference to the Doctrine object and then hard code calls to that object into methods of the UserService class.
For instance, to return a User from the database by id, I might create a method called getUserById($id) and then hardcode a Doctrine prepared statement into that method to select that user from the database and then return a User object.
Would it be better for me to create a whole other service that is just a further abstraction of the Doctrine DBAL and pass that to UserService when I instantiate it? That way, I could hard code the Doctrine prepared statements into that class, leaving my UserService class more encapsulated and reusable in case I decide to move away from Doctrine in the future.
I guess what I'm having a hard time with is realizing if there is a such a thing as overkill in OOP. It seems to me like the second method is much more reusable, but is it necessary or wise?
Moving the Database access to a separate class will bring you a couple of advantages. First of all, if you keep the database access apart from the rest of your logic you can replace the implementation of your database access more easy. If for a reason you want to drop the Doctrine DBAL you'll be happy that all the code is just referencing some interface to a repository instead of directly querying a database.
A second great advantage is that you can test your application logic in separation of your database access logic. If you inject a Repository for users inside your UserService you can Mock this in your tests and be sure they only fail if something is wrong with the actual application logic.
A small example of what you could do
The interface is convenient for reference throughout your codebase. No code references the implementation, only the interface. That way you can easily replace the implementation of the interface without touching all the places it is used:
interface IUserRepository
{
/**
* #return User
*/
public function getUserById($userId);
}
Of course you do need an implementation of said interface. This is what you inject into your UserService. This is what you one day might replace with another implementation of the interface:
class DoctrineDBALUserRepository implements IUserRepository
{
/**
* #return User
*/
public function getUserById($userId)
{
//implementation specific for Doctrine DBAL
}
}
The UserService only knows about the interface and can use it freely. To avoid having to inject the UserRepository in a lot of places in your code you could create a convenience build method. Notice the constructor that references the interface and the build method that injects an implementation of that interface:
class UserService
{
private $UserRepository;
public static build()
{
return new UserService(new DoctrineDBALUserRepository());
}
public function __construct(IUserRepository $UserRepository)
{
$this->UserRepository = $UserRepository;
}
public function getUserById($userId)
{
if ($User = $this->UserRepository->getUserById($userId) {
return $User;
}
throw new RuntimeException('O noes, we messed up');
}
With this in place you can write tests for the business logic (e.g. throw an exception if saving fails):
public function UserServiceTest extends PHPUnit_Framework_TestCase
{
public function testGetUserById_whenRetrievingFails_shouldThrowAnException()
{
$RepositoryStub = $this->getMock('IUserRepository');
$RepositoryStub->expects($this->any())->method('getUserById')->will($this->returnValue(false);
$UserService = new UserService($RepositoryStub);
$this->setExpectedException('RuntimeException');
$UserService->getUserById(1);
}
}
I can imagine you're not familiar with the last bit of code if you're not into unit-testing yet. I hope you are and if not urge you to read up on that as well :D I figured it was good for the completeness of the answer to include it no matter what.

PHP Dependency Injection

I'm trying to get my head around Dependency Injection and I understand it, for the most part.
However, say if, for some reason, one of my classes was dependent on several classes, instead of passing all of these to this one class in the constructor, is there a better, more sensible method?
I've heard about DI Containers, is this how I would go about solving this problem? Where should I start with this solution? Do I pass the dependencies to my DIC, and then pass this to the class that needs these dependencies?
Any help that would point me in the right direction would be fantastic.
Dependency Injection !== DIC
People should really stop confusing them. Dependency Injection is idea that comes from Dependency Inversion principle.
The DIC is "magic cure", which promises to let you use dependency injection, but in PHP is usually implemented by breaking every other principle of object oriented programming. The worst implementations tend to also attach it all to global state, via static Registry or Singleton.
Anyway, if your class depends on too many other classes, then in general , it signifies a design flaw in the class itself. You basically have a class with too many reasons to change, thus, breaking the Single Responsibility principle.
In this case, then dependency injection container will only hide the underlaying design issues.
If you want to learn more about Dependency Injection, i would recommend for you to watch the "Clean Code Talks" on youtube:
The Clean Code Talks - Don't Look For Things!
The Clean Code Talks - "Global State and Singletons"
If you have several dependencies to deal with, then yes a DI container can be the solution.
The DI container can be an object or array constructed of the various dependent object you need, which gets passed to the constructor and unpacked.
Suppose you needed a config object, a database connection, and a client info object passed to each of your classes. You can create an array which holds them:
// Assume each is created or accessed as a singleton, however needed...
// This may be created globally at the top of your script, and passed into each newly
// instantiated class
$di_container = array(
'config' = new Config(),
'db' = new DB($user, $pass, $db, $whatever),
'client' = new ClientInfo($clientid)
);
And your class constructors accept the DI container as a parameter:
class SomeClass {
private $config;
private $db;
private $client;
public function __construct(&$di_container) {
$this->config = $di_container['config'];
$this->db = $di_container['db'];
$this->client = $di_container['client'];
}
}
Instead of an array as I did above (which is simple), you might also create the DI container as an class itself and instantiate it with the component classes injected into it individually. One benefit to using an object instead of an array is that by default it will be passed by reference into the classes using it, while an array is passed by value (though objects inside the array are still references).
Edit
There are some ways in which an object is more flexible than an array, although more complicated to code initially.
The container object may also create/instantiate the contained classes in its constructor as well (rather than creating them outside and passing them in). This can save you some coding on each script that uses it, as you only need to instantiate one object (which itself instantiates several others).
Class DIContainer {
public $config;
public $db;
public $client;
// The DI container can build its own member objects
public function __construct($params....) {
$this->config = new Config();
// These vars might be passed in the constructor, or could be constants, or something else
$this->db = new DB($user, $pass, $db, $whatever);
// Same here - the var may come from the constructor, $_SESSION, or somewhere else
$this->client = new ClientInfo($clientid);
}
}
I've wrote an article about this problem.
The ideea is to use a combination of abstract factory and dependency injection to achieve transparent dependency resolving of (possible nested) dependencies. I will copy/paste here the main code snippets:
namespace Gica\Interfaces\Dependency;
interface AbstractFactory
{
public function createObject($objectClass, $constructorArguments = []);
}
The abstract factory implementation is:
namespace Gica\Dependency;
class AbstractFactory implements \Gica\Interfaces\Dependency\AbstractFactory, \Gica\Interfaces\Dependency\WithDependencyInjector
{
use WithDependencyInjector;
/**
* #param string $objectClass
* #param array $constructorArguments
* #return object instanceof $class
*/
public function createObject($objectClass, $constructorArguments = [])
{
$instance = new $objectClass(...$constructorArguments);
$this->getDependencyInjector()->resolveDependencies($instance);
return $instance;
}
}
The dependency injector is this:
namespace Gica\Dependency;
class DependencyInjector implements \Gica\Interfaces\Dependency\DependencyInjector
{
use \Gica\Traits\WithDependencyContainer;
public function resolveDependencies($instance)
{
$sm = $this->getDependencyInjectionContainer();
if ($instance instanceof \Gica\Interfaces\WithAuthenticator) {
$instance->setAuthenticator($sm->get(\Gica\Interfaces\Authentication\Authenticator::class));
}
if ($instance instanceof \Gica\Interfaces\WithPdo) {
$instance->setPdo($sm->get(\Gica\SqlQuery\Connection::class));
}
if ($instance instanceof \Gica\Interfaces\Dependency\WithAbstractFactory) {
$instance->setAbstractFactory($sm->get(\Gica\Interfaces\Dependency\AbstractFactory::class));
}
//... all the dependency declaring interfaces go below
}
}
The dependency container is the standard one.
The client code could look something like this:
$abstractFactory = $container->get(\Gica\Interfaces\Dependency\AbstractFactory::class);
$someHelper = $abstractFactory->createObject(\Web\Helper\SomeHelper::class);
echo $someHelper->helpAction();
Notice that dependencies are hidden, and we can focus on the main bussiness. My client code doesn't care or know that $someHelper need an Authenticator or that helpAction need an SomeObject to do its work;
In the background a lot of things happen, a lot of dependencies are detected, resolved and injected.
Notice that I don't use the new operator to create $someObject. The responsability of actual creation of the object is passed to the AbstractFactory
P.S. Gica is my nickname :)
I recommend you to use Singltones or Mutlitones. In these cases you will be always able to get objects via static class' methods.
The other way (couldn't find a correct pattern name, but it could be Registry) is to use one global static object to store multiple objects' instances. E.g. (simplified code, without any checks):
class Registry {
private static $instances = array();
public static function add($k, $v) {
$this->instances[$k] = $v;
}
public static function get($k) {
return $this->instances[$k];
}
}
class MyClass {
public function __construct() {
Registry::add('myclass', $this);
}
}

php DI container

i don´t have a lot of php experience i'd need some help,
i have a php MVC framework,
i use this class:
class Registry {
private $objects;
private $settings;
public function __construct() {
}
public function iniObject($class, $key)
{
$this->objects[ $key ] = new $class( $this );
}
public function getObject( $key )
{
return $this->objects[ $key ];
}
public function storeSetting( $setting, $key )
{
$this->settings[ $key ] = $setting;
}
public function getSetting( $key )
{
return $this->settings[ $key ];
}
}
then i pass the registry to the other classes like:
Class Controller
{
/*
* #registry object
*/
protected $registry;
function __construct(Registry $registry)
{
$this->registry = $registry;
//i can use any class from my registry class like the logger class below
$this->registry->getObject('log')->write_log('debug', "Controller Class Initialized");
}
/**
* #all controllers must contain an index method
*/
public function index() {}
}
i start my bootstrap.php with
$registry = new Registry();
// Instantiate some classes
$registry->iniObject( 'Utf8', 'utf8');
$registry->iniObject( 'Uri', 'uri');
$registry->iniObject( 'Router', 'router');
i get any method like:
$registry->getObject('router')->_set_routing();
and i get a view like:
$registry->getObject('output')->_display('myview');
in this way i can use all the classes inside other classes
passing the registry class like DI constructor, works well,
few code and fast execution,
i've been reading about DI containers and other things,
i'd like to know a better ways to do this, if the registry gets
bigger and bigger how will affect the framework i mean i pass
all the registry to every class, there´s a way to pass just
dependencies that every class needs instead the full registry,
is the registry the best way to work with objects cos allow me
to use any class inside any other class or you thing this isn´t a good
way to do it, any recommendation about DI containers libraries,
please i'd like to recieve ideas from more experienced php
programmers to do this
thanks a lot
While I am not an expert, I am currently using the yadif DI framework in my project (https://github.com/beberlei/yadif). I have modified it slightly to suit my purposes.
While the dependency injection and the registry object allows you to access an object from anywhere, I believe the difference is that in dependency injection, the dependecy object is instantiated and passed into the requiring object when it is instantiated.
This passing in can be done via the constructor or by setting properties of the requiring object.
The main point is then that the requiring object and its dependencies are loosely coupled.
As a quick example, imagine that I have a User class that depends on the Database class. The database class would return some information to the User class. However, if I am doing unit testing, I would like to test the User class on its on, with my own set of inputs. With dependency injection, I can easily inject my own mock objects (inputs) into the user class without having to set up a database with the test data and depend on the database to access and return that data to us.
Having said that, dependency injection is not a must or required for all projects. For example, a complex dependency injection framework may affect the performance or introduce unneeded complexity into your application.
You are injecting the whole registry. I suggest you should simply inject your dependency directly:
class Foo {
/**
* #Inject
* #var MyLogClass
*/
private $log;
}
That way your code is simpler to read and write, and you don't have to care about your registry.
This is possible for example with PHP-DI which works with annotations like the DI container you are using.

Categories