view lib/IMPL/Config/ActivationContext.pm @ 421:7798345304bc ref20150831

working on IMPL::Config, removed old stuff
author cin
date Sun, 16 Jul 2017 22:59:39 +0300
parents 3ed0c58e9da3
children b0481c071bea
line wrap: on
line source

package IMPL::Config::ActivationContext;

use IMPL::lang qw(:base);
use IMPL::Const qw(:prop);
use IMPL::Exception();
use IMPL::declare {
    require => {
        Bag                      => 'IMPL::Config::ServicesBag',
        ServiceNotFoundException => 'IMPL::Config::ServiceNotFoundException',
    },
    base => {
        'IMPL::Object' => '@_'
    },
    props => [
        container => PROP_RW,
        instances => PROP_RW,
        _services => PROP_RW,
        _stack    => PROP_RW
    ]
};

sub CTOR {
    my ( $this, $container ) = @_;

    $this->container($container)
      or die IMPL::InvalidArgumentException->new('container');
    $this->_services( $container->services );
    $this->instances( {} );
    $this->_stack( [] );
}

sub EnterScope {
    my ( $this, $name, $services ) = @_;

    my $info = { name => $name };

    if ($services) {
        die IMPL::InvalidArgumentException->new(
            services => 'An array is required' )
          unless isarray($services);

        my $bag = $this->container->serviceCache->{ ref($services) };

        unless ($bag) {
            my $container = $this->container;
            $bag = Bag->new( $this->_services );

            #
            $bag->Register(
                $container->GetLinearRoleHash( $_->{role}, $_->{descriptor} ) )
              foreach @$services;

            $container->serviceCache->{ ref($services) } = $bag;
        }

        $info->{services} = $this->_services;
        $this->_services($bag);
    }

    push @{ $this->_stack }, $info;
}

sub LeaveScope {
    my ($this) = @_;

    my $info = pop @{ $this->_stack }
      or die IMPL::InvalidOperationException->new();

    $this->_services( $info->{services} ) if $info->{services};
}

sub Resolve {
    my ( $this, $role, %opts ) = @_;

    my $d = $this->_services->Resolve($role);

    unless ($d) {
        die ServiceNotFoundException->new($role) unless $opts{optional};
        return $opts{default};
    }
    else {
        return $d->Activate($this);
    }
}

sub Clone {
    my ($this) = @_;

    my $clone = SELF->new( $this->container );

    $clone->_services( $this->_services );
    $clone->instances( { %{ $this->instances } } );
    $clone->_stack( [ @{ $this->_stack } ] );

    return $clone;
}

1;
__END__

=pod

=head1 NAME

C<IMPL::Config::ActivationContext> - an activation context for the service

=head1 SYNOPSIS

For the internal use only

=head1 MEMBERS

=head2 METHODS

=head3 Resolve($serviceId)

=cut