NAME

IOC::Container - An IOC Container object

SYNOPSIS

use IOC::Container;

my $container = IOC::Container->new();
$container->register(IOC::Service::Literal->new('log_file' => "logfile.log"));
$container->register(IOC::Service->new('logger' => sub { 
    my $c = shift; 
    return FileLogger->new($c->get('log_file'));
}));
$container->register(IOC::Service->new('application' => sub {
    my $c = shift; 
    my $app = Application->new();
    $app->logger($c->get('logger'));
    return $app;
}));

$container->get('application')->run();    


# or a more complex example
# utilizing a tree-like structure
# of services

my $logging = IOC::Container->new('logging');
$logging->register(IOC::Service->new('logger' => sub {
    my $c = shift;
    return My::FileLogger->new($c->find('/filesystem/filemanager')->openFile($c->get('log_file')));
}));
$logging->register(IOC::Service::Literal->new('log_file' => '/var/my_app.log')); 

my $database = IOC::Container->new('database');
$database->register(IOC::Service->new('connection' => sub {
    my $c = shift;
    return My::DB->connect($c->get('dsn'), $c->get('username'), $c->get('password'));
}));
$database->register(IOC::Service::Literal->new('dsn'      => 'dbi:mysql:my_app'));
$database->register(IOC::Service::Literal->new('username' => 'test'));
$database->register(IOC::Service::Literal->new('password' => 'secret_test'));          

my $file_system = IOC::Container->new('filesystem');
$file_system->register(IOC::Service->new('filemanager' => sub { return My::FileManager->new() })); 
        
my $container = IOC::Container->new(); 
$container->addSubContainers($file_system, $database, $logging);
$container->register(IOC::Service->new('application' => sub {
    my $c = shift; 
    my $app = My::Application->new();
    $app->logger($c->find('/logging/logger'));
    $app->db_connection($c->find('/database/connection'));
    return $app;
})); 

$container->get('application')->run();    

DESCRIPTION

In this IOC framework, the IOC::Container object holds instances of IOC::Service objects keyed by strings. It can also have sub-containers, which are instances of IOC::Container objects also keyed by string.

                   +------------------+
                   |  IOC::Container  |
                   +---------+--------+
                             |
          +------------------+-----------------+
          |                  |                 |
  (*sub-containers)     (*proxies)        (*services)
          |                  |                 |
          V                  V                 V
+------------------+  +--------------+  +--------------+
|  IOC::Container  |  |  IOC::Proxy  |  | IOC::Service |
+------------------+  +--------------+  +--------------+
                                               |
                                           (instance)
                                               |
                                               V
                                   +-------------------------+                                                
                                   | <Your Component/Object> |
                                   +-------------------------+

METHODS

new ($container_name)

A container can be named with the optional $container_name argument, otherwise the container will have the name 'default'.

name

This will return the name of the container.

Service Methods

register ($service)

Given a $service, this will register the $service as part of this container. The value returned by the name method of the $service object is as the key where this service is stored. This also will call setContainer on the $service and pass in it's own instance.

If $service is not an instance of IOC::Service, or a subclass of it, an IOC::InsufficientArguments exception will be thrown.

If the name of $service already exists, then a IOC::ServiceAlreadyExists exception is thrown.

unregister ($name)

Given a $name this will remove the service from the container. If there is no service by that $name, then a IOC::ServiceNotFound exception is thrown.

registerWithProxy ($service, $proxy)

Same as register but also registers a $proxy object to wrap the $service object with.

addProxy ($name, $proxy)

Adds a $proxy object to wrap the service at $name.

get ($name)

Given a $name this will return the service instance that name corresponds to, if $name is not defined, an exception is thrown.

If there is no service by that $name, then a IOC::ServiceNotFound exception is thrown.

NOTE: If the requested service is currently locked (meaning it is being created), then a deferred service stub is returned. This will allow for cyclical dependencies to work.

find ($path)

Given a $path to a service, this method will attempt to locate that service. It utilizes the IOC::Visitor::ServiceLocator to do this.

hasService ($name)
getServiceList

Returns a list of all the named services available.

Parent Container Methods

getParentContainer

Get the parent container associated with this instance. If there is no container, undef is returned.

setParentContainer ($container)

Given a $container, this will associate it as the invocant's parent. If the $container is not an instance of IOC::Container (or a subclass of it), an IOC::InsufficientArguments exception will be thrown.

isRootContainer

If the invocant does not have a parent, then it is considered a root container and this method will return true (1), otherwise it will return false (0).

findRootContainer

This will climb back up the container hierarchy and find the root of the container tree.

Sub-Container Methods

addSubContainer ($container)

Adds a $container to it's keyed list of sub-containers. This has the effect of making the invocant the parent of $container. If $container is not a IOC::Container object (or a subclass of it), then an IOC::InsufficientArguments exception is thrown. If the name of $container is a duplicate of one already stored, then a IOC::ContainerAlreadyExists exception is thrown.

addSubContainers (@container)

This just loops calling addSubContainer on each of the items in @containers.

hasSubContainer ($name)
hasSubContainers

This will return true (1) if the invocant has sub-containers, and false (0) otherwise.

getSubContainerList

This will return a list of strings which the sub-containers are keyed by.

getSubContainer ($name)

This will return the sub-container associated with $name. If $name is undefined an IOC::InsufficientArguments exception will be thrown. If no sub-container exists by that $name, then an IOC::ContainerNotFound exception will be thrown.

getAllSubContainers

This will return a list of the actual sub-containers stored. This will be in the same order as the list returned by getSubContainerList.

accept ($visitor)

This method is part of the IOC::Visitable interface. It accepts only $visitor objects which implement the IOC::Visitor interface.

TO DO

Work on the documentation

BUGS

None that I am aware of. Of course, if you find a bug, let me know, and I will be sure to fix it.

CODE COVERAGE

I use Devel::Cover to test the code coverage of my tests, see the CODE COVERAGE section of IOC for more information.

SEE ALSO

AUTHOR

stevan little, <stevan@iinteractive.com>

COPYRIGHT AND LICENSE

Copyright 2004-2007 by Infinity Interactive, Inc.

http://www.iinteractive.com

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.