2011-06-14 78 views
3

使用MooseBread::Board,是有可能创建与具有ArrayRef[SomeObject]类型约束的属性的对象,并且具有参数以这样的方式即注射:Bread :: Board - 使用ArrayRef类型约束注入参数?

  • ArrayRef约束被维持,
  • 每个作为该ArrayRef成员的对象的所有依赖项满足Bread::Board
  • 作为该ArrayRef成员的每个对象都是由Bread::Board创建的对象?

为了确保我清楚地解释自己,让我们考虑一个令人难以置信的天真的例子。比方说,我们有一个Wheel类:

package Wheel; 
use Moose; 

has ['size', 'maker'] => (isa => 'Str', is => 'rw', required => 1); 

而且让我们创建一个Vehicle类,其中每个实例都包含了一堆轮:

package Vehicle; 
use Moose; 

has 'wheels' => (
    is => 'rw', 
    isa => 'ArrayRef[Wheel]', 
    required => 1, 
); 

是否然后可能创造的Wheel一个或多个实例和然后将包含这些实例的数组引用注入我们的新的Vehicle实例中?这显然不会工作:

my $c = container 'app' => as { 
    container 'wheels' => as { 
     service 'maker' => "Bob's Tires"; 
     service 'size' => "195R65/15"; 
     service 'carTires' => (
      class => 'Wheel', 
      dependencies => [ depends_on('maker'), depends_on('size') ], 
     ) 
    }; 

    container 'vehicles' => as { 
     service 'sedan' => (
      class => 'Vehicle', 
      dependencies => { 
       # WON'T WORK 
       wheels => depends_on('/wheels/carTires'), 
      } 
     ) 
    }; 
}; 
my $v = $c->resolve(service => 'vehicles/sedan'); 

任何想法?是的,我知道我的Vehicle可以想象没有车轮,我试图创造一个单轮轿车,但我认为你明白我的观点。 :-)这只是一个令人难以置信的微不足道的例子。

+0

这是老了,我不想输入较长的答案,但[我的博客文章上使用提供商(HTTP:/ /www.xenoterracide.com/2013/10/providing-with-providers-and-breadboard.html)可能会帮助人们解决像这样的问题 – xenoterracide 2013-11-01 06:57:16

回答

4

你可以得到carTires的服务回报车轮的数组引用:

container 'wheels' => as { 
    service 'carTires' => (
     block => sub { 
      return [ map {Wheel->new} 1..4 ]; 
     }, 
    ) 
}; 

车辆构造函数将负责其余的在类型约束的条款,因为你已经把它定义为数组引用[轮]。

所以,如果你这样做,而不是将死:

container 'wheels' => as { 
    service 'carTires' => (
     block => sub { 
      return [ map {Window->new} 1..4 ]; 
     }, 
    ) 
}; 
+0

感谢您的答案!我已经重新解释了我的原始问题,以添加额外的警告,即'Wheel'也具有需要满足的依赖关系 - 以相似的方式使用块注入仍然是正确的解决方案? – 9numbernine9 2011-06-14 11:34:22

+0

我会这么认为,因为块注入是最灵活的方面,你可以用它做什么。其他注入方法的问题是我看不到我们可以使用它们创建多个对象实例的ArrayRef。 – stevenl 2011-06-14 13:55:56