Provide multiple service implementations via ContextFunction? [message #1745467] |
Tue, 11 October 2016 09:06 |
Roman Zimmer Messages: 27 Registered: November 2010 |
Junior Member |
|
|
Hey @ll,
for our e4 RCP application I created several plugins. One should be responsible to provide domain specific service implementations (interface + implementation class), which should be injectable in the other plugins. I started with one service, which I could successfully add to the MApplication's context using a ContextFunction as described in Eclipse 4 Context Functions - Tutorial. This works as expected, the service is successfully injected for example in the UI plugin.
Now to my question: Is it possible to provide multiple services via the plugin's component.xml, e.g. by declaring multiple ContextFunctions? If yes, how do you do it?
I could think of these approaches:
- "Hijack" the plugin's ContextFunction and register multiple service implementations at the IEclipseContext instance of the MApplication'. But which object is to return via compute()?
- Create different components, each providing exactly one service implementation. This feels like too much overhead for the given use case...
I'm grateful for every hint or suggestions to best practices! Thank you in advance!
PS: Eclipse Neon is used as development and target platform for the RCP application.
[Updated on: Tue, 11 October 2016 09:17] Report message to a moderator
|
|
|
Re: Provide multiple service implementations via ContextFunction? [message #1745475 is a reply to message #1745467] |
Tue, 11 October 2016 10:54 |
Dirk Fauth Messages: 2903 Registered: July 2012 |
Senior Member |
|
|
First, it is a bad practice to keep interface and implementation class in the same bundle/plugin.
Second, why do you use a ContextFunction for this? Do you need access to other objects available in the context (e.g. application model components)? Otherwise simply create multiple different services.
Regarding your questions:
Quote:Is it possible to provide multiple services via the plugin's component.xml
One component XML file, one service. A ContextFunction is only a special type of declarative service that supports access to the EclipseContext. So the answer is no. There is nothing like a "plugin's context.xml", but you can have multiple component XML files to specify multiple services in one plugin.
Quote:"Hijack" the plugin's ContextFunction and register multiple service implementations at the IEclipseContext instance of the MApplication'.
That doesn't make sense. You can not register multiple service instances in the EclipseContext. You can register multiple services in the ServiceRegistry. But in fact you could use a ContextFunction to determine the service that should be returned based on a context value. That is the purpose of a ContextFunction, to deliver an object based on the context.
Quote:Create different components, each providing exactly one service implementation. This feels like too much overhead for the given use case.
Well, when you are talking about components, than it should be exactly like that. But then there is no need for a ContextFunction! In that case you would simply create declarative service implementations that are registered in the ServiceRegistry. I'm not sure about your use case, as you didn't specified it, but for me it sounds like you don't need a ContextFunction. You need declarative services!
If you specify multiple service implementations for the same interface you would still have the issue which service would be returned on injection in the UI (part, handler, etc.). Using Eclipse injection mechanisms the answer would be to use a ContextFunction.
|
|
|
Re: Provide multiple service implementations via ContextFunction? [message #1745486 is a reply to message #1745475] |
Tue, 11 October 2016 13:28 |
Roman Zimmer Messages: 27 Registered: November 2010 |
Junior Member |
|
|
Thanks for your clarifying words! I'm relatively new to these technologies and as it seems I misunderstood and mixed up some concepts.
My use case is that I want several (service) objects I define in one bundle/plugin to be injectable in a RCP application and other plugins using e4 DI via @Inject or ContextInjectionFactory.inject().
For example, let's say I have the following plugin which should provide the service instances, optionally as singletones:
org.example.services
├── plugin.xml
├── META-INF
│ └── MANIFEST.MF
└── src
└── org
└── example
└── services
├── DomainModelServiceImpl.java
├── DomainModelService.java
├── TestSpecificationServiceImpl.java
└── TestSpecificationService.java
(BTW: Consider this just for simplicity, you're totally right about keeping interfaces and implementations together in one bundle is bad practice!)
In the the e4 RCP application bundle I want to use instances like this:
public class ModelHandler {
@Inject
private DomainModelService domainModelService;
@PostConstruct
public void init() {
Model model = domainModelService.createNewModel("NEW");
....
}
}
or
public class AddTestCaseHandler {
@Execute
public void execute(@Optional @Named(IServiceConstants.ACTIVE_SELECTION) TopicCluster topicCluster,
TestSpecificationService testSpecificationService) {
TestCase newTestCase = testSpecificationService.createTestCase(topicCluster);
EditorHelper.openModelElement(newTestCase);
}
...
}
Then there might be other non-ui bundles, where I want to access these instances via @Inject, ContextInjectionFactory.inject() or ContextInjectionFactory.make(TestSpecificationService.class, context).
I guessed that this is only possible if I register these instances at the IEcpliseContext and to get access to the context I should implement it using ContextFunction. So if I get you right, in org.example.services I just could add more component*.xml files under OSGI-INF to make these service classes injectable. Would just adding @Creatable to the service classes without using ContextFunction at all have done the trick, too?
Nevertheless, I have to dig deeper into ServiceRegistry, declarative services and obviously ContextFunctions, I guess.
Thanks again for your support, very appreciated!
[Updated on: Tue, 11 October 2016 13:33] Report message to a moderator
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.04589 seconds