Home arrow PHP arrow PHP Service Layers: Dependency Injection

PHP Service Layers: Dependency Injection

In this penultimate part of the series, I put the finishing touches on the previous service layer by adding a couple of basic dependency injection containers along with a static helper to it. These can be used by client code to construct a specified service in a valid state.

TABLE OF CONTENTS:
  1. PHP Service Layers: Dependency Injection
  2. The serviceís object graph:
By: Alejandro Gervasio
Rating: starstarstarstarstar / 0
October 17, 2011

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Although its name may sound intimidating, a service is nothing but an additional abstraction layer (usually placed on top of the mapping one). It permits you to encapsulate application logic behind a single entry-point interface that can be consumed by several different clients, without having to deal with frustrating code duplication issues.

As with any other design pattern, the creation of a service isnít tied to a particular programming language or platform. This means that itís perfectly possible to implement it in a fairly straightforward fashion with PHP and enjoy the benefits that it provides, especially when developing middle/large-scale applications.

In line with this concept, in earlier installments of this series I showed how to construct a basic application, which used a service layer to perform CRUD operations on a domain model made up of a few user entities. Moreover, to demonstrate the flexible structure of this service, I enabled it to fetch the aforementioned user entities from the persistence layer in XML format. Not too bad, right?

While the pertinent service in its current state is entirely functional, there are a few extra steps we must take before seeing it in action. Since its object graph is slightly complex, we need first to create some dependencies (including a MySQL adapter, a user mapper and an array collection). In this penultimate chapter of the series Iíll be developing a couple of simple dependency injection containers, which will take care of spawning these collaborators in the background and returning to client code a ready-to-use user service object.

To learn how these DI containers will be created, keep reading. 

Recap time: the previous service classes

If you missed the preceding part of this series, where I implemented the user service mentioned in the introduction, below I included the full source code corresponding to this layer. This way, you can dissect it and understand its underlying logic.

So here is an abstract service, which is responsible for running CRUD functions on generic entities. Take a close look at it:

(MyApplication/Service/AbstractService.php)

<?php

namespace MyApplicationService;
use MyApplicationMapper,
    MyApplicationEntity;

abstract class AbstractService
{
    protected $_mapper;

    /**
     * Constructor
     */
    public function  __construct(MapperAbstractDataMapper $mapper)
    {
        $this->_mapper = $mapper;
    }

    /**
     * Find an entity by their ID
     */
    public function findById($id)
    {
        return $this->_mapper->findById($id);
    }

    /**
     * Find all the entities
     */
    public function findAll()
    {
        return $this->_mapper->findAll();
    }

    /**
     * Insert a new entity
     */
    public function insert(EntityEntityAbstract $entity)
    {
        return $this->_mapper->insert($entity);
    }

    /**
     * Update an entity
     */
    public function update(EntityEntityAbstract $entity)
    {
        return $this->_mapper->update($entity);
    }

    /**
     * Delete an entity
     */
    public function delete($id)
    {
        return $this->_mapper->delete($id);
    }
}

As seen in the above code fragment, the ďAbstractServiceĒ class accepts in its constructor a data mapper, which is used internally to retrieve, save and remove entities from the persistence layer. Since in this  case, I want to perform these operations only on user entities, itís necessary to spawn a subclass that works specifically with these kinds of domain objects.

Well, the following derivative does that. Check it out:

(MyApplication/Service/UserService.php)

<?php

namespace MyApplicationService;
use MyApplicationMapper,
    MyApplicationEntity;

class UserService extends AbstractService
{
    /**
     * Constructor
     */
    public function  __construct(MapperUserMapper $mapper)
    {
        parent::__construct($mapper);
    }

    /**
     * Save a user to persistence layer
     */
    public function save(EntityUser $user)
    {
        return $user->id === null ?
               $this->insert($user) :
               $this->update($user);
    }

    /**
     * Fetch all users in XML format
     */
    public function toXML()
    {
        $users = $this->_mapper->findAll();
        $xml = "<?xml version="1.0" encoding="UTF-8"?>n<users>n";
        foreach($users as $user) {
            $xml .= "<user>n<fname>$user->fname</fname>n"
                  . "<lname>$user->lname</lname>n"
                  . "<email>$user->fname</email>n</user>n";
        }
        $xml .= "</users>";
        return $xml;
    }
}

Mission accomplished. Thanks to the functionality implemented by the prior abstract service, itís really simple to create a child class that manipulates user entities exclusively. And to prove that a service layer can be extended easily, I also enabled the previous one to return the pertinent entities in XML. Now do you see how easy it is to build a service in PHP? I guess you do!

But before you launch your code editor and start adding your own tweaks to the previous class, itís necessary to do some more work. As I said in the introduction, the serviceís object graph is made up of a few dependencies which are injected in turn into the corresponding constructors, right?

Well, to prevent client code from constructing the graph at runtime, in the following segment Iíll be creating a couple of dependency injection containers. They will perform this task behind the scenes.

To learn how this will be done, click on the link below and keep reading. 



 
 
>>> More PHP Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: