blob: d1d638507cd46abb9087227ecd46b6b924a83347 (
plain) (
tree)
|
|
use v6;
class Bread::Board::Container {...}
class Bread::Board::Dependency {...}
role Bread::Board::Service {
has Str $.name;
has Bread::Board::Container $.parent is rw = Bread::Board::Container;
# XXX not sure how to make these optional - specifying the types here
# makes it fail when the parameters aren't passed
# shouldn't the " = {}" part be taking care of that?
# has Hash of Bread::Board::Dependency $.dependencies = {};
has $.dependencies = {};
# XXX overriding new here is an extremely suboptimal solution
# does perl 6 have anything like moose's coercions?
method new (*%params is copy) {
if %params.<dependencies> {
my $deps = {};
for %params.<dependencies>.keys -> $name {
my $dep = %params.<dependencies>.{$name};
$deps.{$name} = $dep.isa(Bread::Board::Dependency)
?? $dep
!! Bread::Board::Dependency.new(service => $dep);
}
%params.<dependencies> = $deps;
}
nextwith(|%params);
}
method get {*};
method get_dependency ($name) {
return $.dependencies.{$name};
}
}
role Bread::Board::HasParameters {
# XXX not sure how to make these optional - specifying the types here
# makes it fail when the parameters aren't passed
# shouldn't the " = {}" part be taking care of that?
# has Hash of Hash $.parameters = {};
has $.parameters = {};
method check_parameters (%params) {
for $.parameters.keys -> $name {
if not %params.{$name}:exists {
die "Required parameter $name not given";
}
}
for %params.keys -> $name {
if not $.parameters.{$name}:exists {
die "Unknown parameter $name given";
}
if not %params.{$name}.isa($.parameters.{$name}.<isa>) {
die "{%params.{$name}.perl} is not a valid value for the $name parameter";
}
}
# XXX why is this return necessary?
return;
}
}
class Bread::Board::Dependency {
has Bread::Board::Service $.service handles 'get';
}
class Bread::Board::ConstructorInjection
does Bread::Board::Service
does Bread::Board::HasParameters {
has $.class;
has Str $.constructor_name is rw = 'new';
method get (*%params is copy) {
# XXX remove more duplication?
self.check_parameters(%params);
for $.dependencies.keys -> $name {
%params{$name} = $.dependencies{$name}.get;
}
return $.class."$.constructor_name"(|%params);
}
}
class Bread::Board::Parameters {
has Hash $.params;
# XXX do we really want to keep this API?
has $.class;
method param (Str $name) {
return $.params.{$name};
}
}
class Bread::Board::BlockInjection
does Bread::Board::Service
does Bread::Board::HasParameters {
has Callable $.block;
has $.class = Any;
method get (*%params is copy) {
# XXX remove more duplication?
self.check_parameters(%params);
for $.dependencies.keys -> $name {
%params{$name} = $.dependencies{$name}.get;
}
return $.block.(
Bread::Board::Parameters.new(
params => %params,
class => $.class,
)
);
}
}
class Bread::Board::Literal does Bread::Board::Service {
has $.value;
method get {
return $.value;
}
}
class Bread::Board::Container {
has Str $.name;
has Bread::Board::Container $.parent is rw = Bread::Board::Container;
# XXX again, as above
# has Hash of Bread::Board::Container $.sub_containers = {};
# has Hash of Bread::Board::Service $.services = {};
has $.sub_containers = {};
has $.services = {};
# XXX again, as above
method new (*%params is copy) {
if %params.<sub_containers>.isa(Array) {
%params.<sub_containers> = %params.<sub_containers>.map(-> $c { $c.name => $c }).hash;
}
if %params.<services>.isa(Array) {
%params.<services> = %params.<services>.map(-> $c { $c.name => $c }).hash;
}
my $container = callwith(|%params);
if %params.<sub_containers>:exists {
for %params.<sub_containers>.values -> $c {
$c.parent = $container;
}
}
if %params.<services>:exists {
for %params.<services>.values -> $c {
$c.parent = $container;
}
}
return $container;
}
method add_sub_container (Bread::Board::Container $c) {
$.sub_containers.{$c.name} = $c;
$c.parent = self;
}
method get_sub_container (Str $name) {
return $.sub_containers.{$name};
}
method has_services {
return $.services > 0;
}
method get_service (Str $name) {
return $.services.{$name};
}
}
|