Guice : 如何自定义第三方模块的绑定?
Guice : How to customize the bindings of a third-party Module?
假设我有一个 ThirPartyModule
第三方模块,它绑定了很多我可以在我的应用程序中使用的组件:
Injector guice = Guice.createInjector(new MyAppModule(), new ThirPartyModule());
如果我想修改用于该模块中某些绑定的实现 classes,最好的方法是什么?
例如,假设 ThirPartyModule
执行绑定:
bind(WidgetInterface.class).to(DefaultWidgeImpl.class).in(Scopes.SINGLETON);
我希望能够将 DefaultWidgeImpl
class 更改为 MyWidgetImpl
class。我知道我可以使用覆盖模块,并简单地重新绑定 WidgetInterface
键。但是,如果 ThirPartyModule
使用相同的 小部件实现 绑定 很多 东西呢?我可能不想重新绑定它们中的每一个!
所以我正在尝试找到最佳解决方案,以便能够指定要使用的实现 class,而无需重新绑定依赖于它的所有组件。
我想 ThirPartyModule
可以先创建一个 getter 方法来实现 class :
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;
}
});
我还考虑过将实现 class 传递给模块的构造函数:
Injector guice = Guice.createInjector(new MyAppModule(), new ThirPartyModule(MyWidgetImpl.class));
我想知道是否有可接受的模式来定制此类第三方模块?假设我 可以 要求以特定方式编写模块,如果它有助于它们可定制的话。
我会这样做:
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
键,您只需要覆盖那个绑定。
假设我有一个 ThirPartyModule
第三方模块,它绑定了很多我可以在我的应用程序中使用的组件:
Injector guice = Guice.createInjector(new MyAppModule(), new ThirPartyModule());
如果我想修改用于该模块中某些绑定的实现 classes,最好的方法是什么?
例如,假设 ThirPartyModule
执行绑定:
bind(WidgetInterface.class).to(DefaultWidgeImpl.class).in(Scopes.SINGLETON);
我希望能够将 DefaultWidgeImpl
class 更改为 MyWidgetImpl
class。我知道我可以使用覆盖模块,并简单地重新绑定 WidgetInterface
键。但是,如果 ThirPartyModule
使用相同的 小部件实现 绑定 很多 东西呢?我可能不想重新绑定它们中的每一个!
所以我正在尝试找到最佳解决方案,以便能够指定要使用的实现 class,而无需重新绑定依赖于它的所有组件。
我想 ThirPartyModule
可以先创建一个 getter 方法来实现 class :
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;
}
});
我还考虑过将实现 class 传递给模块的构造函数:
Injector guice = Guice.createInjector(new MyAppModule(), new ThirPartyModule(MyWidgetImpl.class));
我想知道是否有可接受的模式来定制此类第三方模块?假设我 可以 要求以特定方式编写模块,如果它有助于它们可定制的话。
我会这样做:
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
键,您只需要覆盖那个绑定。