Bread-Board
view release on metacpan or search on metacpan
lib/Bread/Board/Dependency.pm view on Meta::CPAN
has 'service' => (
is => 'ro',
does => 'Bread::Board::Service | Bread::Board::Dependency',
lazy => 1,
default => sub {
my $self = shift;
($self->has_service_path)
|| confess "Could not fetch service without service path";
$self->fetch($self->service_path);
},
handles => [ 'get', 'is_locked', 'lock', 'unlock' ]
);
__PACKAGE__->meta->make_immutable;
no Moose; 1;
__END__
=pod
lib/Bread/Board/Dependency.pm view on Meta::CPAN
L</service_path>.
=head1 METHODS
=head2 C<has_service_path>
Predicate for the L</service_path> attribute.
=head2 C<get>
=head2 C<is_locked>
=head2 C<lock>
=head2 C<unlock>
These methods are delegated to the L</service>.
=head1 AUTHOR
Stevan Little <stevan@iinteractive.com>
lib/Bread/Board/Service.pm view on Meta::CPAN
builder => 'init_params',
clearer => 'clear_params',
handles => {
get_param => 'get',
get_param_keys => 'keys',
_clear_param => 'delete',
_set_param => 'set',
}
);
has 'is_locked' => (
is => 'rw',
isa => 'Bool',
default => sub { 0 }
);
has 'lifecycle' => (
is => 'rw',
isa => 'Str',
trigger => sub {
my ($self, $lifecycle) = @_;
lib/Bread/Board/Service.pm view on Meta::CPAN
}
}
}
$self->clone(%params);
}
}
requires 'get';
sub lock { (shift)->is_locked(1) }
sub unlock { (shift)->is_locked(0) }
no Moose::Util::TypeConstraints; no Moose::Role; 1;
__END__
=pod
=encoding UTF-8
=head1 NAME
lib/Bread/Board/Service.pm view on Meta::CPAN
building blocks: creating an instance, setting/getting parameters,
instance lifecycle.
=head1 ATTRIBUTES
=head2 C<name>
Read/write string, required. Every service needs a name, by which it
can be referenced when L<fetching it|Bread::Board::Traversable/fetch>.
=head2 C<is_locked>
Boolean, defaults to false. Used during L<dependency
resolution|Bread::Board::Service::WithDependencies/resolve_dependencies>
to detect loops.
=head2 C<lifecycle>
$service->lifecycle('Singleton');
Read/write string; it should be either a partial class name under the
lib/Bread/Board/Service/WithDependencies.pm view on Meta::CPAN
my %deps;
if ($self->has_dependencies) {
foreach my $dep ($self->get_all_dependencies) {
my ($key, $dependency) = @$dep;
my $service = $dependency->service;
# NOTE:
# this is what checks for
# circular dependencies
if ($service->is_locked) {
confess "You cannot defer a parameterized service"
if $service->does('Bread::Board::Service::WithParameters')
&& $service->has_parameters;
$deps{$key} = Bread::Board::Service::Deferred->new(service => $service);
}
else {
# since we can't pass in parameters here,
# we return a deferred thunk and you can do
lib/Bread/Board/Service/WithDependencies.pm view on Meta::CPAN
my %name_object_map = $self->resolve_dependencies;
For each element of L</dependencies>, calls its L<<
C<service>|Bread::Board::Dependency/service >> method to retrieve the
service we're dependent on, then tries to instantiate the value of the
service. This can happen in a few different ways:
=over 4
=item the service is not locked, and does not require any parameter
just call C<get> on it
=item the service is not locked, requires parameters, but the dependency has values for them
call C<< $service->get(%{$dependency->service_params}) >>
=item the service is not locked, requires parameters, and we don't have values for them
we can't instantiate anything at this point, so we use a
L<Bread::Board::Service::Deferred::Thunk> instance, on which you can
call the C<inflate> method, passing it all the needed parameters, to
get the actual instance
=item the service is locked
we return a L<Bread::Board::Service::Deferred> that will proxy to the
instance that the service will eventually return; yes, this means that
in many cases circular dependencies can be resolved, at the cost of a
proxy object
=back
=head1 AUTHOR
( run in 1.512 second using v1.01-cache-2.11-cpan-49f99fa48dc )