Created
November 11, 2012 04:22
-
-
Save xenoterracide/4053667 to your computer and use it in GitHub Desktop.
Inversion of Control and Dependency Injection example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use 5.014; | |
| use warnings; | |
| use Class::Load 'load_class'; | |
| package PaymentGateway { | |
| use Moose; | |
| sub submit { | |
| return int( rand(2) ); | |
| } | |
| __PACKAGE__->meta->make_immutable; | |
| } | |
| package Order { | |
| use Moose; | |
| sub make_payment { | |
| my $self = shift; | |
| return $self->_payment_gateway->submit( $self ); | |
| } | |
| has _payment_gateway => ( | |
| isa => 'Object', | |
| is => 'ro', | |
| required => 1, | |
| ); | |
| __PACKAGE__->meta->make_immutable; | |
| } | |
| package AppContainer { | |
| use Moose; | |
| extends 'Bread::Board::Container'; | |
| use Bread::Board; #import sugar | |
| sub _build_config { | |
| my $self = shift; | |
| # hardcode for example | |
| return { | |
| username => 'foo', | |
| password => 'bar', | |
| }; | |
| } | |
| has _config => ( | |
| isa => 'HashRef', | |
| is => 'ro', | |
| lazy => 1, | |
| builder => '_build_config', | |
| ); | |
| sub BUILD { | |
| my $self = shift; | |
| # container can take a container as a parameter. if you do this it | |
| # will simply add to the container it tooks as a paramter | |
| # this will be our root container / | |
| container $self => as { | |
| # subcontainer path to will be /model | |
| container model => as { | |
| # order uses constructor injection | |
| service order => ( | |
| class => 'Order', | |
| dependencies => { | |
| # use full path | |
| _payment_gateway => | |
| depends_on('/remote/payment_gateway'), | |
| }, | |
| ); | |
| }; | |
| # another subcontainer /service | |
| container remote => as { | |
| service username => $self->_config->{username}; | |
| service password => $self->_config->{password}; | |
| service payment_gateway => ( | |
| class => 'PaymentGateway', | |
| # we don't need more than one instance | |
| lifecycle => 'Singleton', | |
| dependencies => { | |
| username => depends_on('username'), | |
| password => depends_on('password'), | |
| }, | |
| ); | |
| }; | |
| }; | |
| } | |
| __PACKAGE__->meta->make_immutable; | |
| } | |
| package Controller { | |
| # this could be any framework controller | |
| use Moose; | |
| has _c => ( | |
| isa => 'Bread::Board::Container', | |
| is => 'ro', | |
| ); | |
| sub process_order { | |
| my $self = shift; | |
| my $order = $self->_c->resolve( service => '/model/order' ); | |
| if ( $order->make_payment ) { | |
| say 'payment succeeded'; | |
| } | |
| else { | |
| say 'payment failed'; | |
| } | |
| } | |
| __PACKAGE__->meta->make_immutable; | |
| } | |
| my $app = AppContainer->new({ name => 'app' }); | |
| # controller has not idea there's only one app containerr | |
| my $controller = Controller->new( _c => $app ); | |
| for ( my $i = 0; $i < 10 ; $i++ ) { | |
| $controller->process_order; | |
| } | |
| 1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment