Skip to content

Commit

Permalink
Made object registration more strict
Browse files Browse the repository at this point in the history
  • Loading branch information
vti committed Aug 26, 2011
1 parent d82c997 commit 1e8af83
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 66 deletions.
47 changes: 18 additions & 29 deletions lib/Cole.pm
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ use warnings;
our $VERSION = '0.009001';

require Carp;

use Class::Load ();
use Scalar::Util ();
use Class::Load ();

sub new {
my $class = shift;
Expand All @@ -21,20 +19,13 @@ sub new {

sub register {
my $self = shift;
my $key = shift;
my ($key, $args) = @_;

Carp::croak('Service name is required') unless $key;
Carp::croak('Service args are required and must be a hashref')
unless $args && ref $args eq 'HASH';

if (@_ == 1 && !(ref($_[0]) eq 'HASH')) {
my $type =
Scalar::Util::blessed($_[0]) ? 'instance'
: ref($_[0]) eq 'CODE' ? 'block'
: 'constant';
$self->{services}->{$key}->{$type} = $_[0];
return $self;
}

$self->{services}->{$key} = @_ == 1 ? $_[0] : {@_};
$self->{services}->{$key} = {%{$args}}; # Shallow copy

return $self;
}
Expand All @@ -45,8 +36,8 @@ sub get {

my $service = $self->_get($key);

if (exists $service->{instance}) {
return $service->{instance};
if (exists $service->{value}) {
return $service->{value};
}
elsif (exists $service->{block}) {
my %args = $self->_build_deps($service);
Expand Down Expand Up @@ -85,7 +76,7 @@ sub _build_service {
my $self = shift;
my ($service) = @_;

return $service->{constant} if exists $service->{constant};
return $service->{value} if exists $service->{value};

Class::Load::load_class($service->{class});

Expand All @@ -106,8 +97,8 @@ sub _build_deps {
my ($key, $value) = ($dep, $dep);

if (ref $dep eq 'HASH') {
$key = (keys(%$dep))[0];
$value = (values(%$dep))[0];
$key = (values(%$dep))[0];
$value = (keys(%$dep))[0];
}

$args{$key} = $self->get($value);
Expand Down Expand Up @@ -147,25 +138,23 @@ L<Cole> is a lightweight Dependency Injection container.
=head1 FEATURES
=head2 C<Constants>
=head2 C<Values>
$ioc->register('string' => 'Hello world!');
$ioc->register(string => {value => 'Hello world!'});
$ioc->register(instance => {value => Foo->new});
=head2 C<Class names>
$ioc->register('class' => {class => 'Foo'});
=head2 C<Instances>
$ioc->register('class' => Foo->new);
$ioc->register(class => {class => 'Foo'});
=head2 C<Dependencies>
$ioc->register('class' => {class => 'Foo', deps => 'bar'});
$ioc->register(class => {class => 'Foo', deps => 'bar'});
=head2 C<Aliases>
$ioc->register('class' => {class => 'Foo', deps => {'bar' => 'baz'}});
$ioc->register(bar => {class => 'Bar'});
$ioc->register(class => {class => 'Foo', deps => {bar => 'baz'}});
C<bar> is passed as C<baz> during C<Foo> creation.
Expand All @@ -177,7 +166,7 @@ C<bar> is passed as C<baz> during C<Foo> creation.
=head2 C<register>
$ioc->register('name' => {class => 'foo'});
$ioc->register(name => {class => 'foo'});
Register a new dependency.
Expand Down
73 changes: 36 additions & 37 deletions t/cole.t
Original file line number Diff line number Diff line change
Expand Up @@ -17,91 +17,92 @@ describe "IOC" => sub {
};

it "should hold services" => sub {
$ioc->register('foo', class => 'Foo');

isa_ok($ioc->get('foo'), 'Foo');
};

it "should accept hash references" => sub {
$ioc->register('foo', {class => 'Foo'});
$ioc->register(foo => {class => 'Foo'});

isa_ok($ioc->get('foo'), 'Foo');
};

it "should hold constants" => sub {
$ioc->register('foo', 'Foo');
$ioc->register(foo => {value => 'hello'});

is($ioc->get('foo'), 'Foo');
is($ioc->get('foo'), 'hello');
};

it "should accept instance as a service" => sub {
$ioc->register('foo', Foo->new);
$ioc->register(foo => {value => Foo->new});

isa_ok($ioc->get('foo'), 'Foo');
};

it "should return all services on get_all" => sub {
my $service1 = Foo->new;
$ioc->register('foo', $service1);
$ioc->register(foo => {value => $service1});
my $service2 = Foo->new;
$ioc->register('bar', $service2);
$ioc->register(bar => {value => $service2});

is_deeply([$ioc->get_all], [bar => $service2, foo => $service1,]);
};

it "should resolve single dependency" => sub {
$ioc->register('foo', class => 'Foo');
$ioc->register('bar', class => 'Bar', deps => 'foo');
$ioc->register(foo => {class => 'Foo'});
$ioc->register(bar => {class => 'Bar', deps => 'foo'});

isa_ok($ioc->get('bar')->foo, 'Foo');
};

it "should resolve multiple dependencies" => sub {
$ioc->register('foo', 'Foo');
$ioc->register('bar', class => 'Bar', deps => 'foo');
$ioc->register('baz', class => 'Baz', deps => ['foo', 'bar']);
$ioc->register(foo => {value => 'Foo'});
$ioc->register(bar => {class => 'Bar', deps => 'foo'});
$ioc->register(baz => {class => 'Baz', deps => ['foo', 'bar']});

isa_ok($ioc->get('baz')->foo, 'Foo');
isa_ok($ioc->get('baz')->bar, 'Bar');
};

it "should resolve dependecy and pass it as other name" => sub {
$ioc->register('some name', 'Foo');
$ioc->register(name => {value => 'foo'});
$ioc->register(
'zzz',
class => 'Bar',
deps => {foo => 'some name'}
zzz => {
class => 'Bar',
deps => {name => 'foo'}
}
);

my $zzz = $ioc->get('zzz');

isa_ok($zzz->foo, 'Foo');
is($zzz->foo, 'foo');
};

it "should create via factory" => sub {
$ioc->register('foo' => sub {'123'});
$ioc->register(
foo => {
block => sub {'123'}
}
);

is($ioc->get('foo'), '123');
};

it "should create via factory and pass deps" => sub {
$ioc->register('dep' => '123');
$ioc->register(dep => {value => '123'});
$ioc->register(
'foo' => block => sub {
my $ioc = shift;
my %args = @_;

return $args{dep};
},
deps => 'dep'
foo => {
block => sub {
my $ioc = shift;
my %args = @_;

return $args{dep};
},
deps => 'dep'
}
);

is($ioc->get('foo'), '123');
};

it "should hold singletons" => sub {
$ioc->register('foo', class => 'Foo');
$ioc->register('bar', class => 'Bar', deps => 'foo');
$ioc->register(foo => {class => 'Foo'});
$ioc->register(bar => {class => 'Bar', deps => 'foo'});

my $bar = $ioc->get('bar');
isa_ok($bar, 'Bar');
Expand All @@ -111,11 +112,11 @@ describe "IOC" => sub {
is $bar->hello, 'there';

$bar = $ioc->get('bar');
is $bar->hello, 'there';
ok not defined $bar->hello;
};

it "should hold prototypes" => sub {
$ioc->register('bar', class => 'Bar', lifecycle => 'prototype');
$ioc->register(bar => {class => 'Bar', lifecycle => 'prototype'});

my $bar = $ioc->get('bar');

Expand All @@ -128,5 +129,3 @@ describe "IOC" => sub {
};

runtests unless caller;

1;

0 comments on commit 1e8af83

Please sign in to comment.