2015-06-26 44 views
6

假設我有一個第三方類,如下所示:如何幫助輔助依賴項?

public class MyObject { 
    @Inject 
    public MyObject(Foo foo, Bar bar) { ... } 
} 

現在假設我有一個工廠接口,像這樣:

public interface MyObjectFactory { 
    public MyObject build(Bar bar); 
} 

的想法是,我希望有一個MyObjectFactory是建立一個MyObject對於固定的Foo - 也就是說,從外部實質上在註解對Bar構造函數參數添加。當然,手動執行MyObjectFactory始終是可能的:

public class MyObjectFactoryImpl implements MyObjectFactory { 
    @Inject private Provider<Foo> foo; 

    @Override 
    public MyObject build(Bar bar) { return new MyObject(foo.get(), bar); } 
} 

但是,讓我們說,有需要我有吉斯建立MyObject實例條件 - 例如,方法攔截器。這似乎是對「注射進樣器」的作業:

public class MyObjectFactoryImpl implements MyObjectFactory { 
    @Inject private Injector injector; 

    @Override 
    public MyObject build(Bar bar) { 
     Injector child = injector.createChildInjector(new AbstractModule() { 
      @Override 
      protected void configure() { 
       bind(Bar.class).toInstance(bar); 
       // Set up method interceptors for MyObject here... 
      } 
     }); 
     return child.getInstance(MyObject.class); 
    } 
} 

這聽起來很邪惡,鍋爐板,Y,所以如果有任何替代實現方式和/或辦法有吉斯產生我想知道工廠impl。

回答

1

首先,這是罕見的,你想成爲合格的MyObject情況下在你的班上週圍正是您所描述的原因。你無法控制它們,所以你不能添加@Assisted註釋,你不能添加方法攔截器等。另外,當你想換出不同的實現的第三方庫時會發生什麼?

因此,您應該將MyObject包裝到另一個對象中。

// **Please** choose better names than this in your real code. 
public class MyWrapperBackedByMyObject implements MyWrapperInterface { 
    private final MyObject delegate; 

    @Inject 
    MyWrapperObject(Foo foo, @Assisted Bar bar) { 
     delegate = new MyObject(foo, bar); 
    } 

    @NotOnWeekends // Example of how you might do method interception 
    public void orderPizza() { 
     delegate.orderPizza(); 
    } 
} 

然後,取出到MyObject所有引用整個代碼,使用的命名約定我上面描述,應該只有引用MyWrapperInterface

-1

實際上是。看看Assisted Inject

包括

 <dependency> 
      <groupId>com.google.inject.extensions</groupId> 
      <artifactId>guice-assistedinject</artifactId> 
      <version>${guice.version}</version> 
     </dependency> 

更新注射輔助

public class MyInjectedObject extends MyObject implements MyIntf { 
@Inject 
public MyObject(Foo foo, @Assisted Bar bar) { super(foo,bar); } 
} 

你必須增加一個接口:

public interface MyIntf {} 

在你的模塊綁定通用的工廠到您界面

install(new FactoryModuleBuilder() 
      .implement(MyIntf.class, MyInjectedObject.class) 
      .build(MyObjectFactory.class) 
); 

現在你可以在任何你想要的地方注入MyObjectFactory。所有的

MyObject obj = myObjectFactory.build(bar); 
+0

同樣,由於'MyObject'是第三方,我不能修改'MyObject';否則我只能使用普通的老式輔助注射。 –

+1

將它包裹到另一個對象中。 –