Rewire - Dependency Injection
Dependency Injection Container for Perl 5
use Rewire; my $services = { filetemp => { package => 'File/Temp' }, tempfile => { package => 'Mojo/File', argument => { '$service' => 'filetemp' } } }; my $rewire = Rewire->new(services => $services); $rewire->resolve('tempfile');
This package provides methods for using dependency injection, and building objects and values.
This package integrates behaviors from:
Data::Object::Role::Buildable
Data::Object::Role::Proxyable
This package uses type constraints from:
Types::Standard
This package supports the following scenarios:
use Rewire; my $services = { io => { package => 'IO/Handle' }, log => { package => 'Mojo/Log', argument => { format => { '$callback' => 'io' } } }, }; my $rewire = Rewire->new( services => $services );
This package supports resolving services as callbacks to be passed around and/or resolved by other services. The $callback directive is used to specify the name of a service to be resolved and passed as an argument.
$callback
use Rewire; my $services = { file => { package => 'Mojo/File', argument => { '$envvar' => 'home' } } }; my $rewire = Rewire->new( services => $services );
This package supports inlining environment variables as arguments to services. The $envvar directive is used to specify the name of an environment variable, and can also be used in metadata for reusability.
$envvar
use Rewire; my $services = { temp => { package => 'File/Temp' }, file => { package => 'Mojo/File', argument => { '$function' => 'temp#tempfile' } } }; my $rewire = Rewire->new( services => $services );
This package supports inlining the result of a service resolution and function call as arguments to services. The # delimited $function directive is used to specify the name of an existing service on the right-hand side, and an arbitrary function to be call on the result on the left-hand side.
#
$function
use Rewire; my $metadata = { home => '/home/ubuntu' }; my $services = { file => { package => 'Mojo/File', argument => { '$metadata' => 'home' } } }; my $rewire = Rewire->new( metadata => $metadata, services => $services );
This package supports inlining configuration data as arguments to services. The $metadata directive is used to specify the name of a stashed configuration value or data structure.
$metadata
use Rewire; my $services = { temp => { package => 'File/Temp' }, file => { package => 'Mojo/File', argument => { '$method' => 'temp#filename' } } }; my $rewire = Rewire->new( services => $services );
This package supports inlining the result of a service resolution and method call as arguments to services. The # delimited $method directive is used to specify the name of an existing service on the right-hand side, and an arbitrary method to be call on the result on the left-hand side.
$method
use Rewire; my $services = { temp => { package => 'File/Temp' }, file => { package => 'Mojo/File', argument => { '$routine' => 'temp#tempfile' } } }; my $rewire = Rewire->new( services => $services );
This package supports inlining the result of a service resolution and routine call as arguments to services. The # delimited $routine directive is used to specify the name of an existing service on the right-hand side, and an arbitrary routine to be call on the result on the left-hand side.
$routine
use Rewire; my $services = { io => { package => 'IO/Handle' }, log => { package => 'Mojo/Log', argument => { handle => { '$service' => 'io' } } }, }; my $rewire = Rewire->new( services => $services );
This package supports inlining resolved services as arguments to other services. The $service directive is used to specify the name of a service to be resolved and passed as an argument.
$service
use Rewire; my $metadata = { applog => '/var/log/rewire.log' }; my $services = { mojo_log => { package => 'Mojo/Log', argument => { path => { '$metadata' => 'applog' }, level => 'warn' }, argument_as => 'list' } }; my $rewire = Rewire->new( services => $services, metadata => $metadata );
This package supports providing static and/or dynamic arguments during object construction from metadata or other services.
metadata
services
use Rewire; my $services = { mojo_date => { package => 'Mojo/Date', builder => [ { method => 'new', return => 'self' }, { method => 'to_datetime', return => 'result' } ] } }; my $rewire = Rewire->new( services => $services, );
This package supports specifying multiple build steps as function, method, and routine calls and chaining them together.
function
method
routine
use Rewire; my $metadata = { home => '/home/ubuntu' }; my $services = { tempfile => { package => 'Mojo/File', argument => { '$metadata' => 'home' } } }; my $rewire = Rewire->new( services => $services, metadata => $metadata );
This package supports configuring services and metadata in the service of building objects and values.
use Rewire; my $services = { mojo_date => { package => 'Mojo/Date', constructor => 'new' } }; my $rewire = Rewire->new( services => $services );
This package supports specifying constructors other than the traditional new routine. A constructor is always called with the package name as the invocant.
new
use Rewire; my $services = { io => { package => 'IO/Handle' }, log => { package => 'Mojo/Log', argument => { handle => { '$service' => 'io' } } }, development_log => { package => 'Mojo/Log', extends => 'log', builder => [ { method => 'new', return => 'self' }, { method => 'path', argument => '/tmp/development.log', return => 'none' }, { method => 'level', argument => 'debug', return => 'none' } ] }, production_log => { package => 'Mojo/Log', extends => 'log', builder => [ { method => 'new', return => 'self' }, { method => 'path', argument => '/tmp/production.log', return => 'none' }, { method => 'level', argument => 'warn', return => 'none' } ] }, staging_log => { package => 'Mojo/Log', extends => 'development_log', }, testing_log => { package => 'Mojo/Log', extends => 'log', }, }; my $rewire = Rewire->new( services => $services );
This package supports extending services in the definition of other services, recursively compiling service configurations and eventually executing the requested compiled service.
use Rewire; my $services = { foo_sum => { package => 'Mojo/Util', function => 'md5_sum', argument => 'foo', } }; my $rewire = Rewire->new( services => $services, );
This package supports specifying construction as a function call, which when called does not provide an invocant.
use Rewire; my $metadata = { home => '/home/ubuntu' }; my $services = { tempfile => { package => 'Mojo/File', argument => { '$metadata' => 'home' }, lifecycle => 'singleton' } }; my $rewire = Rewire->new( services => $services, metadata => $metadata );
This package supports different lifecycle options which determine when services are built and whether they're persisted.
use Rewire; my $metadata = { homedir => '/home', tempdir => '/tmp' }; my $services = { home => { package => 'Mojo/Path', argument => { '$metadata' => 'homedir' }, }, temp => { package => 'Mojo/Path', argument => { '$metadata' => 'tempdir' }, } }; my $rewire = Rewire->new( services => $services, metadata => $metadata );
This package supports specifying data and structures which can be used in the construction of multiple services.
use Rewire; my $services = { mojo_url => { package => 'Mojo/URL', argument => 'https://perl.org', method => 'new' } }; my $rewire = Rewire->new( services => $services, );
This package supports specifying construction as a method call, which when called provides the package or object instance as the invocant.
use Rewire; my $services = { home => { package => 'Mojo/Path', argument => '/home', }, temp => { package => 'Mojo/Path', argument => '/tmp', } }; my $rewire = Rewire->new( services => $services ); # resolve services via method calls [ $rewire->home, # i.e. $rewire->process('home') $rewire->temp # i.e. $rewire->process('temp') ]
This package supports the resolution of services using a single method call. This is enabled by intercepting method calls and proxying them to the "process" method.
use Rewire; my $services = { mojo_url => { package => 'Mojo/URL', argument => 'https://perl.org', routine => 'new' } }; my $rewire = Rewire->new( services => $services, );
This package supports specifying construction as a function call, which when called provides the package as the invocant.
my $metadata = { home => '/home/ubuntu' }; my $services = { tempfile => { package => 'Mojo/File', argument => { '$metadata' => 'home' }, lifecycle => 'eager' } }; my $rewire = Rewire->new( services => $services, metadata => $metadata );
This package supports defining services to be constructed on-demand or automatically on instantiation.
This package has the following attributes:
context(CodeRef)
This attribute is read-only, accepts (CodeRef) values, and is optional.
(CodeRef)
engine(InstanceOf["Data::Object::Space"])
This attribute is read-only, accepts (InstanceOf["Data::Object::Space"]) values, and is optional.
(InstanceOf["Data::Object::Space"])
metadata(HashRef)
This attribute is read-only, accepts (HashRef) values, and is optional.
(HashRef)
services(HashRef)
This package implements the following methods:
config() : HashRef
The config method returns the configuration based on the services and metadata attributes.
# given: synopsis $rewire->config;
process(Str $name, Any $argument, Maybe[Str] $argument_as) : Any
The process method processes and returns an object or value based on the service named but where the arguments are provided ad-hoc. Note: This method is meant to be used to construct services ad-hoc and as such bypasses caching and lifecycle effects.
# given: synopsis $rewire->process('tempfile', 'rewire.tmp');
use Rewire; my $metadata = { logfile => '/var/log/rewire.log', }; my $services = { mojo_log => { package => 'Mojo/Log', argument => { '$metadata' => 'logfile' }, } }; my $rewire = Rewire->new( services => $services, metadata => $metadata ); $rewire->process('mojo_log', { level => 'fatal', path => { '$metadata' => 'logfile' } });
use Rewire; my $metadata = { logfile => '/var/log/rewire.log', }; my $services = { mojo_log => { package => 'Mojo/Log', builder => [ { method => 'new', return => 'self' } ] } }; my $rewire = Rewire->new( services => $services, metadata => $metadata ); $rewire->process('mojo_log', { level => 'fatal', path => { '$metadata' => 'logfile' } });
resolve(Str $name) : Any
The resolve method resolves and returns an object or value based on the service named. Note: This method is recommended to be used to construct services as defined by the configuration and as such doesn't not allow passing additional arguments.
# given: synopsis $rewire->resolve('tempfile');
use Rewire; my $services = { mojo_log => { package => 'Mojo/Log', argument => { level => 'fatal', path => '/var/log/rewire.log' }, } }; my $rewire = Rewire->new( services => $services, ); $rewire->resolve('mojo_log');
package Dynamic; sub import; sub AUTOLOAD { bless {}; } sub DESTROY { ; # noop } package main; use Rewire; my $services = { dynamic => { package => 'Dynamic', builder => [ { method => 'new', return => 'self' }, { method => 'missing_method', return => 'result' } ], } }; my $rewire = Rewire->new( services => $services, ); $rewire->resolve('dynamic');
validate() : Object
The validate method validates the configuration and throws an exception if invalid, otherwise returns itself.
# given: synopsis $rewire->validate;
Al Newkirk, awncorp@cpan.org
awncorp@cpan.org
Copyright (C) 2011-2019, Al Newkirk, et al.
This is free software; you can redistribute it and/or modify it under the terms of the The Apache License, Version 2.0, as elucidated in the "license file".
Wiki
Project
Initiatives
Milestones
Contributing
Issues
To install Rewire, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Rewire
CPAN shell
perl -MCPAN -e shell install Rewire
For more information on module installation, please visit the detailed CPAN module installation guide.