Skip to content

Instantly share code, notes, and snippets.

@xenoterracide
Last active December 25, 2015 22:49
Show Gist options
  • Select an option

  • Save xenoterracide/7052294 to your computer and use it in GitHub Desktop.

Select an option

Save xenoterracide/7052294 to your computer and use it in GitHub Desktop.
use 5.014;
use warnings;
package MyContainer {
use Moose;
use Bread::Board::Declare;
use Bread::Board;
use Bread::Board::Dumper;
use DBIx::Connector;
my %models = (
Product => { _provider => '/provider/ProductVariant' },
ProductVariant => { _provider => '/provider/Category' },
Category => { },
);
sub BUILD {
my $self = shift;
container $self => as {
container provider => as {
service dbh => (
lifecycle => 'Singleton',
block => sub {
return sub {
$self->resolve( service => '/conn' )->dbh;
};
},
);
foreach my $model ( keys %models ) {
service $model => (
lifecycle => 'Singleton',
block => sub {
my $svc = shift;
return sub {
$self->resolve(
service => "/$model",
parameters => $_[1] // {},
);
};
},
);
}
};
};
print Bread::Board::Dumper->dump( $self );
}
has conn => (
isa => 'DBIx::Connector',
lifecycle => 'Singleton',
is => 'ro',
block => sub {
return DBIx::Connector->new( 'dbi:NullP:' );
},
);
has controller => (
isa => 'MyController',
is => 'ro',
infer => 1,
);
has products => (
isa => 'Repository::Product',
is => 'ro',
lifecycle => 'Singleton',
infer => 1,
dependencies => {
_provider => '/provider/Product',
_dbh_provider => '/provider/dbh',
},
);
has $_ => (
isa => $_,
is => 'bare',
infer => 1,
dependencies => { _dbh_provider => '/provider/dbh', %{ $models{$_} } },
) foreach keys %models;
}
package Role::DBH {
use Moose::Role;
has _dbh_provider => (
isa => 'CodeRef',
traits => ['Code'],
is => 'bare',
required => 1,
handles => {
_dbh => 'execute',
},
);
}
package Repository::Product {
use Moose;
with 'Role::DBH';
sub get {
my $self = shift;
# ... #deal with input and sql creation
#... transform the data structure
return $self->_new_product({});
}
has _provider => (
isa => 'CodeRef',
traits => ['Code'],
is => 'bare',
required => 1,
handles => {
_new_product => 'execute',
},
);
}
package Product {
use Moose;
with 'Role::DBH';
sub variants {
my $self = shift;
# pretend where processing a list with dbh and mutating to constructors
return ( $self->_new_variant({}) );
}
has _provider => (
isa => 'CodeRef',
traits => ['Code'],
is => 'bare',
required => 1,
handles => {
_new_variant => 'execute',
},
);
}
package ProductVariant {
use Moose;
with 'Role::DBH';
sub categories {
my $self = shift;
return ( $self->_new_category({}) );
}
has _provider => (
isa => 'CodeRef',
traits => ['Code'],
is => 'bare',
required => 1,
handles => {
_new_category => 'execute',
},
);
}
package Category {
use Moose;
with 'Role::DBH';
}
package MyController {
use Moose;
use Test::More;
use Scalar::Util qw( refaddr );
sub test {
my $self = shift;
my $product = $self->_products->get;
my ( $variant ) = $product->variants;
my ( $category ) = $variant->categories;
isa_ok $product, 'Product';
isa_ok $variant, 'ProductVariant';
isa_ok $category, 'Category';
isa_ok $product->_dbh, 'DBI::db';
isa_ok $variant->_dbh, 'DBI::db';
isa_ok $category->_dbh, 'DBI::db';
is refaddr($self->_products->_dbh), refaddr($product->_dbh), 'refs are the same';
}
has _products => (
isa => 'Repository::Product',
is => 'ro',
required => 1,
);
}
use Test::More;
my $di = MyContainer->new;
$di->controller->test;
done_testing;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment