|
Re: Provide multiple service implementations via ContextFunction? [message #1745475 is a reply to message #1745467] |
Tue, 11 October 2016 06:54   |
Eclipse User |
|
|
|
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 09:28   |
Eclipse User |
|
|
|
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 09:33] by Moderator
|
|
|
|
|
Re: Provide multiple service implementations via ContextFunction? [message #1782874 is a reply to message #1745491] |
Fri, 02 March 2018 13:56  |
Eclipse User |
|
|
|
One should be able to define a IContextFunction Component with multiple service.context.key values:
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="com.multi.service.context.function">
<implementation class="com.multi.service.MultiServiceContextFunction"/>
<service>
<provide interface="org.eclipse.e4.core.contexts.IContextFunction"/>
</service>
<property name="service.context.key">
com.multi.service1
com.multi.service2
</property>
</scr:component>
It appears that simple changes to EclipseContextOSGi where it references SERVICE_CONTEXT_KEY could make this work. As it is, the code assumes there is only one service.context.key value.
It should not be too difficult to imagine a use case where this is desirable, if only for convenience.
|
|
|
Powered by
FUDForum. Page generated in 0.03442 seconds