【发布时间】:2011-12-16 16:36:34
【问题描述】:
我开始越来越喜欢 OSGi 服务,并希望将我的更多组件实现为服务。现在我正在寻找最佳实践,尤其是对于 UI 组件。
对于听众关系,我使用白板模式,恕我直言,这是最好的方法。但是,如果我想要的不仅仅是通知,我可以考虑三种可能的解决方案。
想象以下场景:
interface IDatabaseService {
EntityManager getEntityManager();
}
[1] 白板图案 - 带自我设置服务
我会创建一个新的服务接口:
interface IDatabaseServiceConsumer {
setDatabaseService(IDatabaseService service);
}
并使用像这样的 bindConsumer 方法创建声明性 IDatabaseService 组件
protected void bindConsumer(IDatabaseServiceConsumer consumer) {
consumer.setDatabaseService(this);
}
protected void unbindConsumer(IDatabaseServiceConsumer consumer) {
consumer.setDatabaseService(null);
}
这种方法假设只有一个 IDatabaseService。
[更新] 用法如下所示:
class MyUIClass ... {
private IDatabaseService dbService;
Consumer c = new IDatabaseServiceConsumer() {
setDatabaseService(IDatabaseService service) {
dbService = service;
}
}
Activator.registerService(IDatabaseServiceConsumer.class,c,null);
...
}
[2] 让我的课程成为一项服务
像一个类的图像
公共类 DatabaseEntryViewer 扩展 TableViewer
现在,我只需为我的 IDatabaseService 添加绑定/取消绑定方法并添加一个 component.xml 并添加我的 DatabaseEntryViewer。这种方法假设有一个非参数构造函数,并且我通过 OSGi-Service-Factory 创建 UI 组件。
[3] 经典方式:ServiceTracker
在我的 Activator 中注册静态 ServiceTracker 并访问它的经典方法。使用跟踪器的类必须处理动态。
目前我更喜欢第一种,因为这种方法不会使对象创建复杂化,并且可以将 Activator 从无休止的静态 ServiceTracker 中拯救出来。
【问题讨论】:
-
不明白,为什么不将IDatabaseService“注入”(绑定)到IDatabaseServiceConsumer?
-
嗨 Ivan,目前我们没有使用任何 DI 框架,例如 Spring DI 或 Google juice。对于 Eclipse RCP 开发来说,这是一条艰难的路吗?
-
你还没有说出你真正想要达到的目标。所有三种方法都可能有效,但由于没有上下文,因此无法说出最佳方法。
-
...话虽如此,第一种方法似乎没有意义。事实上它倒退了,你为什么要将消费者注入提供者?关于你对伊万的问题......你为什么认为你需要 Spring 或 Guice 才能进行注射?声明式服务为您提供注入(又名“绑定”)。
-
我的主要目标是在由 Eclipse RCP 框架实例化的 UI 组件中使用我的服务。这就是为什么我不能使用声明式服务。第一种方法是“注入”服务的不那么优雅的解决方法。我读了一些关于 Spring Dependency Injection 的文章,发现 DI 机制的工作原理类似,恕我直言,接近 2。
标签: service osgi whiteboard declarative-services