1

我对 Guice 还很陌生,所以希望这不是一个明显的问题......

我正在处理一个使用反射动态实例化我的一个应用程序类(让我们称之为C)的框架,所以我无法控制它的实例化。C此外,在框架实例化它之后,我没有简单的方法来访问新创建的。如下C所示:

    公共类 C 实现 I {

        公共 C() {
            // 这个 ctor 是由框架调用的,所以不能在这里使用 DI?
        }        

        公共无效初始化(){
            // 这是一个后实例化钩子,f/w 将调用它
        }

        私人无效 m() {
            依赖 d = Dependency.getInstance();
            d.doSmth();
        }
    }

我想使用 DIC获取。DependencyDependency显然是一个单例,但通常情况并非如此。

我想出了两种可能的解决方案,感觉都不是很整洁,所以我想我会问专家:

  1. 静态注入。我很难看到这如何在服务定位器反模式上得到显着改进 - 我最终得到了可以在外部操纵的非最终静态字段......嗯。

  2. 该框架支持一个钩子,用于C在实例化后初始化自身(initialize()如上所示的方法)。此方法可以使用 setter 注入自注入新创建的实例。

对于 2,我想这意味着更多的外部可更改性,但至少对于单元测试之类的事情更明确地暴露了依赖关系。问题是:在这种情况下,我如何获得 Guice Injector(不依赖另一个服务定位器)?我也读过(并且倾向于同意)在整个应用程序代码中明确引用 Injector 是可疑的做法。

您的洞察力将不胜感激。

非常感谢,
克里斯蒂安

4

2 回答 2

2

您可以尝试将提供程序静态注入到 C 中。静态注入更难于测试。但是提供者使 Guice 可以急切地验证您的依赖项,同时懒惰地创建它们。

public class C implements I {
  @Inject static Provider<Dep1> dep1Provider;
  @Inject static Provider<Dep2> dep2Provider;

  ...

  public void initialize() {
    Dep1 dep1 = dep1Provider.get();
    Dep2 dep2 = dep2Provider.get();
    ...
  }
}
于 2011-03-17T07:03:08.633 回答
1

如果您通过静态变量和静态访问器方法使您的 Guice 注入器可用,您可以像这样解决它:

public class C implements I {

    public C() {
        // this ctor is invoked by the framework, you can't do injection here.
    }        

    public void initialize() {
        MyGuice.getInjector().inject(this);
    }

    @Inject
    protected void init(Dep1 dep1, Dep2 dep2) {
        this.dep1 = dep1;
        this.dep2 = dep2;
    }

    private void m() {
        dept1.doSmth();
    }
}

静态调用有点反模式,如果您愿意使用执行代码编织或编译后步骤的解决方案,您可以使用一个简单的注释来删除该依赖关系,该注释负责处理构造函数后注入。这样,即使它们没有初始化方法,您也可以注入所有对象。您可以在此处找到一个示例:如何使用 AspectJ 注入模型对象

@Configurable
public class C implements I {

    public C() {
        // this ctor is invoked by the framework, you can't do injection here.
    }        

    @Inject
    protected void init(Dep1 dep1, Dep2 dep2) {
        this.dep1 = dep1;
        this.dep2 = dep2;
    }

    private void m() {
        dept1.doSmth();
    }
}
于 2011-03-20T20:35:46.357 回答