对不起,如果这是一个微不足道的问题,我是Guice的新手。 假设我有以下课程:
public class MyClass {
@Inject
public MyClass(final MyDependency myDependency) {
this.name = myDependency.getName();
}
public String getName() {
this.name;
}
}
然后我想做的其他地方:
public class SomeOtherClass {
public void test() {
MyClass instanceFoo = injector.getInstance(MyClass.class);
MyClass instanceBar = injector.getInstance(MyClass.class);
assertTrue("foo", instanceFoo.getName());
assertTrue("bar", instanceBar.getName());
}
}
我想有两个“MyClass”实例,一个名为“foo”,另一个名称为“bar”(即每个实例都有一个不同的依赖实例)。如何将这两个实例添加到我的注入器中,如何使用“injector.getInstance”检索每个实例?
我不想为每个可能的依赖项创建“MyClass”的子类。
谢谢!
答案 0 :(得分:5)
您的问题,如标题中所示,有一个更简单的解决方案:如果您想要任意数量的MyClass或MyDependency实例,则可以注入Provider<MyClass>
或Provider<MyDependency>
。无论您是否在模块中实际绑定了提供商,都是如此;对于图中可用的任何T,Guice实际上可以注入T
或Provider<T>
。 (这些分别对应Injector.getInstance
和Injector.getProvider
。)
正如在问题正文中,有两部分:为同一Key
创建多个可注入Class
,并以不同的名称和注入的依赖关系设置实例
Guice使用Key
标识绑定,MyClass
是一个完全限定的类(如List<MyClass>
或BindingAnnotation
),并结合可选的&#34;绑定注释&#34;。这是一个注释,它本身用javax.inject.Qualifier
或@Named
注释;您可以创建自己的,也可以使用带有字符串的内置名为@Named("foo")
的内容(因此@Named("bar")
与annotatedWith
不同。)
大多数情况下,您可以直接使用Key:在bind
调用中使用@Provides
或将注释添加到getInstance
方法,并通过添加注释来请求它们到构造函数参数或@Inject-annotated字段。但是,您仍然可以使用Key上的静态方法手动创建密钥来使用getProvider
和Names.named
。 (对于复杂的情况,请使用TypeLiteral或@Named("foo") MyClass
;有关详细信息,请参阅其文档。)
既然您知道如何注入@Foo MyClass
或toInstance
,那么您如何提供它们?根据您的需要,我选择以下三个选项之一:绑定@Provides
,使用bind
方法,或创建&#34;辅助注射&#34;工厂。
如果您的MyClass实例不需要自己注入,并且您不会改变或操纵实例状态,那么您可以准备根据需要命名的实例,然后toInstance
@Provides @Named("foo") MyClass
。
您还可以编写MyClass
方法,该方法采用toInstance
参数(Guice通过注入器提供),设置名称并返回实例。这是编写Provider类或实例的低开销替代方法,它将为您提供一个新的实例,而不是name
绑定所暗示的共享。
如果您真的希望MyClass.Factory
成为类的构造函数参数的一部分,也许为了保持实例不可变,您可以使用&#34; Assisted Injection&#34;告诉Guice你自己提供哪些参数,哪些来自Guice注射器。这样您就可以注入一个myClassFactory.create("foo")
并调用@Provides
,您可以直接在您的消费类中使用,或使用上面的public function load($data, $formName = null)
{
$scope = $formName === null ? $this->formName() : $formName;
if($scope) {
$data[$scope]['images'] = \yii\helpers\Json::encode($data[$scope]['images']);
}
else {
$data['images'] = \yii\helpers\Json::encode($data['images']);
}
return parent::load($data, $formName); // TODO: Change the autogenerated stub
}
技术。细节有点超出了问题的范围,但查阅&#34;辅助注射&#34;有关语法和添加适当JAR的详细信息。