Home » Eclipse Projects » Eclipse 4 » Trying to get E4 services(I guess I'm not understanding injection)
Trying to get E4 services [message #1016293] |
Tue, 05 March 2013 21:22 |
|
So there is an E4 service I want to use in a class. Everything I read says that I get it by using injection. For example:
@Inject IStylingEngine mStyler;
However, this code only seems to work in classes that are directly invoked by the E4 layer. I.e. if I have a class that is a Class URI for a Part, then mStyler is correctly set. However, if that class uses other UI controls, and further down, one of those controls uses this code to get at the service, it is never set.
Following some other posts, I tying using E4Workbench.getServiceContext.get(XXX) or even creating an IEclipseContext from my bundle. But these always return null when I ask it for the service.
So is there any way I can get a service from an arbitrary point of code? It's going to make things awfully ugly if I have to resolve it at the point my code touches the framework and then pass it down the constructor stacks.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jo Grant, Senior Software Engineer
Admin and Config Console Architect
OpenPages, IBM
|
|
| |
Re: Trying to get E4 services [message #1016479 is a reply to message #1016302] |
Wed, 06 March 2013 15:41 |
|
Hey Tom,
Thanks for the response. That will come in useful. Someday. But since you need an IEclipseContext before you can call ContextInjectionFactory.make(), I'm still stuck as described. I don't know how to get the default IEclipseContext to pass in.
I've tried the following:
class Test
{
@Inject
public IStylingEngine mStyler;
}
invoked by:
try
{
IEclipseContext context1 = E4Workbench.getServiceContext();
Test t1 = ContextInjectionFactory.make(Test.class, context1);
if (t1.mStyler != null)
System.out.println("Case 1 works!");
else
System.out.println("Case 1 fails");
}
catch (Exception e)
{
e.printStackTrace();
System.out.println("case 1 fails");
}
try
{
IEclipseContext context2 = EclipseContextFactory.getServiceContext(Activator.getContext());
Test t2 = ContextInjectionFactory.make(Test.class, context2);
if (t2.mStyler != null)
System.out.println("Case 2 works!");
else
System.out.println("Case 2 fails");
}
catch (Exception e)
{
e.printStackTrace();
System.out.println("case 2 fails");
}
try
{
Test t3 = ContextInjectionFactory.make(Test.class, null);
if (t3.mStyler != null)
System.out.println("Case 3 works!");
else
System.out.println("Case 3 fails");
}
catch (Exception e)
{
e.printStackTrace();
System.out.println("case 3 fails");
}
All of these report failure.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jo Grant, Senior Software Engineer
Admin and Config Console Architect
OpenPages, IBM
|
|
|
Re: Trying to get E4 services [message #1016497 is a reply to message #1016479] |
Wed, 06 March 2013 16:54 |
Eclipse User |
|
|
|
What does the invoker look like? There is no default IEclipseContext. There are a lot IECs (the context hierarchy) and an active one. The idea is that when you do CIF.make(C,IEC); all the @Inject's in C are looked up in the IEC context and it's parents. So this invoker guy is part of your application or some out of container JUnit test or something else?
|
|
|
Re: Trying to get E4 services [message #1016516 is a reply to message #1016497] |
Wed, 06 March 2013 18:07 |
|
The problem is that this depth of code can be arrived at through a variety of means.
I have need of different services throughout my code, but for this, specific, example I have a Composite that creates a whole bunch of UI and wants to style it. (I am converting it from org.eclipse.ui.forms to being e4 CSS driven.)
Sometimes this Composite is constructed in a MPart, but other times I use it directly in a Dialog. (The dialog is launched by clicking on a button with is nested several layers down in a MPart.)
I understand that for a lot of things you want a context very local to the model element in question. But my understanding is that services are generally connected at the very top context, and are, pretty much, universal throughout. If they are, essentially, global, I'd like to be able to access them globally.
[For now I have an ugly hack. I have a startup handler, which gets passed an IEclipseContext. It passes this value to my style control code. Later, when the style control code is requested by the Composite to apply a style, it gets the IStylingEngine from the IEclipseContext it was initialized with. It works. But I'm pretty sure this is not "best practice".]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jo Grant, Senior Software Engineer
Admin and Config Console Architect
OpenPages, IBM
|
|
| |
Re: Trying to get E4 services [message #1016651 is a reply to message #1016516] |
Thu, 07 March 2013 09:15 |
Thomas Schindl Messages: 6651 Registered: July 2009 |
Senior Member |
|
|
Best pratice is that *ALL* instances are created through CIF.make() why
can't you create the Dialog, .... also through the DI-Container. I don't
see a reason you can't do this.
Tom
Am 06.03.13 19:07, schrieb Jo Jaquinta:
> The problem is that this depth of code can be arrived at through a
> variety of means.
> I have need of different services throughout my code, but for this,
> specific, example I have a Composite that creates a whole bunch of UI
> and wants to style it. (I am converting it from org.eclipse.ui.forms to
> being e4 CSS driven.)
> Sometimes this Composite is constructed in a MPart, but other times I
> use it directly in a Dialog. (The dialog is launched by clicking on a
> button with is nested several layers down in a MPart.)
> I understand that for a lot of things you want a context very local to
> the model element in question. But my understanding is that services are
> generally connected at the very top context, and are, pretty much,
> universal throughout. If they are, essentially, global, I'd like to be
> able to access them globally.
>
> [For now I have an ugly hack. I have a startup handler, which gets
> passed an IEclipseContext. It passes this value to my style control
> code. Later, when the style control code is requested by the Composite
> to apply a style, it gets the IStylingEngine from the IEclipseContext it
> was initialized with. It works. But I'm pretty sure this is not "best
> practice".]
|
|
|
Re: Trying to get E4 services [message #1016655 is a reply to message #1016651] |
Thu, 07 March 2013 09:27 |
Eclipse User |
|
|
|
@Tom, I think his issue is that he doesn't want to drag down the IEC which has to be supplied to CIF#make.
If you don't want to extend this context hierarchy downards then I think, theoretically, you can access a top level context and traverse its children until you find a suitable context. But still I think that letting the DI container ( creating what you need with CIF#make) do the instantiations is a better idea, despite the depth.
I'm not sure I fully understand your issue but I hope this helps. Also here's a simplified diagram about the context hierarchy in this slideshow http://www.slideshare.net/smcela/eclipse-4-context-functions
|
|
| |
Re: Trying to get E4 services [message #1016749 is a reply to message #1016651] |
Thu, 07 March 2013 14:52 |
|
Quote:Best pratice is that *ALL* instances are created through CIF.make() why
can't you create the Dialog, .... also through the DI-Container. I don't
see a reason you can't do this.
Well, to do this, it would end up being something like this.
My part would have to create it's main Composite extended panel via make. That panel would have to create the launcher sub-panel via make. The launcher, catching the button click, would have to create the Dialog via make. Then the Dialog, when creating it's Composite extended panel, would have to create it via make(). THEN that panel could access the style object to add CSS styling.
I appreciate in the purest sense that this is the "correct" way to do things. But in a pragmatic sense, that's an awful lot of trouble to go through just to apply some CSS styling and use a service that is going to be, pretty much, global anyway. When you add in the fact that in most cases all of the non-model SWT level code is being ported over from a non-e4 environment, it's a rather large burden of work and changes necessary in order to make use of one part of e4.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jo Grant, Senior Software Engineer
Admin and Config Console Architect
OpenPages, IBM
|
|
|
Re: Trying to get E4 services [message #1016756 is a reply to message #1016749] |
Thu, 07 March 2013 15:20 |
Thomas Schindl Messages: 6651 Registered: July 2009 |
Senior Member |
|
|
You asked for the correct solution ;-)
Like I already outlined what you expect to be a singleton is from the
frameworks point of view not a singleton (I gave you the Vaadin/RAP
usecase already).
Please note that we are publishing the IWorkbench in 4.3 as an
OSGi-Service so you can get access to the instance query the OSGi-Registry.
You are free to creating singletons to shorten call paths if you think
they are the better solution but the framework can't and won't hopefully
provide it.
Tom
Am 07.03.13 15:52, schrieb Jo Jaquinta:
> Quote:
>> Best pratice is that *ALL* instances are created through CIF.make() why
>> can't you create the Dialog, .... also through the DI-Container. I don't
>> see a reason you can't do this.
>
> Well, to do this, it would end up being something like this.
> My part would have to create it's main Composite extended panel via
> make. That panel would have to create the launcher sub-panel via make.
> The launcher, catching the button click, would have to create the Dialog
> via make. Then the Dialog, when creating it's Composite extended panel,
> would have to create it via make(). THEN that panel could access the
> style object to add CSS styling.
> I appreciate in the purest sense that this is the "correct" way to do
> things. But in a pragmatic sense, that's an awful lot of trouble to go
> through just to apply some CSS styling and use a service that is going
> to be, pretty much, global anyway. When you add in the fact that in most
> cases all of the non-model SWT level code is being ported over from a
> non-e4 environment, it's a rather large burden of work and changes
> necessary in order to make use of one part of e4.
>
|
|
|
Re: Trying to get E4 services [message #1016757 is a reply to message #1016756] |
Thu, 07 March 2013 15:33 |
|
I understand you have to balance taking a pure approach against things that will be a barrier to adoption.
Thomas Schindl wrote on Thu, 07 March 2013 10:20Please note that we are publishing the IWorkbench in 4.3 as an
OSGi-Service so you can get access to the instance query the OSGi-Registry.
We're targeting 4.3 for our release, so this is fine. I'll keep my hack for now and move over to this when it is available.
In the meantime, I'll see about making sure all new code we write use make().
Thanks for your help!
Jo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jo Grant, Senior Software Engineer
Admin and Config Console Architect
OpenPages, IBM
|
|
|
Goto Forum:
Current Time: Fri Sep 27 05:18:53 GMT 2024
Powered by FUDForum. Page generated in 0.03818 seconds
|