IOC & Dependency Injection

As applications become more complex and introduce extensions to existing modules, there comes a need to change the implementation of existing components. It isn't acceptable to change the source of existing components and therefore not feasible to change their implementations. IOC allows developers to redefine references to an application's dependencies, thus allowing him/her to use custom module components specific to the project.

When is IOC needed? - Example

Consider an typical subscription website, where users must register an account to access premium content. In this application, we need to associate news feed posts to each user (like Twitter or Facebook). So we create a custom members module, with a new member class that extends the default member class provided by base members module.

<?php
class CustomMember extends saMember {
private $newsFeedPosts;
}

If you were to attempt to register a new user to the application, you would find that a saMember object would be created, not the expected CustomMember object. This occurs because the base members module is only aware of it's own saMember class. We need to change all references of saMember to CustomMember without changing other modules.

See the override reference to a class section to learn how to use the custom member class.

Override Reference to a Class

Siteadmin maintains a map of class => namespace for all classes across the application. In the context of our previous example, the application knows the namespace for saMember is sa\member\saMember. We can overwrite that mapping to a different namespace using the @IOC_NAME declaration in our custom class' docBlock.

<?php
namespace MyApp\member;
/**
* @IOC_NAME="saMember"
*/
class CustomMember extends saMember {
private $newsFeedPosts;
}

The docBlock tells the application create an instance of MyApp\member\CustomerMember every time saMember is referenced.

How to Use IOC

In the previous section, we changed all references to saMember to our custom class, but that will not work on its own. To utilize the IOC system, you can't hard code class references. You must use the IOC handler instead.

Create class instance

Don't

// Returns an instance of saMember. IOC is not activated.
$member = new saMember();

Do

// Returns instance of CustomMember class
$member = ioc::resolve('saMember')

Get class namespace

Don't

if ($member instanceof \sa\member\saMember) {}

Do

$namespace = ioc::staticResolve('saMember')
if ($member instanceof $namespace) {}