2014-04-19 81 views
1

我需要一些幫助來使用guice。 我在這裏的項目:https://github.com/Romain-P/kalibro/blob/master/realm/src/org/kalibro/core/Main.javaGoogle guice:幫助注入

我的問題:我需要在這個Main.java 3個噴油器,只有1個噴油器。

我的應用程序是分開的: LoginServer和WorldServers。 你只有1個realmServer和一些WorldServers。

現在,我剛剛創建了realmServer。在它,你必須: - RealmManager(負責管理球員< - >登陸服務器) - ExchangeManager(負責管理世界< - >登陸服務器)

他們接受CONNEXIONS,和他們創造的客戶,用網狀。 RealmManager & ExchangeManager擴展NetworkService。

NetworkService是一個abstractClass,可以根據需要創建所有管理器。想象一下,如果我想以後創建shopManager,它與web服務器說話。

請參閱代碼:https://github.com/Romain-P/kalibro/tree/master/realm/src/org/kalibro/network/netty

現在,我的Main.java有3個噴射器,但我需要剛剛1 但這工作!但我認爲它沒有清潔,所以我需要只有1個噴油器。

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); 
} 

模塊:

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

你是否需要將兩者都綁定到'NetworkService'?你使用具體的類來解析實例 - 你能否僅僅綁定到具體的類就可以了,例如'綁定(RealmManager.class);',在模塊中?然後這兩個模塊可以在一個注射器中創建。 –

+0

編輯*請等待 –

+0

這是不可能的,因爲我在networkServiceHandler中注入networkService,他不知道經理使用 –

回答

3

吉斯噴射器具有...數組作爲參數:

Guice.createInjector(Module... modules); 

因此,你可以簡單地做:

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

如果有一些衝突,那麼你可以嘗試binding annotationsuntargetted bindings

編輯:

這可能會告訴你如何能避免衝突:

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

則:

@Inject 
@Exchange 
private NetworkService exchangeService; 

編輯2:

我認爲最大的問題是這樣的您啓動NetworkService。你可以把它抽象類,然後寫類似的東西:

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

你想擁有使用完全相同的代碼,除了獲得網絡服務實例2個不同的實例。有幾種方法可以做到這一點,但目前這似乎是最可讀的。或者,您可以考慮使用Inversion of Control來傳遞此時需要的NetworkService,而不是爲ExchangeReaml管理器創建2個不同的對象樹。

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

,或者如果你只是想開始他們並運行一個方法(初始化一切):

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

一則:

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

其他方法將要求您將Guice Multbinding插件安裝到Guice。

+0

存在一些衝突,我會看到綁定註釋, thx –

+0

我已經添加了一個示例來展示如何實現您的目標。 –

+0

謝謝,但是不解決我的問題:]因爲我需要在NetworkServiceHandler中注入NetworkService,並且他必須是沒有註釋的NetworkService,因爲它是一個用於創建新服務的「接口」..例如,我會可能會添加shopManager –

0

我推薦使用的結合annotation來區分網絡服務的注射劑,也許:

@ManagesExchange NetworkService 
    @ManagesRealm NetworkService 
+0

確定但在哪裏?請解釋請 –

+0

更新主題,你可以看到。 –

+0

在您的綁定中(請參閱wiki:https://code.google.com/p/google-guice/wiki/BindingAnnotations) – Fred