如何包装Google Guice的Injector方法?

3

我正在编写一个使用Guice进行所有依赖注入的API,并希望将所有Guice相关内容隐藏不让API开发人员看到。我有以下代码:

public class MyAppModule extends AbstractModule {
    @Override
    public void configure(Binder binder) {
        // Omitted for brevity...
        // For instance, binds interface type Animal to impl type Dog, etc.
    }
}

public class MyInjector {
    public abstract<?> inject(Class<?> clazz) {
        MyAppModule module = new MyAppModule();
        Injector injector = Guice.createInjector(module);

        return injector.getInstance(clazz);
    }
}

// So that API developers can just use Animal references and Guice will
// automatically inject instances of Dog
MyInjector injector = new MyInjector();
Animal animal = injector.inject(Animal.class); // <-- Guice returns a Dog instance

问题出在我的MyInjector#inject(Class<?>)方法上。按照现在的写法,我收到了编译错误:
Multiple markers at this line
- Return type for the method is missing
- Syntax error on token "?", invalid TypeParameter

根据Guice文档Injector#getInstance返回一个abstract<T>。如果可能的话,我想避免泛型以及显式类型转换,以使我的API开发人员更容易理解。我有什么选择吗?如果有,是什么?如果没有,为什么?谢谢。

+1 给 Avirams 的答案。还有一点需要注意:创建注入器可能会很昂贵,因此您应该在 MyInjector 的构造函数中调用 createInjector 并仅在 inject() 方法中使用该实例。 - Jan Galinski
此外:我不明白你想要实现什么......处理 DI 和注入器并不困难,但也不是易如反掌的。请考虑是否真的希望 API 用户通过 "new" 创建注入器。这样可能会导致许多注入器,因此无法保证像 Singleton 这样的作用域是否有效。 既然 API 用户必须使用 @Inject 才能使其正常工作,为什么不简单地编写一个“入门指南”,链接到 Guice 并向他们解释为什么以及如何创建注入器呢? - Jan Galinski
2个回答

5
不要使用通配符 ?,请使用类似 T 的内容。
此外,抽象方法不能有实现,因此您需要将其删除(您正在重写该方法)。
public <T> T inject(Class<T> clazz) {
    MyAppModule module = new MyAppModule();
    Injector injector = Guice.createInjector(module);

    return injector.getInstance(clazz);
}

感谢@Aviram Segal - 你做得很好。 - IAmYourFaja

2
您应该使用以下方式:
public <T> T inject(Class<T> clazz);

当使用T代替?时,您可以返回类型为T的对象。

顺便说一下,这与Injector所做的相同:

public abstract T getInstance (Class<T> type)

注意:在您的代码中,您尝试实现一个抽象方法。您应该删除abstract关键字,否则将会出现语法错误。抽象方法不能包含实现(这是在子类中完成的)。


感谢 @micha (+1) - 但是实施这些更改会产生新的错误:此行有多个标记 -类型注入器中的抽象方法inject只能由抽象类定义 -抽象方法不指定主体... - IAmYourFaja
1
这是因为你的方法是抽象的。当使用抽象时,你不能为这个方法提供实现(必须在子类中完成)。在你的情况下,你可以只删除抽象关键字就可以了。 - micha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接