1# PODNAME: Bread::Board::Manual::Concepts::Typemap 2# ABSTRACT: An overview of the typemapping feature 3 4__END__ 5 6=pod 7 8=encoding UTF-8 9 10=head1 NAME 11 12Bread::Board::Manual::Concepts::Typemap - An overview of the typemapping feature 13 14=head1 VERSION 15 16version 0.37 17 18=head1 INTRODUCTION 19 20A new (read: experimental) feature of Bread::Board is typemapped services. 21These are services which are mapped to a particular type rather then just 22a name. This feature has the potential to make obsolete a large amount of the 23Bread::Board configuration by simply asking Bread::Board to figure things 24out on its own. Here is a small example of how this works. 25 26 # define the classes making sure 27 # to specify required items and 28 # their types 29 30 { 31 package Stapler; 32 use Moose; 33 34 package Desk; 35 use Moose; 36 37 package Chair; 38 use Moose; 39 40 package Cubicle; 41 use Moose; 42 43 has 'desk' => ( is => 'ro', isa => 'Desk', required => 1 ); 44 has 'chair' => ( is => 'ro', isa => 'Chair', required => 1 ); 45 46 package Employee; 47 use Moose; 48 49 has [ 'first_name', 'last_name' ] => ( 50 is => 'ro', 51 isa => 'Str', 52 required => 1, 53 ); 54 55 has 'stapler' => ( is => 'rw', isa => 'Stapler', predicate => 'has_stapler' ); 56 57 has 'work_area' => ( is => 'ro', isa => 'Cubicle', required => 1 ); 58 } 59 60 # now create the container, and 61 # map the Employee type and ask 62 # Bread::Board to infer all the 63 # other relationships 64 65 my $c = container 'Initech' => as { 66 typemap 'Employee' => infer; 67 }; 68 69 # now you can create new Employee objects 70 # by calling ->resolve with the type and 71 # supplying the required parameters (see 72 # below for details). 73 74 my $micheal = $c->resolve( 75 type => 'Employee', 76 parameters => { 77 first_name => 'Micheal', 78 last_name => 'Bolton' 79 } 80 ); 81 82 my $cube = $micheal->work_area; # this will be a Cubicle object 83 $cube->desk; # this will be a Desk object 84 $cube->chair; # this will be a Chair object 85 86 $micheal->has_stapler; # this is false 87 88 # We can create another Employee object 89 # and this time we pass in the optional 90 # parameter for the non-required 'stapler' 91 # attribute 92 93 my $milton = $c->resolve( 94 type => 'Employee', 95 parameters => { 96 first_name => 'Milton', 97 last_name => 'Waddams', 98 stapler => Stapler->new 99 } 100 ); 101 102 $milton->has_stapler; # this is true 103 104In the above example, we created a number of Moose classes that had 105specific required relationships. When we called C<infer> for the 106B<Employee> object, Bread::Board figured out those relationships 107and set up dependencies and parameters accordingly. 108 109For the C<work_area> object, we saw the B<Cubicle> type and then 110basically called C<infer> on the B<Cubicle> object. We then saw 111the B<Desk> and B<Chair> objects and called C<infer> on those as well. 112The result of this recursive inference was that the B<Employee>, 113B<Cubicle>, B<Desk> and B<Chair> relationships were modeled in 114Bread::Board as dependent services. 115 116Bread::Board also took it one step further. 117 118We were able to resolve the B<Cubicle>, B<Desk> and B<Chair> types 119automatically because they were already defined by Moose as subtypes 120of the I<Object> type. We knew that it could introspect those classes 121and get more information. However, this was not the case with the 122I<first_name> and I<last_name> attributes of the B<Employee> object. 123In that case, we determined that we couldn't resolve those objects and 124(because it was a top-level inference) instead turned them into required 125parameters for the inferred B<Employee> service. 126 127And lastly, with a top-level inference (not one caused by recursion) 128Bread::Board will also look at all the remaining non-required attributes 129and turn them into optional parameters. In this case we have a C<stapler> 130attribute that is not required and so is listed as an optional parameter, 131meaning that it is not required, but still subject to type checking. 132 133=head1 CONCLUSION 134 135This example should give a good basic overview of this feature and more 136details can be found in the test suite (F<t/07*.t>). These show examples 137of how to typemap roles to concrete classes and how to supply hints to 138C<infer> to help Bread::Board figure out specific details. 139 140As I mentioned above, this feature should be considered experimental 141and we are still working out details and writing tests for it. Any 142contributions are welcome. 143 144=head1 AUTHOR 145 146Stevan Little <stevan@iinteractive.com> 147 148=head1 BUGS 149 150Please report any bugs or feature requests on the bugtracker website 151https://github.com/stevan/BreadBoard/issues 152 153When submitting a bug or request, please include a test-file or a 154patch to an existing test-file that illustrates the bug or desired 155feature. 156 157=head1 COPYRIGHT AND LICENSE 158 159This software is copyright (c) 2019, 2017, 2016, 2015, 2014, 2013, 2011, 2009 by Infinity Interactive. 160 161This is free software; you can redistribute it and/or modify it under 162the same terms as the Perl 5 programming language system itself. 163 164=cut 165