2010-06-24 48 views
1

這裏是我的客戶:有時不需要如何在Guice中進行可選的綁定?

class Client { 
    @Inject(optional=true) Service service; 
} 

該服務,而我們知道,信息的JVM啓動時(即粘結劑運行之前)。 如何使綁定成爲可選項?如果我完全不指定綁定,它會嘗試新建該服務(並且因爲沒有零參數構造函數而失敗:「注入package.Client.service時出錯(Service.java:40):找不到在package.Service「)一個合適的構造函數,我不能這樣做:

binder.bind(Service.class).toInstance(null); 

因爲吉斯似乎不允許空值。有任何想法嗎?

+0

吉斯建議使用'binder.bind(Service.class).toProvider( (null));' – oshai 2014-07-02 11:51:44

+0

這個問題的人可能會對Guice的['OptionalBinding'](https://google.github.io/guice/api-docs/4.1/javadoc/com/google)感興趣/inject/multibindings/OptionalBinder.html)類,它允許您提供可能或不可以設置的綁定。 – dimo414 2017-04-17 20:51:22

回答

6

您使用的是Guice 2.0嗎?我已經嘗試過這兩種方法,其中Service是一個接口(服務字段總是null),並且它是一個類(如果它不能創建帶有JIT綁定的新實例,則爲實例,如果可以的話,則爲null)。這兩個看起來像你所期望的。

在這兩種情況下,我都沒有使用像bind(Service.class).toInstance(null)這樣的綁定。如果你這樣做,那麼你需要確保Service的所有注入點指定它們允許它爲null。這可以通過標註一個名爲@Nullable任何標註注入點來完成(你可以自己做或使用現有):

class Client { 
    @Inject @Nullable Service service; 
} 
2

我無法重現此問題。當我運行這個示例代碼時,注入器創建並且可選注入不被滿足。該程序打印null

public class OptionalInjections { 

    static class Service { 
    public Service(Void v) {} // not injectable 
    } 

    static class Client { 
    @Inject(optional = true) Service service; 
    } 

    public static void main(String[] args) { 
    Injector i = Guice.createInjector(); 
    Client client = i.getInstance(Client.class); 
    System.out.println(client.service); 
    } 
} 

你能在JUnit測試案例重現這一併將其提交給Guice issue tracker

+0

運行您的測試我得到: com.google.inject.ConfigurationException:在Scratch $ Service中出錯。 (Scratch.java:15)注入時出現錯誤$ Client.service(Scratch.java:18):無法在Scratch $ Service中找到合適的構造函數。類必須有一個(且只有一個)用@Inject註釋的構造函數或一個零參數構造函數。 但是,我意識到我正在使用Guice 1.0 - 這不是我曾經想過要升級的東西。現在在Guice 2。0,我會像預期的那樣得到null。謝謝! – gubby 2010-06-25 16:28:03

3

如果您想使綁定可選,您可以使用@Inject(optional = true)進行字段和方法注入。對於構造器和其他參數類型的注射,你必須使用一個輔助類,例如:

class Foo { 
    public String hello(Helper helper) { 
    return Helper.string; 
    } 
    private static final class Helper { 
    @Inject(optional = true) public String string = ""; 
    } 
} 

注意上面不允許null被注入,所以富#你好永遠不會返回null。如果您確實想要允許null,只需添加@Nullable註釋。請記住,除非您提供如下所示的代碼將無法綁定(爲null,如果沒有別的)的字符串:

class Bar { 
    @Inject @Nullable public String hello(@Nullable String string) { 
    return string; 
    } 
}