PHPackages                             molajo/ioc - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. molajo/ioc

ActiveMolajo-package

molajo/ioc
==========

Molajo Inversion of Control package offers a full-featured, simple-to-use dependency injection and object construction solution for PHP applications.

v0.4(12y ago)1432MITPHPPHP &gt;=5.4

Since Nov 24Pushed 10y ago3 watchersCompare

[ Source](https://github.com/Molajo/IoC)[ Packagist](https://packagist.org/packages/molajo/ioc)[ Docs](http://github.com/Molajo/IoC)[ RSS](/packages/molajo-ioc/feed)WikiDiscussions master Synced 2mo ago

READMEChangelog (1)Dependencies (2)Versions (5)Used By (0)

======= Inversion of Control (IoC) Package
==========================================

[](#inversion-of-control-ioc-package)

[![Build Status](https://camo.githubusercontent.com/b40065aa2ba4e0f8144ae0bd4daffd7fcfe8e7b6338897f4e67db3cbfe043ba8/68747470733a2f2f7472617669732d63692e6f72672f4d6f6c616a6f2f496f432e706e673f6272616e63683d6d6173746572)](https://travis-ci.org/Molajo/IoC)

The [Molajo Inversion of Control (IoC)](https://github.com/Molajo/IoC/blob/master/.dev/IoC.png)package offers a full-featured, dependency injection solution and a services layer for PHP applications.

Usage
-----

[](#usage)

These are the basic steps to implementing the Inversion of Control (IoC) package:

1. Create a [Service Folder](https://github.com/Molajo/IoC#1-service-folder) to store custom dependency injection handlers.
2. Update the [Front Controller](https://github.com/Molajo/IoC#2-front-controller) for the Inversion of Control Container (IoCC).
3. [Request Services](https://github.com/Molajo/IoC#3-application-service-requests) from the IoCC within the Application.
4. Create [Custom Factory Methods](https://github.com/Molajo/IoC#4---custom-dependency-injection-handlers) for Services.

### 1. Service Folder

[](#1-service-folder)

Create a folder within your application to store Service Factory Methods. Each Customer Handler has a folder containing a class file named `ClassnameFactoryMethod.php`. When instantiating the IoCC, you'll provide the namespace of the Services Folder.

```
Molajo
.. Services
.. .. Database
.. .. .. DatabaseFactoryMethod.php
.. .. Configuration
.. .. .. ConfigurationFactoryMethod.php
.. .. Modelread
.. .. .. ModelreadFactoryMethod.php
.. .. etc ..

```

The default namespace for a services folder is `Molajo\Services`. Whatever value is used, it will be passed in as a parameter when instantiating the Container class.

### 2. Front Controller

[](#2-front-controller)

The [Front Controller](http://www.martinfowler.com/eaaCatalog/frontController.html) should be the only point of entry into the Inversion of Control Container (IoCC).

#### Use Statement

[](#use-statement)

Add a use statement for the IoC Container class.

```
use Molajo\IoC\Container;
```

#### Class Property

[](#class-property)

Define a class property in which to store the IoCC instance.

```
    /**
     * Inversion of Control Container
     *
     * @var    object
     * @since  1.0.0
     */
    protected $iocc;
```

#### IoCC Methods

[](#iocc-methods)

Add these four methods: getService, setService, cloneService, and removeService to the Front Controller.

```
    /**
     * Get a service instance
     *
     * @param    string $service
     * @param    array  $options
     *
     * @results  null|object
     * @since    1.0
     * @throws   FrontcontrollerException
     */
    public function getService($service, $options = array())
    {
        return $this->ioc->getService($service, $options);
    }

    /**
     * Replace the existing service instance
     *
     * @param    string $service
     * @param    object $instance
     *
     * @results  $this
     * @since    1.0
     * @throws   FrontcontrollerException
     */
    public function setService($service, $instance = null)
    {
        $this->ioc->getService($service, $instance);

        return $this;
    }

    /**
     * Clone the existing service instance
     *
     * @param    string $service
     *
     * @results  null|object
     * @since    1.0
     * @throws   FrontcontrollerException
     */
    public function cloneService($service)
    {
        return $this->ioc->cloneService($service);
    }

    /**
     * Remove the existing service instance
     *
     * @param    string $service
     *
     * @results  $this
     * @since    1.0
     */
    public function removeContainerEntries($service)
    {
        $this->ioc->removeContainerEntries($service);

        return $this;
    }
```

#### Instantiate the Container

[](#instantiate-the-container)

In the Front Controller boot process, instantiate the [Container](https://github.com/Molajo/IoC/blob/master/Container.php)using the code that begins with **$connect** and ends before "// Automatically Load These Services". The four closure statements passed into the Container will be used outside of the Front Controller to access the IoCC methods defined in the previous step. Note, also, the location of the $services\_folder is passed into the Container.

```
    /**
     * Initialise Application, including invoking Inversion of Control Container and
     *  Services defined in Services.xml
     *
     * @return  $this
     * @since  1.0.0
     * @throws  FrontcontrollerException
     */
    public function initialise()
    {
        $this->checkPHPMinimum();

        set_exception_handler(array($this, 'handleException'));
        set_error_handler(array($this, 'handlePHPErrors'), 0);

        $connect       = $this;
        $getService    = function ($service, $options = array()) use ($connect) {
            return $connect->getService($service, $options);
        };
        $setService    = function ($service, $instance) use ($connect) {
            return $connect->setService($service, $instance);
        };
        $cloneService  = function ($service) use ($connect) {
            return $connect->cloneService($service);
        };
        $removeService = function ($service) use ($connect) {
            return $connect->removeContainerEntries($service);
        };

        $services_folder = 'Molajo\\Services';

        $this->ioc = new Container($getService, $setService, $cloneService, $removeService, $services_folder);

        // Automatically Load These Services
        $xml_string = $this->readXMLFile(__DIR__ . '/' . 'Services.xml');

        $services = simplexml_load_string($xml_string);

        foreach ($services->service as $service) {
            $this->getService((string)$service->attributes()->name, array());
        }

        return;
    }
```

### 3. Application Service Requests

[](#3-application-service-requests)

The four closures provide a way to access the Front Controller entry points into the IoCC.

- **$getService** - create the $service using the $options specified, or return an existing service with the same name;
- **$setService** - replace the existing $service registry in the container with the instance specified;
- **$cloneService** - clone the container registry entry for a specified service, returning the cloned instance;
- **$removeService** - remove the container registry entry specified;

When the IoC Container creates a Factory Method instance, it injects it with all four closures before injecting the handler into the DI Adapter. The handler can use those class properties to interact with the IoCC. In this example, the handler requests the dependent Application Service.

```
    $getService = $this->getService;
    $application = $getService('Application');

    /** Has cache been activated? */
    $cache_service = $application->get('cache_service');
    if ((int)$cache_service === 0) {
        return $this;
    }
```

#### getService Parameters

[](#getservice-parameters)

1. **$service** Fully qualified namespace (ex. `Molajo\\Services\\Database\\DatabaseInjector`) or the name of the Services sub-folder (ex. `Database`).
2. **$options** Optional associative array contain runtime parameters required by the service.

#### Existing, If Exists, or New Instance

[](#existing-if-exists-or-new-instance)

When the Container processes a getService request, it first determines if the named service exists in the registry. If it is, the existing service is returned. If it does not exist, a new instance will be created unless the `if_exists` $options entry was specified in the request.

#### Example 1: No fully qualified namespace

[](#example-1-no-fully-qualified-namespace)

When the fully qualified namespace is not defined, the Container looks for a folder with that name in the Services library. In this example, the $options array defines runtime variables for the instantiation process.

```
$getService = $this->getService;

$options = array;
$options['model_type'] = 'Application';
$options['model_name'] = 'Includers';
$database = $getService('LocateFile', $options);
```

#### Example 2: if\_exists Option

[](#example-2-if_exists-option)

This request instructs the Container only return an instance of the User if that instance already exists.

```
$getService = $this->getService;

$options = array;
$options['if_exists'] = true;
$database = $getService('Molajo\\User', $options);
```

#### Example 3: Standard Factory Method

[](#example-3-standard-factory-method)

A Service Factory Method is not always needed. Classes can be created by the Standard Factory Method. It will match the values defined in the $options associative array with the Constructor parameters and use that data to create the class. For the service name, use the fully qualified class name.

```
$getService = $this->getService;

$options = array;
$options['constructor_parameter1'] = true;
$options['constructor_parameter2'] = true;
$database = $getService('Molajo\\Utilities\\Classname', $options);
```

#### setService

[](#setservice)

Replaces the existing Container registry entry for this service with the value sent in.

```
$setService = $this->setService;
$database = $setService('Application', $instance);
```

#### cloneService

[](#cloneservice)

Clones the existing Container registry entry for this service and returns the cloned value.

```
$cloneService = $this->cloneService;
$database = $cloneService('Database');
```

#### removeService

[](#removeservice)

Removes the existing Container registry entry for this service.

```
$removeService = $this->removeService;
$database = $removeContainerEntries('Database');
```

### 4 - Custom Factory Methods

[](#4---custom-factory-methods)

To create a Custom Dependency Injection Handler:

1. Add a folder to the **Services Folder** defined in [Step 1](https://github.com/Molajo/IoC#1-service-folder). The folder name is the name of the service.
2. Create a PHP file in that folder named `ServiceNameFactoryMethod.php`.

```
Molajo
.. Services
.. .. ServiceName
.. .. .. ServiceNameFactoryMethod.php

```

#### Standard Properties

[](#standard-properties)

The Custom Factory Method has access to the following class properties:

1. **$getService** - Closure to request a service of the IoCC, defined above
2. **$setService** - Closure to set a service contained within the IoCC registry, defined above
3. **$cloneService** - Closure to clone a service contained within the IoCC registry, defined above
4. **$removeService** - Closure to remove a service contained within the the IoCC registry, defined above
5. **$service** - The name specified in the getService statement
6. **$service\_namespace** - Set the fully qualified namespace for the Class to be instantiated in the constructor
7. **$store\_instance\_indicator** - defaults to false, set to true in the constructor to store the instance in the IoCC registry
8. **$static\_instance\_indicator** - defaults to false, set to true in the constructor to request a static instance
9. **$store\_properties\_indicator** - defaults to false, set to true in the constructor to store the properties, not the instance, in the IoCC registry
10. **$product\_result** - populated with the instantiated class
11. **$options** - associative array provided by the getService call

#### Custom Factory Method Starter

[](#custom-factory-method-starter)

Below is a basic starting pattern for a Custom Dependency Injection Handler. The event methods available to the Factory Method are: onBeforeInstantiation, Instantiate, onAfterInstantiation, initialise, onAfterServiceInitialise, and getProductValue. Each method can be used to inject code at different points in the class creation process. The like-named [AbstractHandler](https://github.com/Molajo/IoC/blob/master/Handler/AbstractFactoryMethod.php)method will be used for any omitted methods in the custom class. It is a good idea to become familiar with that class.

The [Molajo\\Services](https://github.com/Molajo/Standard/tree/master/vendor/Molajo/Services)folder is also a good source of examples of Custom DI Injectors.

```
