Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/boxuk/boxuk-di
Dependency Injection and Reflection Library
https://github.com/boxuk/boxuk-di
Last synced: 5 days ago
JSON representation
Dependency Injection and Reflection Library
- Host: GitHub
- URL: https://github.com/boxuk/boxuk-di
- Owner: boxuk
- License: gpl-3.0
- Created: 2010-11-11T17:26:44.000Z (about 14 years ago)
- Default Branch: master
- Last Pushed: 2020-03-12T15:55:18.000Z (over 4 years ago)
- Last Synced: 2024-04-14T11:50:53.827Z (7 months ago)
- Language: PHP
- Homepage:
- Size: 72.3 KB
- Stars: 9
- Watchers: 12
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.markdown
- License: LICENSE-GPL
Awesome Lists containing this project
README
# Unmaintained
# Box UK - Dependency Injection, Reflection and Annotations
The BoxUK-DI library enables you to easily handle dependency injection between components using annotations and type-hinting, similar to Guice and Spring.
## Dependencies
* PHP 5.3+
* Addendum 0.4.0+## Including the Library
To include the library just include the bootstrap file in your application.
include '../path/to/boxuk-di/lib/bootstrap.php';## The Standard Injector
The main part of the library is the DI container, a simple example to fetch a class...
$libraryLoader = $injector->getClass( 'LibraryLoader' );By default, the injector will create a new class each time it's asked for it. Its constructor parameters will be analysed to check types so that any dependencies can be injected into the new object (if these dependencies don't exist they will be created). It's methods will also be checked on creation for any that have been annotated for method injection (see below)
## Scopes
By default, new objects will be instantiated for each requested class. To use objects in a different scope, singleton for example, just annotate them as so:
/**
* @ScopeSingleton
*/
class LibraryLoader {
}### Available Scopes
#### Singleton
The singleton scope is defined by the annotation @ScopeSingleton, and lasts for the lifetime of a request. Objects annotated as singletons will only be created once by the injector, and then the same object is returned on each subsequent request.
/**
* @ScopeSingleton
*/
class MyClass {}#### Session
The session scope will store objects in the users session, and these will be available for the lifetime of the session. This can be used for things like a logged in user, a shopping cart, etc... To give a class session scope just annotate it as so.
/**
* @ScopeSession
*/
class MyShoppingCart {}To use this scope you will first need to define a class that implements the _SessionHandler_ interface and bind it to this name (SessionHandler).
### Interface Binding
If your class is implementing an interface which it is type hinted for then you can specify this by the above annotation:
/**
* @ScopeSingleton(implements="SomeInterface")
*/
class MyClass implements SomeInterface, AnotherInterface {}Then requests for that interface will return this singleton:
$oInjector->getClass( 'SomeInterface' );### 3rd Party Singletons
To add 3rd party singletons to the injector just go through the _getScope()_ method.
$this->injector->getScope( 'singleton' )->set( $doctrineManager );## Method Injection
You can also annotate methods to be injected:
/**
* @InjectMethod
*/
public function setClassLoader( ClassLoader $oClassLoader ) {}*NB:* When doing method injection there is no constraint on the name of the method, or the number of parameters injected.
### Parameter Types
If your method requires tweaking the injected parameter types then you can specify these with another annotation:
/**
* @InjectMethod
* @InjectParam(variable="class", class="ModuleRegistry")
*/
public function setSomething( SomeInterface $class ) {
// will receive a ModuleRegistry
}This can also be used for constructors.
## Property Injection
The final type of injection available is property injection. This can be used for public *and* private properties.
/**
* @InjectProperty
* @var SomeClass
*/
private $someClass;The type of object injected is specified by the *@var* PHPDoc.
## Inheritance
### Methods
When doing method injection, the injector will ascend up the inheritance chain to also inject methods in parent classes. If you override a method in your child class though this method will only be injected (if annotated) in the child class.
### Scopes
When checking a class for scope, the injector will ascend up the inheritance chain and stop at the first scope annotation it encounters.
## Fetching New Classes
To ignore any scope annotations you can force fetching a new instance of the class you want:
$oInjector->getNewClass( 'SomeClass' );## Constructor Patterns
The one requirement of the injector is that type hinting or _@InjectParam_ annotations need to be used to identify dependencies, so only classes can be dependencies. This makes a clean seperation between class dependencies and class configuration. For classes created with the injector you will not be able to pass in strings or arrays to the constructor. You can think of this as...
1. Objects are dependencies
2. Anything else is configurationSo you will need to remove any configuration from your constructors and injected methods, this will be moved to initialisation time for your class:
$class = $injector->getClass( 'MyClass' );
$class->initialise( $port, array( 'some', 'values' ) );*NB:* initialise() here is just an arbitrary method on the class being created.
## Using the Injector
So, your class has been injected with all it's dependencies, but what if you want to create more objects inside your class? Well just ask for the injector as one of your dependencies:
private $injector;public function __construct( BoxUK\Inject\Injector $injector ) {
$this->injector = $injector;
}private function myMethod() {
$class = $this->injector->getClass( 'SomethingElse' );
}Don't use the injector as a service locator though inside your class, always specify your dependencies to be injected at construct time.
## Inject Arbitrary Objects
The injector also provides an *inject()* method which can be used to do method injection and property injection on arbitrary objects. These objects can have been created elsewhere but the injector will scan them for dependencies to inject.
$injector->inject( $someObject );## The Helper
The easiest way to create an injector is to use the _Helper_ class.
$helper = new BoxUK\Inject\Helper();
$injector = $helper->getInjector();### Configuration
When you create the helper you can pass in a _Config_ object. This example shows a config object generated from an _.ini_ file.
$config = new BoxUK\Inject\Config\IniFile();
$config->initFromFile( 'path/to/file.ini' );
$helper = new BoxUK\Inject\Helper( $config );The injector will be all set up and ready to go. There are also methods to create reflectors and caches.
## Reflection and Annotations
The second part of the library, which the injector is built on is the reflector. You can use this class to access reflection and annotation information on classes.
$reflector = $helper->getReflector();### Caching
Reflection can be slow, so for your applications production mode it's reccomended to use the _BoxUK\Reflect\Caching_ reflector instead. You can get this through configuration.
boxuk.reflector = cachingThe complete list of configuration options is as follows:
Setting
Values
Default
boxuk.reflector
standard, caching
standard
boxuk.reflector.cache
file, memcache, apc
file
boxuk.reflector.filecache.dir
(path to cache directory)
(sys_get_temp_dir())
boxuk.reflector.filecache.filename
(name of cache file)
$CLASS.cache
boxuk.reflector.memcache.host
(memcache host)
localhost
boxuk.reflector.memcache.port
(memcache port)
11211
boxuk.reflector.memcache.key
(memcache key)
$CLASS
boxuk.reflector.apc.key
(APC key)
$CLASS
_($CLASS means the fully qualified name of the class concerned)_
## Unit Testing
You can unit test these classes using:
phing test