簡體   English   中英

如何在Dagger中“提供” void方法

[英]How can I 'provide' a void method in Dagger

我正在嘗試從Spring遷移項目,並通過遵循示例GitHub存儲庫開始使用Dagger 2。

在Spring中,我可以在類級別使用注釋來公開類的所有方法,包括void方法。 我想在Dagger 2中做到這一點,即我想“提供”一個void方法。

在下面的代碼示例中,也許我應該將printRandomUUID方法移至“ Printer界面。 但是,我正在做這個小練習,目標是遷移經典的Spring @Component@Service

正確的方法是什么? 是否可以在組件或模塊級別提供void方法?

public class Main {

 interface Printer {

    void printMsg(String msg);
 }

 static class ConsolePrinter implements Printer {

    @Override
    public void printMsg(String msg) {
        System.out.println(msg);
    }
 }

 @Singleton
 @Component(modules = ConsoleModule.class)
 interface HelloWorldApp {

    Printer getPrinter();

    //this doesn't compile -> java.lang.IllegalArgumentException: not a valid component method:
    void printRandomUUID();
 }

 @Module
 static class ConsoleModule {

    @Provides
    Printer providePrinter() {
        return new ConsolePrinter();
    }

    //this doesn't compile -> @Provides methods must return a value (not void)
    @Provides
    void printRandomUUID() {
        System.out.println(UUID.randomUUID().toString());
    }

 }

 public static void main(String[] args) {
    HelloWorldApp app = DaggerMain_HelloWorldApp.create();
    app.getPrinter().printMsg("Hello");
    System.out.println("-");
    //app.printRandomUUID();//here i want a void method to be consumed, from the component.
 }
}

尚不可能(尚未)。 與Spring不同,Dagger僅通過檢查Component接口和Modules進行配置。 這意味着Dagger @Component方法必須@Component文檔中的方法格式匹配 ,並且目前無法提供委托給其他實例的任意代碼或方法。

並不是說組件不能有void方法:它們可以,但必須是一參數方法,才能在外部創建的實例中注入@Inject注釋的方法和字段。 這些方法稱為成員注入方法 ,除了可以void它們void它們還可以返回它們接受的類型以便於鏈接。

從不同的角度來看,我認為將任意業務邏輯與Dagger創建的組件相結合是一個糟糕的主意,因為它具有簡單性和正確性:

  • 這樣做可能違反SRP或關注點分離:依賴項注入的既定優勢之一是將對象創建邏輯與其他業務邏輯分離。 允許在對象創建組件上添加業務方法應該與在業務組件中使用new一樣不當。 (是否應該通過DI圖提供每個對象都是另一天的有爭議的話題。)
  • 如果您堅持最佳實踐,並避免了構造函數/工廠/提供者的副作用和其他“繁瑣的工作”,那么您應該能夠對Component方法中可能發生的事情和可能發生的事情做出明確的推理。 在Component上允許使用任意方法(尤其是void方法)將與該做法相反。
  • 如果您的應用程序使用單獨的粒度庫而不是整體式編譯步驟,則從其自己的對象圖中使用Component可能會使不引入依賴周期而難以構建。 當然,Dagger確實允許在其自己的圖形中注入組件,但是不計后果地這樣做可能會在以后導致循環問題。
  • 使用現有結構很容易表示相似的用例-像Louis Wasserman所評論的那樣通過圖提供Runnable,或者注入類似的單一用途的對象來保存該方法-使得將任意實現都保留在Component之外似乎不會導致功能或可讀性的重大損失。 最糟糕的是,您需要一個額外的方法調用才能到達您定義的類。

如果要按原樣進行遷移,我將在HelloWorldApp旁邊創建一個名為HelloWorldMethods的類,並將將放置在HelloWorldApp上的所有方法轉移到該類上。 如果這是Spring遷移中的常見模式,則您甚至可以為其定義一個本地約定(例如FooComponent隨FooMethods或FooUtil附帶)。 最后,如果您想隱藏Dagger實現的詳細信息(如在外部API中一樣),您還可以編寫自己的類來包裝和使用Component,將重要的方法委派給內部Component並提供所需的任意實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM