NAME
Beam::Wire - A Dependency Injection Container
SYNOPSIS
# wire.yml
dbh:
class: 'DBI'
method: connect
args:
- 'dbi:mysql:dbname'
- {
PrintError: 1
}
cache:
class: 'CHI'
args:
driver: 'DBI'
dbh: { ref: 'dbh' }
# myscript.pl
use Beam::Wire;
my $wire = Beam::Wire->new( file => 'wire.yml' );
my $dbh = $wire->get( 'dbh' );
my $cache = $wire->get( 'cache' );
$wire->set( 'dbh', DBI->new( 'dbi:pgsql:dbname' ) );
DESCRIPTION
Beam::Wire is a dependency injection container.
TODO: Explain what a DI container does and why you want it
ATTRIBUTES
file
Read the list of services from the given file. The file is described below in the FILE section.
dir
A directory to use when searching for inner container files. Defaults to the directory that contains the file
.
config
A hashref of service configurations. This is normally filled in by reading the FILE.
services
A hashref of services. If you have any services already built, add them here.
METHODS
new
Create a new container.
FILE
Beam::Wire can read a YAML file to fill a container with services. The file should be a single hashref. The keys will be the service names.
SERVICE ATTRIBUTES
class
The class to instantiate. The class will be loaded and the method
(below) method called.
method
The class method to call to construct the object. Defaults to new
.
args
The arguments to the method
method. This can be either an array or a hash, like so:
# array
dbh:
class: DBI
method: connect
args:
- 'dbi:mysql:dbname'
# hash
cache:
class: CHI
args:
driver: Memory
max_size: 16MB
Using the array of arguments, you can give arrayrefs or hashrefs:
# arrayref of arrayrefs
names:
class: 'Set::CrossProduct'
args:
-
- [ 'Foo', 'Barkowictz' ]
- [ 'Bar', 'Foosmith' ]
- [ 'Baz', 'Bazleton' ]
# hashref
cache:
class: CHI
args:
- driver: Memory
max_size: 16MB
INNER CONTAINERS
Beam::Wire objects can hold other Beam::Wire objects!
inner:
class: Beam::Wire
args:
config:
dbh:
class: DBI
method: connect
args:
- 'dbi:mysql:dbname'
cache:
class: CHI
args:
driver: Memory
max_size: 16MB
Inner containers' contents can be reached from outer containers by separating the names with a slash character:
my $dbh = $wire->get( 'inner/dbh' );
INNER FILES
inner:
class: Beam::Wire
args:
file: inner.yml
Inner containers can be created by reading files just like the main container. If the file
attribute is relative, the parent's dir
attribute will be added:
# share/parent.yml
inner:
class: Beam::Wire
args:
file: inner.yml
# share/inner.yml
dbh:
class: DBI
method: connect
args:
- 'dbi:sqlite:data.db'
# myscript.pl
use Beam::Wire;
my $container = Beam::Wire->new(
file => 'share/parent.yml',
);
my $dbh = $container->get( 'inner/dbh' );
If more control is needed, you can set the dir attribute on the parent container.
If even more control is needed, you can make a subclass of Beam::Wire.