File Coverage

blib/lib/MooX/PluginKit/Factory.pm
Criterion Covered Total %
statement 35 36 97.2
branch 2 4 50.0
condition 0 3 0.0
subroutine 10 10 100.0
pod 2 2 100.0
total 49 55 89.0


line stmt bran cond sub pod time code
1             package MooX::PluginKit::Factory;
2              
3             our $VERSION = '0.05';
4              
5             =head1 NAME
6              
7             MooX::PluginKit::Factory - Dynamically apply plugins to classes at runtime.
8              
9             =head1 SYNOPSIS
10              
11             use MooX::PluginKit::Factory;
12            
13             my $kit = MooX::PluginKit::Factory->new(
14             plugins => [...],
15             namespace => ...,
16             );
17            
18             my $object = $kit->class_new('Some::Class', %args);
19              
20             =head1 DESCRIPTION
21              
22             A PluginKit factory takes a list of plugins and then provides methods
23             for applying those plugins to classes and building objects from those classes.
24              
25             Unless you are a power user you are better off using
26             L.
27              
28             =cut
29              
30 3     3   20 use MooX::PluginKit::Core;
  3         6  
  3         256  
31 3     3   1478 use Types::Standard -types;
  3         192704  
  3         29  
32 3     3   13822 use Types::Common::String -types;
  3         60606  
  3         37  
33 3     3   4151 use Module::Runtime qw( require_module );
  3         8  
  3         23  
34              
35 3     3   130 use Moo;
  3         7  
  3         24  
36 3     3   1388 use strictures 2;
  3         23  
  3         123  
37 3     3   621 use namespace::clean;
  3         7  
  3         20  
38              
39             =head1 ARGUMENTS
40              
41             =head2 plugins
42              
43             An array ref of plugin names (relative or absolute).
44              
45             =cut
46              
47             has plugins => (
48             is => 'ro',
49             isa => ArrayRef[ NonEmptySimpleStr ],
50             default => sub{ [] },
51             );
52              
53             =head2 namespace
54              
55             The namespace to resolve relative plugin names to.
56              
57             =cut
58              
59             has namespace => (
60             is => 'ro',
61             isa => NonEmptySimpleStr,
62             );
63              
64             =head1 ATTRIBUTES
65              
66             =head2 resolved_plugins
67              
68             L with all relative plugin names resolved.
69              
70             =cut
71              
72             has resolved_plugins => (
73             is => 'lazy',
74             init_arg => undef,
75             );
76             sub _build_resolved_plugins {
77 28     28   236 my ($self) = @_;
78              
79             return [
80 12         79 map { resolve_plugin( $_, $self->namespace() ) }
81 28         48 @{ $self->plugins() }
  28         147  
82             ];
83             }
84              
85             =head1 METHODS
86              
87             =head2 build_class
88              
89             my $new_class = $kit->build_class( $class );
90              
91             Creates a new class with all applicable L applied to it
92             and returns the new class name.
93              
94             =cut
95              
96             sub build_class {
97 29     29 1 69 my ($self, $base_class) = @_;
98              
99             return build_class_with_plugins(
100             $base_class,
101 29         49 @{ $self->resolved_plugins() },
  29         505  
102             );
103             }
104              
105             =head2 class_new
106              
107             my $object = $kit->class_new( $class, %args );
108              
109             Calls L and then creates an object of that class.
110             If the class to be built is a plugin consumer then
111             L will be defaulted
112             to this factory.
113              
114             =cut
115              
116             sub class_new {
117 11     11 1 32 my $self = shift;
118 11         21 my $base_class = shift;
119              
120 11         30 my $class = $self->build_class( $base_class );
121 11 50       3740 require_module $class if !$class->can('new');
122 11         73 my $args = $class->BUILDARGS( @_ );
123              
124 11 50       127 if (is_consumer $class) {
125 0   0     0 $args->{plugin_factory} ||= $self;
126             }
127              
128 11         41 return $class->new( $args );
129             }
130              
131             1;
132             __END__