.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Bread::Board::Container 3pm" .TH Bread::Board::Container 3pm "2022-12-12" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Bread::Board::Container \- A container for services and other containers .SH "VERSION" .IX Header "VERSION" version 0.37 .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 7 \& use Bread::Board; \& my $c = container MCP => as { \& container Users => as { \& service flynn => ...; \& service bradley => ...; \& service dillinger => ...; \& }; \& \& container Programs => as { \& container Rebels => as { \& service tron => ...; \& service yori => ...; \& alias flynn => \*(Aq/Users/flynn\*(Aq; \& }; \& \& # nested container \& container Slaves => as { \& service sark => ...; \& service crom => ...; \& }; \& }; \& }; \& \& # OR directly... \& my $guardians => Bread::Board::Container\->new( name => \*(AqGuardians\*(Aq ); \& $guardians\->add_service( \& Bread::Board::ConstructorInjection\->new( \& name => \*(Aqdumont\*(Aq, \& ..., \& ) \& ); \& $c\->get_sub_container(\*(AqPrograms\*(Aq)\->add_sub_container($guardians); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This class implements the container for Bread::Board: a container is a thing that contains services and other containers. Each container and service has a name, so you end up with a tree of named nodes, just like files and directories in a filesystem: each item can be referenced using a path (see Bread::Board::Traversable for the details). .SH "ATTRIBUTES" .IX Header "ATTRIBUTES" .ie n .SS """name""" .el .SS "\f(CWname\fP" .IX Subsection "name" Read/write string, required. Every container needs a name, by which it can be referenced when fetching it. .ie n .SS """services""" .el .SS "\f(CWservices\fP" .IX Subsection "services" Hashref, constrained by \f(CW\*(C`Bread::Board::Container::ServiceList\*(C'\fR, mapping names to services directly contained in this container. Every service added here will have its \f(CW\*(C`parent\*(C'\fR set to this container. .PP You can pass an arrayref of services instead of a hashref, the keys will be the names of the services. .PP You should probably use \*(L"add_service\*(R" and \*(L"get_service\*(R" to manipulate this attribute, instead of modifying it directly. .ie n .SS """sub_containers""" .el .SS "\f(CWsub_containers\fP" .IX Subsection "sub_containers" Hashref, constrained by \f(CW\*(C`Bread::Board::Container::SubContainerList\*(C'\fR, mapping names to containers directly contained in this container. Every container added here will have its \f(CW\*(C`parent\*(C'\fR set to this container. .PP You can pass an arrayref of containers instead of a hashref, the keys will be the names of the containers. .PP You should probably use \*(L"add_sub_container\*(R" and \&\*(L"get_sub_container\*(R" to manipulate this attribute, instead of modifying it directly. .PP Containers added here can either be normal Bread::Board::Container or Bread::Board::Container::Parameterized. .SH "METHODS" .IX Header "METHODS" .ie n .SS """add_service""" .el .SS "\f(CWadd_service\fP" .IX Subsection "add_service" .Vb 1 \& $container\->add_service($service); .Ve .PP Adds a service into the \*(L"services\*(R" map, using its name as the key. .ie n .SS """get_service""" .el .SS "\f(CWget_service\fP" .IX Subsection "get_service" .Vb 1 \& my $service = $container\->get_service($name); .Ve .PP Returns a service by name, or \f(CW\*(C`undef\*(C'\fR if there's no such service in the \*(L"services\*(R" map. .ie n .SS """has_service""" .el .SS "\f(CWhas_service\fP" .IX Subsection "has_service" .Vb 1 \& if ($container\->has_service($name)) { ... } .Ve .PP Returns true if a service with the given name name exists in the \&\*(L"services\*(R" map, false otherwise. .ie n .SS """has_services""" .el .SS "\f(CWhas_services\fP" .IX Subsection "has_services" .Vb 1 \& if ($container\->has_services) { ... } .Ve .PP Returns true if the \*(L"services\*(R" map contains any services, false if it's empty. .ie n .SS """get_service_list""" .el .SS "\f(CWget_service_list\fP" .IX Subsection "get_service_list" .Vb 1 \& my @service_names = $container\->get_service_list(); .Ve .PP Returns the names off all services present in the \*(L"services\*(R" map. .ie n .SS """add_sub_container""" .el .SS "\f(CWadd_sub_container\fP" .IX Subsection "add_sub_container" .Vb 1 \& $container\->add_sub_container($container); .Ve .PP Adds a container into the \*(L"sub_containers\*(R" map, using its name as the key. .ie n .SS """get_sub_container""" .el .SS "\f(CWget_sub_container\fP" .IX Subsection "get_sub_container" .Vb 1 \& my $container = $container\->get_sub_container($name); .Ve .PP Returns a container by name, or \f(CW\*(C`undef\*(C'\fR if there's no such container in the \*(L"sub_containers\*(R" map. .ie n .SS """has_sub_container""" .el .SS "\f(CWhas_sub_container\fP" .IX Subsection "has_sub_container" .Vb 1 \& if ($container\->has_sub_container($name)) { ... } .Ve .PP Returns true if a container with the given name name exists in the \&\*(L"sub_containers\*(R" map, false otherwise. .ie n .SS """has_sub_containers""" .el .SS "\f(CWhas_sub_containers\fP" .IX Subsection "has_sub_containers" .Vb 1 \& if ($container\->has_sub_containers) { ... } .Ve .PP Returns true if the \*(L"sub_containers\*(R" map contains any contains, false if it's empty. .ie n .SS """get_sub_container_list""" .el .SS "\f(CWget_sub_container_list\fP" .IX Subsection "get_sub_container_list" .Vb 1 \& my @container_names = $container\->get_sub_container_list(); .Ve .PP Returns the names off all containers present in the \*(L"sub_containers\*(R" map. .ie n .SS """add_type_mapping_for""" .el .SS "\f(CWadd_type_mapping_for\fP" .IX Subsection "add_type_mapping_for" .Vb 1 \& $containers\->add_type_mapping_for( $type_name, $service ); .Ve .PP Adds a mapping from a Moose type to a service: whenever we try to \*(L"resolve\*(R" that type, we'll use that service to instantiate it. .ie n .SS """get_type_mapping_for""" .el .SS "\f(CWget_type_mapping_for\fP" .IX Subsection "get_type_mapping_for" .Vb 1 \& my $service = $container\->get_type_mapping_for( $type_name ); .Ve .PP Returns the service to use to instantiate the given type name. .PP Important: if a mapping for the exact type can't be found, but a mapping for a \fIsubtype\fR of it can, you'll get the latter instead: .PP .Vb 2 \& package Superclass { use Moose }; \& package Subclass { use Moose; exends \*(AqSuperclass\*(Aq }; \& \& $c\->add_type_mapping_for( \& \*(AqSubclass\*(Aq, \& Bread::Board::ConstructorInjection\->new(name=>\*(Aqsc\*(Aq,class=>\*(AqSubclass\*(Aq), \& ); \& my $o = $c\->get_type_mapping_for(\*(AqSuperclass\*(Aq)\->get; .Ve .PP \&\f(CW$o\fR is an instance of \f(CW\*(C`Subclass\*(C'\fR. If there are more than one sub-type mapped, you get a random one. This is probably a bad idea. .ie n .SS """has_type_mapping_for""" .el .SS "\f(CWhas_type_mapping_for\fP" .IX Subsection "has_type_mapping_for" .Vb 1 \& if ($container\->has_type_mapping_for( $type_name )) { ... } .Ve .PP Returns true if we have a service defined to instantiate the given type name, but see the note on \&\*(L"get_type_mapping_for\*(R" about subtype mapping. .ie n .SS """resolve""" .el .SS "\f(CWresolve\fP" .IX Subsection "resolve" .Vb 2 \& my $object = $container\->resolve(service=>$service_name); \& my $object = $container\->resolve(service=>$service_name,parameters=>\e%p); .Ve .PP When given a service name, this method will fetch the service, then call \f(CW\*(C`get\*(C'\fR on it, optionally passing the given parameters. .PP .Vb 2 \& my $object = $container\->resolve(type=>$type); \& my $object = $container\->resolve(type=>$type,parameters=>\e%p); .Ve .PP When given a type name, this method will use \&\*(L"get_type_mapping_for\*(R" to get the service, then call \f(CW\*(C`get\*(C'\fR on it, optionally passing the given parameters. If the instance is not of the expected type, the method will die. .SH "AUTHOR" .IX Header "AUTHOR" Stevan Little .SH "BUGS" .IX Header "BUGS" Please report any bugs or feature requests on the bugtracker website https://github.com/stevan/BreadBoard/issues .PP When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature. .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This software is copyright (c) 2019, 2017, 2016, 2015, 2014, 2013, 2011, 2009 by Infinity Interactive. .PP This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.