2016-12-06 73 views
1

比方说,我有一个结合许多组件,我可以在我的应用程序,然后使用一个ThirPartyModule第三方模块:如果我想修改该模块用于一些绑定实现类Guice:如何自定义第三方模块的绑定?

Injector guice = Guice.createInjector(new MyAppModule(), new ThirPartyModule()); 

,什么是最好的方法?

例如,假设ThirPartyModule执行该绑定:

bind(WidgetInterface.class).to(DefaultWidgeImpl.class).in(Scopes.SINGLETON); 

,我希望能够改变DefaultWidgeImplMyWidgetImpl类。我知道我可以使用重写模块,只需重新绑定WidgetInterface键。但是,如果ThirPartyModule结合很多的使用同一widget实现东西呢?我可能不想要重新绑定他们每个人!

所以我试图找到最好的解决方案,能够指定要使用的实现类,而不必重新绑定所有组件取决于它。

我想ThirPartyModule可以先创建一个实现类getter方法:

bind(WidgetInterface.class).to(getWidgetImpClass()).in(Scopes.SINGLETON); 

protected Class<? extends WidgetInterface> getWidgetImpClass() { 
    return DefaultWidgeImpl.class; 
} 

然后应用程序可以覆盖getWidgetImpClass()方法:

Injector guice = Guice.createInjector(new MyAppModule(), new ThirPartyModule() { 
    @Override 
    protected Class<? extends WidgetInterface> getWidgetImpClass() { 
     return MyWidgetImpl.class; 
    } 
}); 

我也不过关于通过实现类到模块的构造函数:

Injector guice = Guice.createInjector(new MyAppModule(), new ThirPartyModule(MyWidgetImpl.class)); 

我想知道是否有可接受的模式来自定义此类第三方模块?假设我可以要求模块以特定的方式写入,如果它有助于它们的定制。

回答

2

这是我会怎么做:

public class ThirdPartyModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     // CoolWidget -- 
     //    \ 
     //    > WidgetInterface -> DefaultWidgetImpl 
     //   /
     // AwesomeWidget 

     OptionalBinder.newOptionalBinder(binder(), WidgetInterface.class) 
       .setDefault() 
       .to(DefaultWidgetImpl.class); 

     bind(CoolWidget.class).to(WidgetInterface.class); 
     bind(AwesomeWidget.class).to(WidgetInterface.class); 
     // etc. 
    } 
} 

public class MyAppModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     OptionalBinder.newOptionalBinder(binder(), WidgetInterface.class) 
       .setBinding() 
       .to(CustomWidgetImpl.class); 
    } 
} 

通过使所有绑定间接经过WidgetInterface键,你只需要越过一个结合。

+0

哇,我不得不承认,我甚至不知道'OptionalBinder',它确实很方便......谢谢! – electrotype

+0

我不认为单身人士与'@Named(“default”)'有什么关系。如果'CustomWidgetImpl'必须是单身,那么用'@ Singleton'或者'.in(Singleton.class)'标记它。 –

+0

无论如何,你可能不需要'@Named(“default”)'。它只是'{CoolWidget,AwesomeWidget} - > WidgetInterface - > DefaultWidgetImpl'。 –