2013-03-12 51 views
2

我的Java代碼使用多個接口實現(下面的示例中是BugTemplate),其中綁定的實現取決於上下文。Guice中的多個實現間接依賴

在Guice中,我相信用BindingAnnotations來完成這個工作是正確的。但是,我的用例與典型示例不同,因爲上下文從接口的實現中移除了一個級別。

總結可能的依賴關係:

FooBugFinder - > BugFiler - > FooBugTemplate

BarBugFinder - > BugFiler - > BarBugTemplate

示例代碼:

class FooBugFinder { 
    // ... 
    public findBugsAndFileThem() { 
    List<Bug> bugs = findBugs(); 
    bugFiler.fileBugs(bugs); 
    } 
    @Inject 
    FooBugFinder(BugFiler bugFiler) { 
    // BugFiler should have been instantiated with a FooBugTemplate. 
    this.bugFiler = bugFiler; 
    } 
} 

class BugFiler { 
    // ... 
    public fileBugs(List<Bug> bugs) { 
    List<FormattedBugReport> bugReports = bugTemplate.formatBugs(bugs); 
    fileBugReports(bugReports); 
    } 
    @Inject 
    BugFiler(BugTemplate bugTemplate) { 
    // The specific implementation of BugTemplate is context-dependent. 
    this.bugTemplate = bugTemplate; 
    } 
} 

interface BugTemplate { 
    List<FormattedBugReport> formatBugs(List<Bug> bugs); 
} 

class FooBugTemplate implements BugTemplate { 
    @Overrides 
    List<FormattedBugReport> formatBugs(List<Bug> bugs) { 
    // ... 
    } 
} 

我首先想到的是註釋構造函數如下:

FooBugFinder(@Foo BugFiler bugFiler) { } 

但是,怎麼會知道的吉斯注入參數BugFiler的構造方法時應用該註釋?

換句話說,FooBugFinder需要一個使用FooBugTemplate實例化的BugFiler實例。 BarBugFinder需要一個使用BarBugTemplate實例化的BugFiler實例。

任何想法?

abstract class BugFilerModule extends PrivateModule { 
    private final Class<? extends Annotation> annotation; 

    BugFilerModule(Class<? extends Annotation> annotation) { 
    this.annotation = annotation; 
    } 

    @Override protected void configure() { 
    bind(BugFiler.class).annotatedWith(annotation).to(BugFiler.class); 
    expose(BugFiler.class).annotatedWith(annotation); 
    bindBugTemplate(); 
    } 

    abstract void bindBugTemplate(); 
} 

然後,當你創建你的噴油器:

Injector injector = Guice.createInjector(
     new BugFilerModule(Foo.class) { 
      @Override void bindBugTemplate() { 
      bind(BugTemplate.class).to(FooBugTemplate.class); 
      } 
     }, 
     new BugFilerModule(Bar.class) { 
      @Override void bindBugTemplate() { 
      bind(BugTemplate.class).to(BarBugTemplate.class); 
      } 
     }, 
     /* other modules */); 

,您可以創建在一個FooBugFinder

+0

我相信這就是所謂的「機器人腿」問題。查看https://code.google.com/p/google-guice/wiki/FrequentlyAskedQuestions,然後向下滾動到「如何構建兩個相似但略有不同的對象樹?」 – 2013-03-12 21:18:36

回答

1

您可以通過創建一個公開的註釋BugFiler對象的私人模塊做你建議的方式:

public class FooBugFinder { 
    @Inject 
    public FooBugFinder(@Foo BugFiler fooBugFiler) { 
    ... 
    } 
} 
+0

謝謝 - 語法有點麻煩,但它確實有效。 – frankadelic 2013-03-12 23:48:16