NAME
Venus::Factory - Factory Class
ABSTRACT
Factory Class for Perl 5
SYNOPSIS
package main;
use Venus::Factory;
my $factory = Venus::Factory->new;
# $factory->class('Venus::Path');
# $factory->build;
# bless(.., "Venus::Path")
DESCRIPTION
This package provides an object-oriented factory pattern and mechanism for building objects using dependency injection.
ATTRIBUTES
This package has the following attributes:
name
name(string $name) (string)
The name attribute is read/write, accepts (string) values, is optional, and defaults to undef.
Since 4.15
INHERITS
This package inherits behaviors from:
INTEGRATES
This package integrates behaviors from:
METHODS
This package provides the following methods:
args
args(any @args) (Any)
The args method accepts arguments and merges them with any "arrayref", "hashref", or "list" registered in the current configuration and returns the result. Returns a list in list context.
If an "arrayref" exists and the argment is an arrayref, the values are merged by appending the arguments provided to the end of the registered arrayref.
If a "hashref" exists and the argment is a hashref, the values are merged without overriding the keys and values from the registered hashref.
If a "list" exists and the argment is a list of values, the values are merged by appending the arguments provided to the end of the registered list.
Since 4.15
- args example 3
-
# given: synopsis package main; my $args = $factory->args({path => '/root'}); # {path => "/root"}
- args example 4
-
# given: synopsis package main; $factory->value({path => '/boot'}); my $args = $factory->args({path => '/root'}); # {path => "/root"}
- args example 5
-
# given: synopsis package main; $factory->value({path => '/boot'}); my $args = $factory->args; # {path => "/boot"}
- args example 6
-
# given: synopsis package main; $factory->value(name => 'example'); my @args = $factory->args; # ('name', 'example')
- args example 7
-
# given: synopsis package main; $factory->register('data.home')->value('/home'); $factory->register('data.root')->value('/root'); $factory->list('data.home', 'data.root'); my @args = $factory->args; # ('/home', '/root')
- args example 8
-
# given: synopsis package main; $factory->register('data.home')->value('/home'); $factory->register('data.root')->value('/root'); $factory->list('data.home', 'data.root'); my @args = $factory->args('/boot'); # ('/home', '/root', '/boot')
- args example 9
-
# given: synopsis package main; $factory->register('data.home')->value('/home'); $factory->register('data.root')->value('/root'); $factory->arrayref('data.home', 'data.root'); my $args = $factory->args; # ['/home', '/root']
- args example 10
-
# given: synopsis package main; $factory->register('data.home')->value('/home'); $factory->register('data.root')->value('/root'); $factory->arrayref('data.home', 'data.root'); my $args = $factory->args(['/boot']); # ['/home', '/root', '/boot']
- args example 11
-
# given: synopsis package main; $factory->register('data.home')->value('/home'); $factory->register('data.root')->value('/root'); $factory->hashref({home => 'data.home', root => 'data.root'}); my $args = $factory->args; # {home => '/home', root => '/root'}
- args example 12
-
# given: synopsis package main; $factory->register('data.home')->value('/home'); $factory->register('data.root')->value('/root'); $factory->hashref({home => 'data.home', root => 'data.root'}); my $args = $factory->args({boot => '/boot'}); # {home => '/home', root => '/root', boot => '/boot'}
arrayref
arrayref(arrayref $data) (arrayref)
The arrayref method modifies the current configuration and registers an arrayref where each value is a string or arrayref representing arguments to be passed to "build", each value is resolved and the resulting arrayref merged with the "value" upon resolution.
Since 4.15
- arrayref example 2
-
# given: synopsis; my $arrayref = $factory->arrayref('path'); # bless(..., "Venus::Factory")
- arrayref example 3
-
# given: synopsis; $factory->arrayref('path'); my $arrayref = $factory->arrayref; # ['path']
- arrayref example 4
-
# given: synopsis; my $arrayref = $factory->arrayref(['path', '/var/log'], ['path', '/tmp/log']); # bless(..., "Venus::Factory")
assert
assert(string $expr) (Venus::Factory)
The assert method modifies the current configuration and registers a type expression to be used to validate the resulting object upon resolution.
Since 4.15
- assert example 2
-
# given: synopsis; my $assert = $factory->assert('Example'); # bless(..., "Venus::Factory")
- assert example 3
-
# given: synopsis; $factory->assert('Example'); my $assert = $factory->assert; # "Example"
attach
attach(string $name, Venus::Factory $data) (Venus::Factory)
The attach method adds an existing "detached" container to the registry and returns container.
Since 4.15
- attach example 1
-
# given: synopsis package main; my $attach = $factory->attach; # bless(..., "Venus::Factory")
- attach example 2
-
# given: synopsis package main; my $attach = $factory->attach('path', Venus::Factory->new->class('Venus::Path')); # bless(..., "Venus::Factory")
builder
builder(coderef $callback) (coderef)
The builder method modifies the current configuration and registers a callback invoked during resolution which the resolved object is passed through. The return value of the callback will be returned by "resolve".
Since 4.15
- builder example 2
-
# given: synopsis; my $builder = $factory->builder(sub{}); # bless(..., "Venus::Factory")
- builder example 3
-
# given: synopsis; $factory->builder(sub{}); my $builder = $factory->builder; # sub{}
cache
cache(hashref $cache) (hashref)
The cache method gets and sets a store to be used by all derived containers where objects will be cached upon resolution.
Since 4.15
cached
cached(boolean $bool) (Venus::Factory)
The cached method modifies the current configuration and denotes that the object should be cached upon resolution.
Since 4.15
- cached example 2
-
# given: synopsis; my $cached = $factory->cached(true); # bless(..., "Venus::Factory")
callback
callback(any @args) (Venus::Factory)
The callback method modifies the current configuration and denotes that a coderef containing the resolved object should be returned upon resolution.
Since 4.15
- callback example 2
-
# given: synopsis; $factory->class('Venus::Path'); my $callback = $factory->callback('.'); # sub{...}
chain
chain(string | within[arrayref, string] @chain) (Venus::Factory)
The chain method method modifies the current configuration and registers a string or arrayref representing subsequent method calls to be chained upon resolution.
Since 4.15
- chain example 2
-
# given: synopsis; my $chain = $factory->chain('step_1'); # bless(..., "Venus::Factory")
- chain example 3
-
# given: synopsis; $factory->chain('step_1'); my $chain = $factory->chain; # ["step_1"]
- chain example 4
-
# given: synopsis; $factory->chain('step_1', 'step_2'); my $chain = $factory->chain; # ["step_1", "step_2"]
- chain example 5
-
# given: synopsis; $factory->chain('step_1', 'step_2', ['step_3', 1..4]); my $chain = $factory->chain; # ["step_1", "step_2", ["step_3", 1..4]]
class
class(string $class) (Venus::Factory)
The class method is shorthand for calling "package", "assert", and "method" with the argument "new".
Since 4.15
- class example 2
-
# given: synopsis; my $class = $factory->class('Venus::Path'); # bless(..., "Venus::Factory")
- class example 3
-
# given: synopsis; $factory->class('Venus::Path'); my $class = $factory->class; # "Venus::Path"
clone
clone() (Venus::Factory)
The clone method clones the current configuration and returns a container not attached to the registry.
Since 4.15
- clone example 1
-
# given: synopsis package main; my $clone = $factory->clone; # bless(..., "Venus::Factory")
- clone example 2
-
# given: synopsis package main; $factory->class('Venus::Path')->name('path'); my $clone = $factory->clone; # bless(..., "Venus::Factory")
- clone example 3
-
# given: synopsis package main; $factory->class('Venus::Path')->builder(sub{$_->absolute})->name('path'); my $clone = $factory->clone; # bless(..., "Venus::Factory")
constructor
constructor(any @data) (defined)
The constructor method modifies the current configuration and registers a callback invoked during resolution which is passed the package, if any, and the resolved dependencies (and/or arguments), if any. The return value of the callback will be considered the resolved object.
Since 4.15
- constructor example 2
-
# given: synopsis; my $constructor = $factory->constructor(sub{}); # bless(..., "Venus::Factory")
- constructor example 3
-
# given: synopsis; $factory->constructor(sub{}); my $constructor = $factory->constructor; # sub{}
detach
detach(string $name) (maybe[Venus::Factory])
The detach method removes an existing container from the registry and returns container. The detached container will still have access to the registry to resolve dependencies. To detach from the registry use "reset".
Since 4.15
- detach example 2
-
# given: synopsis package main; $factory->register('path')->class('Venus::Path'); my $detach = $factory->detach('path'); # bless(..., "Venus::Factory")
dispatch
dispatch(string $name) (Venus::Factory)
The dispatch method modifies the current configuration and denotes the subroutine that should be dispatched to upon resolution.
Since 4.15
- dispatch example 2
-
# given: synopsis; my $dispatch = $factory->dispatch('do_something'); # bless(..., "Venus::Factory")
- dispatch example 3
-
# given: synopsis; $factory->dispatch('do_something'); my $dispatch = $factory->dispatch; # "do_something"
extend
extend(string $name) (Venus::Factory)
The extend method copies the details of the configuration specified to the current configuration.
Since 4.15
- extend example 1
-
# given: synopsis; $factory->register('path')->class('Venus::Path'); my $extend = $factory->extend; # bless(..., "Venus::Factory")
- extend example 2
-
# given: synopsis; $factory->register('path')->class('Venus::Path'); my $extend = $factory->register('temp')->extend('path'); # bless(..., "Venus::Factory")
function
function(string $name) (Venus::Factory)
The function method modifies the current configuration and denotes that object resolution should result from a function call using the function name provided.
Since 4.15
- function example 2
-
# given: synopsis; my $function = $factory->function('do_something'); # bless(..., "Venus::Factory")
- function example 3
-
# given: synopsis; $factory->function('do_something'); my $function = $factory->function; # "do_something"
hashref
hashref(hashref $data) (hashref)
The hashref method modifies the current configuration and registers an hashref where each value is a string or arrayref representing arguments to be passed to "build", each value is resolved and the resulting hashref is merged with the "value" upon resolution.
Since 4.15
- hashref example 2
-
# given: synopsis; my $hashref = $factory->hashref({path => 'path'}); # bless(..., "Venus::Factory")
- hashref example 3
-
# given: synopsis; $factory->hashref({path => 'path'}); my $hashref = $factory->hashref; # {path => "path"}
- hashref example 4
-
# given: synopsis; $factory->hashref({ tmplog => ['path', '/tmp/log'], varlog => ['path', '/var/log'], }); my $hashref = $factory->hashref; # {tmplog => ["path", "/tmp/log"], varlog => ["path", "/var/log"]}
list
list(string | arrayref @data) (string | arrayref)
The list method modifies the current configuration and registers a sequence of values where each value is a string or arrayref representing arguments to be passed to "build", each value is resolved and the resulting list is merged with the "value" upon resolution.
Since 4.15
- list example 4
-
# given: synopsis; $factory->list(['path', '/var/log'], ['path', '/tmp/log']); my @list = $factory->list; # (['path', '/var/log'], ['path', '/tmp/log'])
method
method(string $name) (Venus::Factory)
The method method modifies the current configuration and denotes that object resolution should result from a method call using the method name provided.
Since 4.15
- method example 2
-
# given: synopsis; my $method = $factory->method('do_something'); # bless(..., "Venus::Factory")
- method example 3
-
# given: synopsis; $factory->method('do_something'); my $method = $factory->method; # "do_something"
new
new(hashref $data) (Venus::Factory)
The new method returns a Venus::Factory object.
Since 4.15
- new example 1
-
package main; use Venus::Factory; my $factory = Venus::Factory->new; # bless(..., "Venus::Factory")
package
package(string $name) (Venus::Factory)
The package method modifies the current configuration and denotes that object resolution should be derived from the package name provided.
Since 4.15
- package example 2
-
# given: synopsis; my $package = $factory->package('Example'); # bless(..., "Venus::Factory")
- package example 3
-
# given: synopsis; $factory->package('Example'); my $package = $factory->package; # "Example"
protocol
protocol(string $name) (Venus::Factory)
The protocol method modifies the current configuration and denotes the subroutine dispatch protocol that should be used upon resolution.
Since 4.15
- protocol example 2
-
# given: synopsis; my $protocol = $factory->protocol('method'); # bless(..., "Venus::Factory")
- protocol example 3
-
# given: synopsis; $factory->protocol('method'); my $protocol = $factory->protocol; # "method"
register
register(string $name) (Venus::Factory)
The register method registers and returns a new container (dependency resolver).
Since 4.15
- register example 1
-
# given: synopsis; my $register = $factory->register('path'); # bless(..., "Venus::Factory")
registry
registry(hashref $store) (hashref)
The registry method returns a hashref representing all registered containers.
Since 4.15
- registry example 2
-
# given: synopsis; my $registry = $factory->registry({}); # bless(..., "Venus::Factory")
- registry example 3
-
# given: synopsis; $factory->registry({}); my $registry = $factory->registry; # {}
reset
reset(string $name) (any)
The reset method resets a property of the current configuration based on the name provided. If no name is provided this method will reset all properties. If a property name is provided this method returned the value of the reset property. If no property name is provided this method returns the invocant.
Since 4.15
- reset example 1
-
# given: synopsis package main; my $reset = $factory->reset; # bless(..., "Venus::Factory")
- reset example 2
-
# given: synopsis package main; $factory->class('Venus::Path')->name('path'); my $reset = $factory->reset; # bless(..., "Venus::Factory")
- reset example 3
-
# given: synopsis package main; $factory->class('Venus::Path')->name('path'); my $reset = $factory->reset('assert'); # "Venus::Path"
- reset example 4
-
# given: synopsis package main; $factory->name('path'); $factory->class('Venus::Path'); # my $reset = $factory->reset('package'); # "Venus::Path"
resolve
resolve(any @args) (any)
The resolve method resolves the current configuration and returns the constructed object based on the configuration. Any arguments provided (or registered "values") are merged with any registered "arrayref", "hashref", or "list" values.
Since 4.15
- resolve example 1
-
# given: synopsis; $factory->class('Venus::Path'); my $resolve = $factory->resolve; # bless(..., "Venus::Path")
- resolve example 2
-
# given: synopsis; $factory->class('Venus::Path'); my $resolve = $factory->resolve('.'); # bless(..., "Venus::Path")
- resolve example 3
-
# given: synopsis; my $resolve = $factory->register('path')->class('Venus::Path')->resolve('.'); # bless(..., "Venus::Path")
- resolve example 4
-
# given: synopsis; $factory->class('Venus::Log'); my $resolve = $factory->resolve; # bless(..., "Venus::Log")
- resolve example 5
-
# given: synopsis; $factory->register('log')->class('Venus::Log'); my $resolve = $factory->resolve; # undef
- resolve example 6
-
# given: synopsis; my $resolve = $factory->register('date')->class('Venus::Date')->value(570672000)->resolve; # bless(..., "Venus::Date")
- resolve example 7
-
# given: synopsis; my $resolve = $factory->register('date') ->class('Venus::Date')->value({year => 1988, month => 2, day => 1})->resolve; # bless(..., "Venus::Date")
- resolve example 8
-
# given: synopsis; my $resolve = $factory->register('date') ->class('Venus::Date')->value(year => 1988, month => 2, day => 1)->resolve; # bless(..., "Venus::Date")
- resolve example 9
-
# given: synopsis; my $resolve = $factory->register('date') ->class('Venus::Date')->builder(sub{$_->mdy})->value(570672000) ->assert('string') ->resolve; # "02-01-1988"
- resolve example 10
-
# given: synopsis; my $resolve = $factory->register('greeting') ->class('Venus::String')->builder(sub{$_->titlecase}) ->assert('string') ->resolve('hello world'); # "Hello World"
- resolve example 11
-
# given: synopsis; $factory->register('string')->class('Venus::String')->assert('string'); my $string = $factory->retrieve('string'); $string->builder(sub{ my ($factory, $object) = @_; return $object->titlecase; }); my $resolve = $string->resolve('hello world'); # "Hello World"
- resolve example 12
-
# given: synopsis; my $resolve = $factory->register('md5')->package('Digest::MD5')->function('md5_hex')->resolve; # "d41d8cd98f00b204e9800998ecf8427e"
- resolve example 13
-
# given: synopsis; my $resolve = $factory->register('md5')->package('Digest::MD5')->function('md5_hex')->resolve('hello'); # "5d41402abc4b2a76b9719d911017c592"
- resolve example 14
-
# given: synopsis; $factory->cache({}); my $secret = $factory->register('secret')->cached(true)->package('Digest::MD5')->function('md5_hex'); # $secret->resolve(rand); # "fa95053a9a204800ced194ffa3fc84bc" # $secret->resolve(rand); # "fa95053a9a204800ced194ffa3fc84bc"
- resolve example 15
-
# given: synopsis; my $error = $factory->register('error')->class('Venus::Error'); $error->constructor(sub{ my ($factory, $package, $method, @args) = @_; return $package->$method(@args)->do('name', 'on.factory.build'); }); $error->resolve; # bless(..., "Venus::Error")
- resolve example 16
-
# given: synopsis; my $resolve = $factory->register('data.home')->value('/root')->resolve; # "/root"
- resolve example 17
-
# given: synopsis; my $resolve = $factory ->register('data.home')->value('/root') ->register('path.home')->class('Venus::Path')->list('data.home') ->resolve; # bless(..., "Venus::Path")
retrieve
retrieve(string $name) (Venus::Factory)
The retrieve method returns a registered container (dependency resolver) using the name provided. If no argument is provided the invocant is returned.
Since 4.15
- retrieve example 1
-
# given: synopsis; $factory->register('path')->class('Venus::Path'); my $retrieve = $factory->retrieve; # bless(..., "Venus::Factory")
- retrieve example 2
-
# given: synopsis; $factory->register('path')->class('Venus::Path'); my $retrieve = $factory->retrieve('path'); # bless(..., "Venus::Factory")
routine
routine(string $name) (Venus::Factory)
The routine method modifies the current configuration and denotes that object resolution should result from a routine call (or package call) using the subroutine name provided.
Since 4.15
- routine example 2
-
# given: synopsis; my $routine = $factory->routine('do_something'); # bless(..., "Venus::Factory")
- routine example 3
-
# given: synopsis; $factory->routine('do_something'); my $routine = $factory->routine; # "do_something"
value
value(any @data) (any)
The value method method modifies the current configuration and registers value(s) to be provided to the "method", "function", or "routine" upon resolution.
Since 4.15
- value example 2
-
# given: synopsis; my $value = $factory->value('hello world'); # bless(..., "Venus::Factory")
- value example 3
-
# given: synopsis; $factory->value('hello world'); my @value = $factory->value; # ("hello world")
- value example 4
-
# given: synopsis; $factory->value({value => 'hello world'}); my @value = $factory->value; # ({value => 'hello world'})
AUTHORS
Awncorp, awncorp@cpan.org
LICENSE
Copyright (C) 2022, Awncorp, awncorp@cpan.org.
This program is free software, you can redistribute it and/or modify it under the terms of the Apache license version 2.0.