22 Ekim 2021 Cuma

Guice Multibinder Sınıfı

Giriş
Şu satırı dahil ederiz
import com.google.inject.multibindings.Multibinder;
Aynı arayüzü gerçekleştiren tüm sınıfları Set olarak alabilmemizi sağlar. List olarak @Inject edemeyiz.

Benzer yetenek Spring ile de geliyor. Ancak farklı olarak aynı arayüzü gerçekleştiren bean'leri List veya Set olarak alabiliriz.

Örnek
Şöyle yaparız. Böylece Action sınıfından kalıtan her şeyi alabiliriz.
Multibinder<Action> actionBinder = Multibinder.newSetBinder(binder(), Action.class);
actionBinder.addBinding().to(FooAction.class);
actionBinder.addBinding().to(BarAction.class);
Şöyle yaparız
@Inject
public Foo(Set<Action> actions) {
  ...
}
Örnek
Şöyle yaparız. Böylece elimizde soyut bir Module olur
public abstract class ActionModule extends AbstractModule {
  private Multibinder<Action> actionBinder;

  @Override
  protected void configure() {
    actionBinder = Multibinder.newSetBinder(binder(), Action.class);
    configureActions();
  }

  //Override this method to call {@link #bindAction}.
  protected abstract void configureActions();

  protected final LinkedBindingBuilder<Action> bindAction() {
    return actionBinder.addBinding();
  }
}
Module gerçekleştirimi için şöyle yaparız.
public final class MyStandardActionModule extends ActionModule {
  @Override
  protected void configureActions() {
    bindAction().to(FooAction.class);
    bindAction().to(BarAction.class);
    // If you need to instantiate an action through a Provider, do this.
    bindAction().toProvider(BazActionProvider.class);
    // You can also scope stuff:
    bindAction().to(MySingletonAction.class).in(Singleton.class);
  }
}



11 Ekim 2021 Pazartesi

Guice AbstractModule Sınıfı

Giriş
Şu satırı dahil ederiz.
import com.google.inject.AbstractModule;
Metodların karşılığı şöyle
Guice DSL syntax         Mental model
bind(key).toInstance(value) map.put(key, () -> value) (instance binding)
bind(key).toProvider(provider) map.put(key, provider)    (provider binding)
bind(key).to(anotherKey) map.put(key, map.get(anotherKey)) (linked binding)
@Provides Foo provideFoo() {...} map.put(Key.get(Foo.class), module::provideFoo) (provider                                                            (method binding)
bind metodu
Örnek - to 
Şöyle yaparız. Burada her seferinde yeni bir DefaultCommunicatorImpl yaratılır
public class BasicModule extends AbstractModule {

  @Override
  protected void configure() {
    bind(Communicator.class).to(DefaultCommunicatorImpl.class);
  }
}
Örnek - toInstance 
Şöyle yaparız. Burada her seferinde aynı DefaultCommunicatorImpl kullanılır
public class BasicModule extends AbstractModule {
DefaultCommunicatorImpl communicator = ...;
@Override protected void configure() { bind(Communicator.class).to(communicator);
} }
Örnek - toInstance 
Şöyle yaparız. Burada her seferinde yeni bir Communication yaratılır
public class BasicModule extends AbstractModule {
@Override protected void configure() {
bind(Communication.class).toInstance(new Communication(true)); } }
Örnek - toConstructor 
Şöyle yaparız. Burada her seferinde yeni bir Communication yaratılır ve Boolean alan constructor'ı kullanılır.
public class BasicModule extends AbstractModule {
@Override protected void configure() { bind(Boolean.class).toInstance(true); bind(Communication.class).toConstructor( Communication.class.getConstructor(Boolean.TYPE)); } }
install metodu
Ortak olan şeylerin bir AbstractModule altında toplanabilmesini sağlar.
Örnek
Şöyle yaparız
class TextEditorModule extends AbstractModule {
@Override protected void configure() { install (new MyCommonModule(); } }

Guice Injector Sınıfı

Giriş
Şu satırı dahil ederiz.
import com.google.inject.Injector;
createChildInjector metodu
Farklı konfigürasyonlar göre Injector yaratabilmeyi sağlar.

Örnek
Şöyle yaparız
class ForeverModule extends AbstractModule {
  ...
}

class TemporaryModule extends AbstractModule {
  ...
}

Injector foreverInjector = Guice.createInjector(new ForeverModule());

Injector injector = foreverInjector.createChildInjector(new TemporaryModule());
/*
 * Do stuff with the injector as you would normally. When you
 * get bored of that injector, create a replacement injector
 * as a child of the long-lived injector.
*/
getInstance metodu
Belirtilen Class'a ait bir nesne döner. Nesne Spring terminolojisiyle @Autowire edilmiştir.
Örnek
Şöyle yaparız
Injector injector = Guice.createInjector(new BasicModule());
Communication comms = injector.getInstance(Communication.class);

Guice Kullanımı

Maven
Şu satırı dahil ederiz
<dependency>
  <groupId>com.google.inject</groupId>
  <artifactId>guice</artifactId>
  <version>4.1.0</version>
</dependency>
Kullanım
1. Bir Injector yaratılır. Injector'ı yaratırken AbstractModule nesnesi veririz.
2. Injector.getInstance(Foo.class) çağrısı ile @Inject anotasyonları doldurulmuş bir Foo nesnesi elde ederiz
3. Eğer Enforce Explicit Binding seçili değilse, Guice JustInTimeBindings yapabilir. Yani AbstractModule tarafından bilinmeyen veya anotasyon ile işaretlenmemiş nesneleri de yaratabilir.

Örnek
Şöyle yaparız
Injector injector = Guice.createInjector(new BasicModule());
Communication comms = injector.getInstance(Communication.class);
Injector Sınıfı
Injector Sınıfı yazısına taşıdım

AbstractModule Sınıfı
AbstractModule Sınıfı yazısına taşıdım

Singleton Kullanımı
Singleton 3 farklı şekilde yapılabilir.
1. At Class level
Örnek
Şöyle yaparız
@Singleton
class SpellCheckerImpl implements SpellChecker {
   
  @Override
  public void checkSpelling() { 
    ...
  }
}

class TextEditorModule extends AbstractModule {
@Override protected void configure() { bind(SpellChecker.class).to(SpellCheckerImpl.class); } }
2. At Configuration level
Örnek
Şöyle yaparız
class TextEditorModule extends AbstractModule {
@Override protected void configure() { bind(SpellChecker.class).to(SpellCheckerImpl.class).in(Singleton.class); } }
3. At Method level
Örnek
Şöyle yaparız
class TextEditorModule extends AbstractModule {
   @Override
   protected void configure() {} 

   @Provides @Singleton
   public SpellChecker provideSpellChecker() {
      SpellChecker spellChecker = new SpellCheckerImpl();
      return spellChecker;
   }
}