Guice - привязка экземпляра, созданного фабрикой вспомогательных инъекций

Допустим, есть класс A, конструктор которого выглядит примерно так:

public A(@Assited long id, @Assisten String name, ServiceA serviceA, ServiceB serviceB)

И есть AFactory:

public interface AFactory{

    A create(long id, String name);
}

Так что для создания экземпляра ИИ явно нужно сделать что-то подобное:

injector = Guice.createInjector(new MyModule());
AFactory af = injector.getInstance(AFactory .class);
A a = AFactory.create(100, "mike");

НО, допустим, у меня есть другие классы: класс B, класс C и класс D, который имеет член с типом A, например (с инъекцией поля, но также может быть ctor):

    public class B{
       @Inject
       A a;
    }

И я хочу, чтобы один и тот же экземпляр A был введен в эти классы. Но все же есть возможность добавить другой экземпляр A в другие классы (скажем, класс E и F).

Как правильно это сделать? Я просто не могу придумать чистый способ сделать это.

1 ответ

Решение

Вы можете структурировать свой модуль для использования провайдеров (я использую методы @Provides ниже, но вы можете использовать полные классы или экземпляры провайдеров, если хотите) и пометить непротиворечивую букву A как @Singleton. Если вы хотите две привязки A (непротиворечивые и непоследовательные), по крайней мере, одна из них должна быть помечена аннотацией привязки; я использую @Named здесь из-за удобства, но вы можете использовать любую обязательную аннотацию, как указано в документации.

public class AModule extends AbstractModule {
  @Override public void configure() {
    // Install your AFactory module. Here, injections for AFactory should succeed.
    install(new FactoryModuleBuilder().build(AFactory.class));
  }

  /**
   * Provides a singleton @Named("consistent") A.
   * Inject @Named("consistent") A into B, C, and D; Guice will cache the instance.
   */
  @Provides @Singleton @Named("consistent")
      A provideConsistentA(AFactory factory) {
    return factory.create(100, "mike");
  }

  /**
   * Provides an unscoped A.
   * Inject A without an annotation into E and F; each instance will be separate.
   */
  @Provides @Singleton A provideUnscopedA(AFactory factory) {
    return factory.create(200, "jeff");
  }
}
Другие вопросы по тегам