package org.realityforge.replicant.example.client.ioc;

import com.google.gwt.inject.client.AbstractGinModule;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.name.Names;
import com.google.web.bindery.event.shared.EventBus;
import org.realityforge.gwt.lognice.LoggingEventBus;
import org.realityforge.replicant.client.transport.CacheService;
import org.realityforge.replicant.client.transport.gwt.LocalCacheService;
import org.realityforge.replicant.example.client.GlobalAsyncCallback;
import org.realityforge.replicant.example.client.net.TyrellDataLoaderService;
import org.realityforge.replicant.example.client.net.TyrellDataLoaderServiceImpl;
import org.realityforge.replicant.example.client.net.TyrellSessionContext;
import org.realityforge.replicant.example.client.net.TyrellSessionContextImpl;

public class BasicModule
  extends AbstractGinModule
{
  @Override
  protected void configure()
  {
    bindNamedService( "GLOBAL", AsyncCallback.class, GlobalAsyncCallback.class );
    bind( TyrellDataLoaderService.class ).to( TyrellDataLoaderServiceImpl.class ).asEagerSingleton();
    bind( TyrellSessionContext.class ).to( TyrellSessionContextImpl.class ).asEagerSingleton();
    bind( CacheService.class ).to( LocalCacheService.class ).asEagerSingleton();
    bind( EventBus.class ).to( LoggingEventBus.class ).asEagerSingleton();
  }

  private <T> void bindNamedService( final String name,
                                     final Class<T> service,
                                     final Class<? extends T> implementation )
  {
    bind( service ).annotatedWith( Names.named( name ) ).to( implementation ).asEagerSingleton();
  }
}

package org.realityforge.replicant.example.client.ioc;

import com.google.gwt.inject.client.AbstractGinModule;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.name.Names;
import com.google.web.bindery.event.shared.EventBus;
import org.realityforge.gwt.lognice.LoggingEventBus;
import org.realityforge.replicant.client.transport.CacheService;
import org.realityforge.replicant.client.transport.gwt.LocalCacheService;
import org.realityforge.replicant.example.client.GlobalAsyncCallback;

public class BasicModule
  extends AbstractGinModule
{
  @Override
  protected void configure()
  {
    bindNamedService( "GLOBAL", AsyncCallback.class, GlobalAsyncCallback.class );
    bind( CacheService.class ).to( LocalCacheService.class ).asEagerSingleton();
    bind( EventBus.class ).to( LoggingEventBus.class ).asEagerSingleton();
  }

  private <T> void bindNamedService( final String name,
                                     final Class<T> service,
                                     final Class<? extends T> implementation )
  {
    bind( service ).annotatedWith( Names.named( name ) ).to( implementation ).asEagerSingleton();
  }
}

Remove double binding