Riena/Getting Started with injecting services and extensions
Riena Project > Getting Started> Getting Started with Injecting Services and Extensions
Getting Started with Injecting Services and Extensions
The Idea of Injecting Services and Extensions in Riena
//// NASCENT ////
Services and extension are the main building blocks of Eclipse RCP applications. There is a long list of discussions and debates about when to use services and when to use extensions. So, we will not add another discussion here. We think that both are useful and have their permission.
One problem with both of them is that using them requires a lot of code that respects their life cycle and is quite error prone. Most of this code is embedded within the code that needs other services or extensions. This approach does not clearly separate the concerns and it makes unit testing more difficult.
A common solution for this problem is the use of dependency injection frameworks such as Spring (http://springframework.org/) or HiveMind (http://hivemind.apache.org/).
Within Riena we are using a simple to use approach to inject services and extensions into objects (pojos). Our approach is code based, i.e. no xml configuration files. Furthermore we are using fluent interfaces (http://en.wikipedia.org/wiki/Fluent_interface) and conventions to simplify the injection definitions. Service injecting examples:
Inject.service("ServiceClazz1").into(target).andStart(context) Inject.service("ServiceClazz2").useFilter(filter).into(target).bind("register").unbind("unregister").andStart(context) Inject.service("ServiceClazz3").useRanking().into(target).bind("register").unbind("unregister").andStart(context)
where ´target´ is the pojo that gets a service injected. When services come and go they will be injected into or removed from the pojos. The method names for injecting/removing can be specified with the bind() and unbind() methods. If they are not defined default method names are assumed.
Extensions get injected into pojos as instances of an interface defined by useType(). If the interface is not defined explicitly it will be retrieved with reflection from the bind method. The interface needs only to declare the getters. Dynamic proxies will be created for this interface which map the data from the extensions. A few simple rules are used for the mapping from extensions to the properties (lightweight xml/java mapping).
Extension injecting examples:
Inject.extension("extpoint1").into(target).andStart(context) Inject.extension("extpoint2").useType(interface).into(target).bind("configure").useTranslation().andStart(context) Inject.extension("extpoint3").expectExactly(1).into(target).andStart(context)