Jump to: navigation, search

Recommenders/ExtensionFactory

The ExtensionFactory class can be found in bundle org.eclipse.recommenders.commons.injection. The ExtensionFactory is used to automatically invoke dependency injection on classes defined as extensions. In concrete, the ExtensionFactory instantiates the extension using guice for dependency injection. This enables you to use @Inject annotations on your fields or on the constructor.

Let's look at an example:

public class MyView extends ViewPart {
 
   @Inject
   private Service service;
 
   @Inject
   public MyView(ConfigurationObject configuration) {
 
...

As you can see the improvement is that you can define needed objects in the constructor, because you don't rely on a default constructor anymore and you completely hide the code requesting injection on your fields.


How to use the ExtensionFactory

Let's discuss this on an example. Below is the definition of the RecommendationsView:

<view
	category="org.eclipse.recommenders.rcp.category.views"
	class="org.eclipse.recommenders.internal.rcp.views.recommendations.RecommendationsView"
	icon="icons/full/view16/slice.gif"
	id="org.eclipse.recommenders.rcp.views.RecommendationsView"
	name="Recommendations">
</view>

To enable automatic dependency injection on RecommendationsView we have to change to the configration to this one:

<view
	category="org.eclipse.recommenders.rcp.category.views"
	class="org.eclipse.recommenders.injection.ExtensionFactory:org.eclipse.recommenders.internal.rcp.views.recommendations.RecommendationsView"
	icon="icons/full/view16/slice.gif"
	id="org.eclipse.recommenders.rcp.views.RecommendationsView"
	name="Recommendations">
</view>

The only thing that changed here is, that we added a prefix to the class value. We have added org.eclipse.recommenders.injection.ExtensionFactory separated by : from the definition of the class we want to get the injection target.

And that's it. At least we thought that for the first time. But there are configuration cases where the separation is not done by eclipse. We observed these cases on injecting a builder or a nature. If we look at a definition of such a nature we see, that the class is defined one step deeper in the xml hierarchy:

<runtime>
 <run class="org.eclipse.recommenders.internal.rcp.RecommendersNature">
 </run>
</runtime>

But we are able to define parameters in these cases, so you have to change the configuration like done in this example:

<runtime>
 <run class="org.eclipse.recommenders.injection.ExtensionFactory">
	  <parameter name="class" value="org.eclipse.recommenders.internal.rcp.RecommendersNature" />
 </run>
</runtime>

How it works

The definition of ExtensionFactory as class tells eclipse to instantiate the ExtensionFactory, not the View as it would be done normaly. The ExtensionFactory implements the interface IExecutableExtension, which allows it to access the configurations we made. In this configuration the implementation class of the extension is given, so the factory is able to instantiate this class using the Injector of InjectionService (located in the same package). To tell eclipse that it should not use the ExtensionFactory instance as extension we implement the interface IExecutableExtensionFactory too. If any extension class implements this interface it is treated as a factory class which should create the extension.