view lib/IMPL/Config/ServiceDescriptor.pm @ 427:09e0086a82a7 ref20150831 tip

Merge
author cin
date Tue, 15 May 2018 00:51:33 +0300
parents b0481c071bea
children
line wrap: on
line source

package IMPL::Config::ServiceDescriptor;
use strict;

use IMPL::lang qw(:base);
use IMPL::Exception();
use IMPL::declare {
    require => {
        Bag                 => 'IMPL::Config::Bag',
        ActivationException => 'IMPL::Config::ActivationException'
    },
    base => [
        'IMPL::Object'             => undef,
        'IMPL::Config::Descriptor' => undef
    ],
    props => [
        type       => 'r',
        activation => 'r',
        args       => 'r',
        services   => 'r',
        norequire  => 'r',
        _name      => 'rw',
        _loaded    => 'rw'
    ]
};

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

    $this->type( $opts{type} )
      or die IMPL::InvalidArgumentException->new('type');

    $this->activation( SELF->ParseActivation( $opts{activation} ) );
    $this->args( $opts{args} )           if exists $opts{args};
    $this->services( $opts{services} )   if exists $opts{services};
    $this->norequire( $opts{norequire} ) if exists $opts{norequire};

    $this->_name( 'new {'
          . SELF->ActivationToString( $this->activation ) . '} '
          . $this->type );
}

sub Activate {
    my ( $this, $context) = @_;

    my $instance;
    my $activation = $this->activation;
    my $cache;

    if ( $activation == SELF->ACTIVATE_SINGLETON ) {
        $cache = $context->container->root->instances;
    }
    elsif ( $activation == SELF->ACTIVATE_CONTAINER ) {
        $cache = $context->container->instances;
    }
    elsif ( $activation == SELF->ACTIVATE_HIERARCHY ) {
        $cache = $context->owner->instances;
    }
    elsif ( $activation == SELF->ACTIVATE_CONTEXT ) {
        $cache = $context->instances;
    }

    $instance = $cache->{ ref($this) } if $cache;
    unless ($instance) {
        $instance = $this->CreateInstance($context);
        $cache->{ ref($this) } = $instance if $cache;
    }

    return $instance;
}

sub CreateInstance {
    my ( $this, $context) = @_;

    my $class =
        $this->norequire
      ? $this->type
      : $context->container->Require( $this->type );
      
    
    # determine how to pass arguments
    if (isarray($this->args)) {
        # if args is an array ref, pass it as list
        return $class->new(map $context->Activate($_), @{$this->args});
    } elsif (ishash($this->args)) {
        # if args is a hash ref, pass it as list
        my %args;
        while(my ($k,$v) = each %{$this->args}) {
            $args{$k} = $context->Activate($v);
        }
        return $class->new(%args);
    } elsif(defined $this->args) {
        # otherwise pass it as a single argument
        return $class->new($context->Activate($this->args)); 
    } else {
        return $class->new();
    }
}

sub GetName {
    shift->_name;
}

1;