Google Guice 中的 AssistedInject 和 MapBinder

AssistedInject and MapBinder together in Google Guice

我最近开始使用 Guice,需要一些帮助。

我有一个 class 构造函数,其中包含 3 种不同的要注入的参数。下面是 class

@Inject public Bullet(EntityParams entityParams, Movable movable, Renderable renderable) {
    super(entityParams, movable, renderable);
}

这里entityParams应该是辅助注射

Movable 接口有多个实现,因此需要使用 MapBinder。

Renderable 接口只有一种实现,所以没问题。

我现在要做的是 ->

public class DefaultEntityFactory implements EntityFactory {

    private final Provider<Renderable> renderableProvider;

    private final Map<String, Movable> movableMap;

    @Inject public DefaultEntityFactory(Provider<Renderable> renderableProvider, Map<String, Movable> movableMap) {
        this.renderableProvider = renderableProvider;
        this.movableMap = movableMap;
    }

    @Override
    public Bullet create(EntityParams entityParams, String movableType) {
        return new Bullet(entityParams, movableMap.get(movableType), renderableProvider.get());
    }

}

工厂 class 给了我一颗子弹,但我只是想知道这是他们更好的方法吗?

从您现有的代码开始

@Inject
public Bullet(
    EntityParams entityParams,
    Movable movable,
    Renderable renderable) {
    super(entityParams, movable, renderable);
}

首先我会处理地图活页夹。

@Inject
public Bullet(
    EntityParams entityParams,
    String movableType,
    Map<String, Provider<Movable>> movables,
    Renderable renderable) {
    super(entityParams, movables.get(movableType), renderable);
}

接下来,我将跟随 AssistedInject 帮助页面。 https://github.com/google/guice/wiki/AssistedInject

首先我添加了 @Assisted 注释。

@Inject
public Bullet(
    @Assisted EntityParams entityParams,
    @Assisted String MovableType,
    Map<String, Provider<Movable>> movables,
    Renderable renderable) {
    super(entityParams, movables.get(movableType), renderable);
}

然后创建工厂接口。

public interface BulletFactory {
    public Bullet create(EntityParams entityParams, String movableType);
}

并将其绑定在一起。

bind(BulletFactory.class)
   .toProvider(FactoryProvider.newFactory(BulletFactory.class, Bullet.class));

您现在可以注入 BulletFactory 来创建新的 Bullet

根据你的问题,使用 @Named 代替 multi-binder 可能会更好(传入 String 类型并立即将其从 multi-binder 中拉出来感觉有点尴尬)但是这应该有效。