2015-09-27 96 views
1

我感興趣什麼是正確的方式來構建具有@Assisted參數的依賴關係的對象。一個例子更好地說明:Guice 3 - 使用輔助注入時自動構建對象圖

Ordinarilly有沒有@Assisted PARAMS的依賴,你可以簡單地擁有對象,所有他們之間的依賴與這些獲得注入沒問題的複雜層次結構,我就可以得到一個對象的實例和它的所有依賴關係都將被生成並注入,而無需執行任何操作。

但是,如果我想改變它,有些依賴的對象層次有@Assisted PARAMS然後我要創建自己使用一個工廠,即那些實例:

public SomeConcreteService(@Assisted String string) { 
    this.string = string; 
} 

MyFactory myFactory = injector.getInstance(MyFactory .class); 
SomeService myService = factory.getMyService("some string"); 

這將導致對清潔問題對象的實例化,因爲我將不得不手動創建這些實例。並將它們傳遞到所需的對象,這基本上呈現該對象的DI多餘我想?即然後,我會需要使用new關鍵字,並通過手動所有依賴...

new MyComplexObject(myService, myOtherService) 

如何讓這個我沒有手工打造的對象圖,如果一個或多個依賴關係使用@Assisted參數?

回答

1

你需要問自己的問題是,「爲什麼我要製作這個@Assisted,誰來創建這些對象?」

如果您使用密鑰來獲得你需要一個實例,然後你有什麼是好的:

public class YourInjectableClass { 
    @Inject private MyFactory factory; 

    public void doStuff(String key) { 
    // You have a key, and your factory, so you can create the instance yourself. 
    SomeService service = factory.getMyService(key); 
    // [...] 
    } 
} 

但是如果你使用的關鍵是獲得一個實例創建一個實例來創建一個實例得到什麼你需要,那麼這似乎有問題。這可能是一個很好的解決問題的child injectors

public class YourInjectableClass { 
    @Inject private Injector injector; 
    public void doStuff(String key) { 
    // You need an OuterObject. So rather than calling 
    // new OuterObject(new InnerObject(factory.getMyService(key))), do: 
    OuterObject outerObject = 
     injector.createChildInjector(new OuterObjectModule(key)) 
     .getInstance(OuterObject.class); 
    // [...] 
    } 
} 

因爲你的價值需要在整個依賴關係樹,你可以把它當作一個注入依賴。這可能會讓你更加困惑,但是可以讓你避免讓依賴關注實例化細節。

或者,您可以創建一個手動OuterObjectFactory外觀,它可以手動調用new。這可能是遺留代碼的更好解決方案,但可以通過確保一個類負責抽取實例化細節來幫助遵循單一責任原則。


N.B.我假設SomeConcreteService接受對象圖可以提供的其他依賴關係。如果沒有,那麼根本沒有理由使用注入:給SomeConcreteService一個公共構造函數,並在需要時調用new SomeConcreteService("your value here")。儘管Guice需要一些努力來抽象使用new,但也不需要創建數據對象或依賴關係燈對象,如HashMapDate

+0

我其實沒有真實世界的場景,我只是在想這件事。但是,即使「SomeConcreteService」不需要其他依賴關係,如果可以將其與Guice進行管理,可能仍然很好,例如,可以切換到另一個服務;只是想。 – Neilos

+0

關於你的回答,我認爲大部分時間你的第一個例子就足夠了。主要的變化是:注入工廠,並有一些基本的'init()'方法來初始化依賴項(我假設它將在整個類中多次使用),或者如果只是使用了一次,那麼'doStuff )'方法就足夠了。所以我需要添加額外的邏輯來傳遞密鑰,就像你說的那樣可以理解。你的第二個例子,但我不認爲我完全理解,但我會花一些時間尋找它:) – Neilos