Question

I need some help to use guice. I've my project here: https://github.com/Romain-P/kalibro/blob/master/realm/src/org/kalibro/core/Main.java

My problem: I need to replace in this Main.java the 3 injectors, with just 1 injector.

My application is separated: LoginServer and WorldServers. You have just 1 realmServer, and some WorldServers as you want.

Now, I've just created realmServer. In it you have: - RealmManager (which manages players <-> loginServer) - ExchangeManager (which manages worlds <-> loginServer)

They accept connexions, and they create clients, with netty. RealmManager & ExchangeManager extend NetworkService.

NetworkService is an abstractClass, which is useful to create all managers as you want. Imagine if i want later to create shopManager, which speaks with webServer.

Please see the code: https://github.com/Romain-P/kalibro/tree/master/realm/src/org/kalibro/network/netty

Now, my Main.java has 3 injectors, but i need to have just 1. That does work ! but i think it's not cleaned, so i need to have just 1 Injector.

Main.java

[...]
Injector exchangeInjector = Guice.createInjector(new ExchangeModule());
Injector realmInjector = Guice.createInjector(new RealmModule());
try {
    log.info("initializing exchange");
    exchangeInjector.getInstance(ExchangeManager.class).run(config.getExchangePort());
    log.info("initializing server");
    realmInjector.getInstance(RealmManager.class).run(config.getRealmPort());
} catch(Exception e) {
    log.error("Can't start application", +e.getMessage());
    System.exit(1);
}

Modules:

public class RealmModule extends AbstractModule {
    protected void configure() {
        install(new NetworkModule());
        bind(NetworkService.class).to(RealmManager.class);
    }
}
//the same for ExchangeModule..
Was it helpful?

Solution

Guice injector has ... array as an argument:

Guice.createInjector(Module... modules);

So you can simply do:

Guice.createInjector(new ExchangeModule(), new RealmModule());

If there are some conflicts you can try binding annotations or untargetted bindings.

EDIT:

This might show how you could avoid conflicts:

bind(NetworkService.class).annotatedWith(Exchange.class).to(ExchangeManager.class);
bind(NetworkService.class).annotatedWith(Realm.class).to(RealmManager.class);

then:

@Inject
@Exchange
private NetworkService exchangeService;

EDIT 2:

I think the greatest problem is the way you initiate the NetworkService. You can make it an abstract class and then write something like that:

public class ExchangeHandler extends AbstractHandler {
    @Inject
    ExchangeHandler(@Exchange NetworkService service) {
         super(service);
    }
}

You want to have 2 distinct instances that use the exactly same code except for obtaining the NetworkService instance. There are several ways to do it but this one seems to be the most readable at the moment. Alternatively you might consider using Inversion of Control to pass NetworkService you need at the moment instead of creating 2 distinct trees of objects for Exchange and Reaml managers.

class ClassUsingManagers {
    @Inject
    ClassUsingManagers(
            @Exchange NetworkService exchangeService,
            @Realm NetworkService realmService,
            NetworkServiceHandler handler) {
        handler.actionForService(exchangeService);
        handler.actionForService(realmService);
    }
}

or if you just want to initiate them and run one method (which initialized everything else):

Multibinder serviceSet = Multibinder.newSetBinder(binder(), NetworkService.class);
serviceSet.addBinding().asEagerSingleton();

an then:

class ClassUsingManagers {
    @Inject
    ClassUsingManagers(
            Set<NetworkService> services,
            NetworkServiceHandler handler) {
        for(NetworkService service : services)
            handler.actionForService(service);
    }
}

That other method would require you to install Guice Multbinding addon to Guice.

OTHER TIPS

I'd recommend using a binding annotation to distinguish the injections of NetworkService, perhaps:

  @ManagesExchange NetworkService
  @ManagesRealm NetworkService
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top