﻿viocon/README.md                                                                                    0000777                 00000003554 15251221733 0007337 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       # Viocon [![Build Status](https://travis-ci.org/usmanhalalit/viocon.png?branch=master)](https://travis-ci.org/usmanhalalit/viocon)
A simple and flexible Dependency Injection or Service container for PHP.

It can be extremely helpful to decouple your dependencies. You can also mock dependencies at runtime.

## Installation

Viocon uses [Composer](http://getcomposer.org/) to make things easy.

Learn to use composer and add this to require (in your composer.json):

    "usmanhalalit/viocon": "1.0.*@dev"

Library on [Packagist](https://packagist.org/packages/usmanhalalit/viocon).

## Usage
```PHP
$container = new \Viocon\Container();
```

**You can optionally create a class alias too**
```PHP
new \Viocon\Container('Container');
```
Viocon will create a class alias for you with the given name 'Container'.
Now you can use this class' methods statically, like
```PHP
\Container::set(...);
\Container::build(...);
```
And so ...
___

### Bind a closure
```PHP
$container->set('myClosure', function ($test1, $test2) 
{
    $stdClass = new \stdClass();
    $stdClass->testVar1 = $test1;
    $stdClass->testVar2 = $test2;
    $stdClass->testMethod = function ($test3) {
        return $test3;
    };

    return $stdClass;
});

$object = $container->build('myClosure', array('Test Var 1', 'Test Var 2'))

echo $object->testVar1;

```

### Build Any Class and Optionally Pass Parameters
```PHP
$container->build('\PDO', array('myConnectionInfo'));

```

### Singleton

```PHP
$container->set('mySingleton', '\\stdClass');
$stdClass = $container->build('mySingleton');
```

### Replacing Objects at Runtime
It can be useful while testing with mocked object
```PHP
$mockedClass = new \stdClass();
$mockedClass->testVar = 'mocked';

static::$container->setInstance('\\stdClass', $mockedClass);

$stdClass = static::$container->build('\\stdClass');
$this->assertEquals('mocked', $stdClass->testVar);
```
                                                                                                                                                    viocon/phpunit.xml                                                                                  0000777                 00000001057 15251221733 0010265 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?xml version="1.0" encoding="UTF-8"?>

<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         colors="true"
         bootstrap="tests/bootstrap.php"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false"
         syntaxCheck="false">
    <testsuites>
        <testsuite name="Viocon Test Suite">
            <directory>tests/Viocon/</directory>
        </testsuite>
    </testsuites>
</phpunit>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 viocon/LICENSE                                                                                      0000777                 00000002070 15251221733 0007055 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       The MIT License (MIT)

Copyright (c) 2013 Muhammad Usman

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.                                                                                                                                                                                                                                                                                                                                                                                                                                                                        viocon/composer.json                                                                                0000777                 00000001262 15251221733 0010574 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       {
    "name": "usmanhalalit\/viocon",
    "description": "A simple and flexible Dependency Injection container for PHP.",
    "homepage": "https:\/\/github.com\/usmanhalalit\/viocon",
    "keywords": [
        "ioc",
        "container",
        "di",
        "test"
    ],
    "license": "MIT",
    "minimum-stability": "dev",
    "authors": [
        {
            "name": "Muhammad Usman",
            "email": "hi@usman.it",
            "role": "Developer"
        }
    ],
    "require": {
        "php": ">=5.3.0"
    },
    "require-dev": {
        "phpunit\/phpunit": "3.7.*"
    },
    "autoload": {
        "psr-4": {
            "Rvx\\Viocon\\": "src\/Viocon\/"
        }
    }
}                                                                                                                                                                                                                                                                                                                                              viocon/tests/bootstrap.php                                                                          0000777                 00000000111 15251221733 0011732 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php

namespace Rvx;

require_once __DIR__ . "/../vendor/autoload.php";
                                                                                                                                                                                                                                                                                                                                                                                                                                                       viocon/tests/Viocon/ContainerTest.php                                                               0000777                 00000005625 15251221733 0013753 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php

namespace Rvx\Viocon;

class ContainerTest extends \Rvx\PHPUnit_Framework_TestCase
{
    protected static $container;
    public static function setupBeforeClass()
    {
        static::$container = new Container();
    }
    public function testBuildWithClassNameAsKey()
    {
        $stdClass = static::$container->build('\\stdClass');
        $this->assertInstanceOf('\\stdClass', $stdClass);
    }
    public function testBuildWithClassNameAsKeyWithConstructorParams()
    {
        $reflectionClass = static::$container->build('\\ReflectionClass', array('Rvx\\Viocon\\ContainerTest'));
        $this->assertInstanceOf('\\ReflectionClass', $reflectionClass);
        $this->assertEquals('Rvx\\Viocon\\ContainerTest', $reflectionClass->name);
    }
    public function testSetAndBuild()
    {
        static::$container->set('myStdClass', '\\stdClass');
        $stdClass = static::$container->build('myStdClass');
        $this->assertInstanceOf('\\stdClass', $stdClass);
    }
    public function testSetAndBuildClosure()
    {
        static::$container->set('myClosure', function ($test1, $test2) {
            $stdClass = new \stdClass();
            $stdClass->testVar1 = $test1;
            $stdClass->testVar2 = $test2;
            $stdClass->testMethod = function ($test3) {
                return $test3;
            };
            return $stdClass;
        });
        $myClosure = static::$container->build('myClosure', array('Test Var 1', 'Test Var 2'));
        $this->assertInstanceOf('\\stdClass', $myClosure);
        $this->assertEquals('Test Var 1', $myClosure->testVar1);
        $this->assertEquals('Test Var 2', $myClosure->testVar2);
        $method = $myClosure->testMethod;
        $this->assertEquals('test', $method('test'));
    }
    public function testReplacingWithMockedInstanceOnRuntime()
    {
        $mockedClass = new \stdClass();
        $mockedClass->testVar = 'mocked';
        static::$container->setInstance('\\stdClass', $mockedClass);
        $stdClass = static::$container->build('\\stdClass');
        $this->assertEquals('mocked', $stdClass->testVar);
    }
    public function testSingleton()
    {
        $container = static::$container;
        $container->singleton('mySingleton', '\\stdClass');
        $this->assertInstanceOf('\\stdClass', $container->build('mySingleton'));
    }
    public function testSingletonWithPersistence()
    {
        $container = new Container();
        $container->singleton('mySingleton', '\\stdClass');
        $stdClass = $container->build('mySingleton');
        $stdClass->testVar = 'value';
        $stdClass2 = $container->build('mySingleton');
        $this->assertEquals('value', $stdClass2->testVar);
    }
    public function testAlias()
    {
        new Container('VContainer');
        \Rvx\VContainer::set('myClosure', function () {
            return 'Test';
        });
        $this->assertEquals('Test', \Rvx\VContainer::build('myClosure'));
    }
}
                                                                                                           viocon/src/Viocon/Container.php                                                                     0000777                 00000006532 15251221733 0012536 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php

namespace Rvx\Viocon;

class Container
{
    /**
     * @var array
     */
    public $registry = array();
    /**
     * Singleton instances
     *
     * @var array
     */
    public $singletons = array();
    public function __construct($alias = null)
    {
        if ($alias) {
            AliasFacade::setVioconInstance($this);
            \class_alias('Rvx\\Viocon\\AliasFacade', $alias);
        }
    }
    /**
     * Register an object with a key
     *
     * @param  string $key
     * @param  mixed  $object
     * @param  bool   $singleton
     *
     * @return void
     */
    public function set($key, $object, $singleton = \false)
    {
        $this->registry[$key] = \compact('object', 'singleton');
    }
    /**
     * If we have a registry for the given key
     *
     * @param  string $key
     *
     * @return bool
     */
    public function has($key)
    {
        return \array_key_exists($key, $this->registry);
    }
    /**
     * Register as singleton.
     *
     * @param  string $key
     * @param  mixed  $object
     *
     * @return void
     */
    public function singleton($key, $object)
    {
        $this->set($key, $object, \true);
    }
    /**
     * Register or replace an instance as a singleton.
     * Useful for replacing with Mocked instance
     *
     * @param  string $key
     * @param  mixed  $instance
     *
     * @return void
     */
    public function setInstance($key, $instance)
    {
        $this->singletons[$key] = $instance;
    }
    /**
     * Build from the given key.
     * If there is a class registered with Container::set() then it's instance
     * will be returned. If a closure is registered, a closure's return value
     * will be returned. If nothing is registered then it will try to build an
     * instance with new $key(...).
     *
     * $parameters will be passed to closure or class constructor.
     *
     *
     * @param  string $key
     * @param  array  $parameters
     *
     * @return mixed
     */
    public function build($key, $parameters = array())
    {
        // If we have a singleton instance registered the just return it
        if (\array_key_exists($key, $this->singletons)) {
            return $this->singletons[$key];
        }
        // If we don't have a registered object with the key then assume user
        // is trying to build a class with the given key/name
        if (!\array_key_exists($key, $this->registry)) {
            $object = $key;
        } else {
            $object = $this->registry[$key]['object'];
        }
        $instance = $this->instanciate($object, $parameters);
        // If the key is registered as a singleton, we can save the instance as singleton
        // for later use
        if (isset($this->registry[$key]['singleton']) && $this->registry[$key]['singleton'] === \true) {
            $this->singletons[$key] = $instance;
        }
        return $instance;
    }
    /**
     * Instantiate an instance of the given type.
     *
     * @param  string $key
     * @param  array  $parameters
     *
     * @throws \Exception
     * @return mixed
     */
    protected function instanciate($key, $parameters = null)
    {
        if ($key instanceof \Closure) {
            return \call_user_func_array($key, $parameters);
        }
        $reflection = new \ReflectionClass($key);
        return $reflection->newInstanceArgs($parameters);
    }
}
                                                                                                                                                                      viocon/src/Viocon/AliasFacade.php                                                                   0000777                 00000001642 15251221733 0012726 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php

namespace Rvx\Viocon;

/**
 * This class gives the ability to access non-static methods statically
 *
 * Class AliasFacade
 *
 * @package Viocon
 */
class AliasFacade
{
    /**
     * @var Container
     */
    protected static $vioconInstance;
    /**
     * @param $method
     * @param $args
     *
     * @return mixed
     */
    public static function __callStatic($method, $args)
    {
        if (!static::$vioconInstance) {
            static::$vioconInstance = new Container();
        }
        return \call_user_func_array(array(static::$vioconInstance, $method), $args);
    }
    /**
     * @param Container $instance
     */
    public static function setVioconInstance(Container $instance)
    {
        static::$vioconInstance = $instance;
    }
    /**
     * @return \Viocon\Container $instance
     */
    public static function getVioconInstance()
    {
        return static::$vioconInstance;
    }
}
                                                                                              viocon/src/Viocon/VioconException.php                                                               0000777                 00000000113 15251221733 0013715 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php

namespace Rvx\Viocon;

class VioconException extends \Exception
{
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  