Home » Eclipse Projects » Eclipse 4 » How to get objects be injected into an preference page?
How to get objects be injected into an preference page? [message #1005444] |
Fri, 25 January 2013 13:21 |
Eclipse User |
|
|
|
Hello,
in an Addon I added an object to the EclipseContext:
@PostConstruct
public void register(IEclipseContext context) {
MyClass object = new MyClass();
context.set(MyClass.class, object);
}
Then I have another plugin which contributes a preference page:
public class MyPreferencePage extends PreferencePage implements
IWorkbenchPreferencePage {
@Inject
private MyClass object;
@Inject
private IEclipseContext eclipseContext;
public void init(IWorkbench workbench) {
// init the preference page
}
}
My problem now is that MyClass object always is null. I tried to inject
the eclipseContext but it is null, too. What am I doing wrong?
best regards,
Gilbert
|
|
| | | |
Re: How to get objects be injected into an preference page? [message #1006045 is a reply to message #1005905] |
Tue, 29 January 2013 15:56 |
Eclipse User |
|
|
|
Hmm, is there no possibility to inject something? What kinds of classes
can use injection and what kind of classes cannot?
I thought that this is one big argument for DI: loose coupling between,
e.g., domain and visualisation? This means for my use case that I have
to create some kind of singleton for my domain model which is to be
exposed. THis then can be used by my preference class. So, back to the
Eclipse roots and no step ahead.
best regards,
Gilbert
Tom Schindl wrote:
> the preference pages are not created through DI but they are created
> through the extension registry IIRC so you can't use injection there.
>
> Tom
>
> Am 25.01.13 14:21, schrieb Gilbert Mirenque:
>> Hello,
>> in an Addon I added an object to the EclipseContext:
>>
>> @PostConstruct
>> public void register(IEclipseContext context) {
>> MyClass object = new MyClass();
>> context.set(MyClass.class, object);
>> }
>>
>> Then I have another plugin which contributes a preference page:
>>
>> public class MyPreferencePage extends PreferencePage implements
>> IWorkbenchPreferencePage {
>>
>> @Inject
>> private MyClass object;
>> @Inject
>> private IEclipseContext eclipseContext;
>>
>> public void init(IWorkbench workbench) {
>> // init the preference page
>> }
>> }
>>
>> My problem now is that MyClass object always is null. I tried to inject
>> the eclipseContext but it is null, too. What am I doing wrong?
>>
>> best regards,
>> Gilbert
>>
>
|
|
|
Re: How to get objects be injected into an preference page? [message #1006046 is a reply to message #1006045] |
Tue, 29 January 2013 16:00 |
Thomas Schindl Messages: 6651 Registered: July 2009 |
Senior Member |
|
|
Hi,
You are using the compat.layer which is not using DI, in the end fairly
nothing can use DI in the compat story unless you e.g. use the e4.brigde
which at least provides DI for views and editors.
Tom
Am 29.01.13 16:56, schrieb Gilbert Mirenque:
> Hmm, is there no possibility to inject something? What kinds of classes
> can use injection and what kind of classes cannot?
> I thought that this is one big argument for DI: loose coupling between,
> e.g., domain and visualisation? This means for my use case that I have
> to create some kind of singleton for my domain model which is to be
> exposed. THis then can be used by my preference class. So, back to the
> Eclipse roots and no step ahead.
>
> best regards,
> Gilbert
>
> Tom Schindl wrote:
>> the preference pages are not created through DI but they are created
>> through the extension registry IIRC so you can't use injection there.
>>
>> Tom
>>
>> Am 25.01.13 14:21, schrieb Gilbert Mirenque:
>>> Hello,
>>> in an Addon I added an object to the EclipseContext:
>>>
>>> @PostConstruct
>>> public void register(IEclipseContext context) {
>>> MyClass object = new MyClass();
>>> context.set(MyClass.class, object);
>>> }
>>>
>>> Then I have another plugin which contributes a preference page:
>>>
>>> public class MyPreferencePage extends PreferencePage implements
>>> IWorkbenchPreferencePage {
>>>
>>> @Inject
>>> private MyClass object;
>>> @Inject
>>> private IEclipseContext eclipseContext;
>>>
>>> public void init(IWorkbench workbench) {
>>> // init the preference page
>>> }
>>> }
>>>
>>> My problem now is that MyClass object always is null. I tried to inject
>>> the eclipseContext but it is null, too. What am I doing wrong?
>>>
>>> best regards,
>>> Gilbert
>>>
>>
|
|
|
Re: How to get objects be injected into an preference page? [message #1006151 is a reply to message #1006046] |
Wed, 30 January 2013 09:06 |
Eclipse User |
|
|
|
Hi Tom,
ok I only used PreferencePages in the old 3.x style because I didn't
find instruction on how to implement them in the new e4 style. Is this
possible?
What about plugins not making any contributions to the UI especially to
the e4 workbench model? Don't they have any chance to get something
injected?
best regards,
Gilbert
Tom Schindl wrote:
> Hi,
>
> You are using the compat.layer which is not using DI, in the end fairly
> nothing can use DI in the compat story unless you e.g. use the e4.brigde
> which at least provides DI for views and editors.
>
> Tom
>
> Am 29.01.13 16:56, schrieb Gilbert Mirenque:
>> Hmm, is there no possibility to inject something? What kinds of classes
>> can use injection and what kind of classes cannot?
>> I thought that this is one big argument for DI: loose coupling between,
>> e.g., domain and visualisation? This means for my use case that I have
>> to create some kind of singleton for my domain model which is to be
>> exposed. THis then can be used by my preference class. So, back to the
>> Eclipse roots and no step ahead.
>>
>> best regards,
>> Gilbert
>>
>> Tom Schindl wrote:
>>> the preference pages are not created through DI but they are created
>>> through the extension registry IIRC so you can't use injection there.
>>>
>>> Tom
>>>
>>> Am 25.01.13 14:21, schrieb Gilbert Mirenque:
>>>> Hello,
>>>> in an Addon I added an object to the EclipseContext:
>>>>
>>>> @PostConstruct
>>>> public void register(IEclipseContext context) {
>>>> MyClass object = new MyClass();
>>>> context.set(MyClass.class, object);
>>>> }
>>>>
>>>> Then I have another plugin which contributes a preference page:
>>>>
>>>> public class MyPreferencePage extends PreferencePage implements
>>>> IWorkbenchPreferencePage {
>>>>
>>>> @Inject
>>>> private MyClass object;
>>>> @Inject
>>>> private IEclipseContext eclipseContext;
>>>>
>>>> public void init(IWorkbench workbench) {
>>>> // init the preference page
>>>> }
>>>> }
>>>>
>>>> My problem now is that MyClass object always is null. I tried to inject
>>>> the eclipseContext but it is null, too. What am I doing wrong?
>>>>
>>>> best regards,
>>>> Gilbert
>>>>
>>>
>
|
|
|
Re: How to get objects be injected into an preference page? [message #1006154 is a reply to message #1006151] |
Wed, 30 January 2013 09:18 |
Thomas Schindl Messages: 6651 Registered: July 2009 |
Senior Member |
|
|
Before we proceed let's clarify. Are you working on a pure e4
application or one that does use the compat layer?
Now to your question:
It always depends on how you make contributions. The old extension
registry has no idea about DI and hence stuff contributed through it are
doomed to fail.
I'm not sure what you mean with any contribution to the e4 workbench
model. MContribution-Elements where the instance is created by the e4
framework get stuff injected. If you create instances yourself using
ContextInjectionFactory.make/inject you get stuff injected.
The important thing when talking about DI is always the part code
creating the instances, if this code does not use DI you are almost lost.
Tom
Am 30.01.13 10:06, schrieb Gilbert Mirenque:
> Hi Tom,
> ok I only used PreferencePages in the old 3.x style because I didn't
> find instruction on how to implement them in the new e4 style. Is this
> possible?
> What about plugins not making any contributions to the UI especially to
> the e4 workbench model? Don't they have any chance to get something
> injected?
>
> best regards,
> Gilbert
>
>
>
> Tom Schindl wrote:
>> Hi,
>>
>> You are using the compat.layer which is not using DI, in the end fairly
>> nothing can use DI in the compat story unless you e.g. use the e4.brigde
>> which at least provides DI for views and editors.
>>
>> Tom
>>
>> Am 29.01.13 16:56, schrieb Gilbert Mirenque:
>>> Hmm, is there no possibility to inject something? What kinds of classes
>>> can use injection and what kind of classes cannot?
>>> I thought that this is one big argument for DI: loose coupling between,
>>> e.g., domain and visualisation? This means for my use case that I have
>>> to create some kind of singleton for my domain model which is to be
>>> exposed. THis then can be used by my preference class. So, back to the
>>> Eclipse roots and no step ahead.
>>>
>>> best regards,
>>> Gilbert
>>>
>>> Tom Schindl wrote:
>>>> the preference pages are not created through DI but they are created
>>>> through the extension registry IIRC so you can't use injection there.
>>>>
>>>> Tom
>>>>
>>>> Am 25.01.13 14:21, schrieb Gilbert Mirenque:
>>>>> Hello,
>>>>> in an Addon I added an object to the EclipseContext:
>>>>>
>>>>> @PostConstruct
>>>>> public void register(IEclipseContext context) {
>>>>> MyClass object = new MyClass();
>>>>> context.set(MyClass.class, object);
>>>>> }
>>>>>
>>>>> Then I have another plugin which contributes a preference page:
>>>>>
>>>>> public class MyPreferencePage extends PreferencePage implements
>>>>> IWorkbenchPreferencePage {
>>>>>
>>>>> @Inject
>>>>> private MyClass object;
>>>>> @Inject
>>>>> private IEclipseContext eclipseContext;
>>>>>
>>>>> public void init(IWorkbench workbench) {
>>>>> // init the preference page
>>>>> }
>>>>> }
>>>>>
>>>>> My problem now is that MyClass object always is null. I tried to inject
>>>>> the eclipseContext but it is null, too. What am I doing wrong?
>>>>>
>>>>> best regards,
>>>>> Gilbert
>>>>>
>>>>
>>
|
|
|
Re: How to get objects be injected into an preference page? [message #1006164 is a reply to message #1006154] |
Wed, 30 January 2013 10:06 |
Eclipse User |
|
|
|
Hi Tom,
Tom Schindl wrote:
> Before we proceed let's clarify. Are you working on a pure e4
> application or one that does use the compat layer?
Some of my plugins use the compat layer because they didn't evolve for
long. But the new plugins I develop should be real e4 plugins. That's
why I was asking how to add a preference page in the e4 style.
> Now to your question:
> It always depends on how you make contributions. The old extension
> registry has no idea about DI and hence stuff contributed through it are
> doomed to fail.
Ok
> I'm not sure what you mean with any contribution to the e4 workbench
> model. MContribution-Elements where the instance is created by the e4
> framework get stuff injected. If you create instances yourself using
> ContextInjectionFactory.make/inject you get stuff injected.
Ok, consider the following use case. I have an EMF metamodel (ecore) and
its API generated. All this stuff is contained in a model plugin. Since
I want to separate generated code, from other code, from UI code I have
another plugin which I call registration plugin. This plugin creates my
one and only instance (well, that's my hope) of the aformentioned
metamodel. I only need one instance of this metamodel, so it acts like a
singleton. For this reason I thought I could add this only instance to
the IEclipseContext in my registration plugin and is then available with
DI in other plugins. So I did the following in the registration plugin:
1) I registered a fragment at the extension point
org.eclipse.e4.workbench.model
2) In the fragment I added a Addon like this:
<fragments xsi:type="fragment:StringModelFragment" featurename="addons"
parentElementId="org.eclipse.e4.legacy.ide.application">
<elements xsi:type="application:Addon"
contributionURI="bundleclass://my.reegistration.plugin/MyRegistrationClass"/>
</fragments>
( I omitted all ID's)
3) MyRegistrationClass is implemented as follows:
class MyRegistrationClass{
@PostConstruct
public void register(IEclipseContext context) {
MyModel model = createSingleModelInstance();
context.set(MyModel.class, model);
}
[..]
}
4) I have another UI plugin which should EMF databind the single model
instance in some preference pages. Since I didn't find any hint on how
to realise preference pages with the new e4 style I used the old
mechanism. But as you said the following always resulted in null:
class MyPreferencePage extends PreferencePage implements
IWorkbenchPreferencePage{
@Inject
private MyModel model;
}
This means my UI plugin doesn't make any contribution to the new e4
workbench/application model because old mechanisms are used. But,
imagine this is not a UI plugin but only another "invisible" plugin
intended to make only some analysis on the single metamodel instance I
registered with the registration plugin, how can this instance be
retrieved from the analysis plugin which makes no contributions to the
workbench/application model? Is this possible?
After your hint to the ContextInjectionFactory (which I didn't use so
long) I tried the following in my registration plugin:
class MyRegistrationClass{
@PostConstruct
public void register(IEclipseContext context) {
MyModel model = createSingleModelInstance();
context.set(MyModel.class, model);
context.declareModifiable(MyModel.class);
context.modify(MyModel.class, model);
}
[..]
}
Then I tried to do the following in my "UI" plugin:
class MyPreferencePage extends PreferencePage implements
IWorkbenchPreferencePage{
public void init(IWorkbench workbench) {
Bundle bundle = FrameworkUtil.getBundle(getClass());
BundleContext bundleContext = bundle.getBundleContext();
IEclipseContext context =
EclipseContextFactory.getServiceContext(bundleContext);
MyModel model1 = context.get(MyModel.class);
MyModel model2 = ContextInjectionFactory.make(MyModel.class, context);
}
}
But model1 is null and when trying to make model2 I get an
InjectionException: Could not find satisfiable constructor in MyModel
What disturbs me is that this error message suggests that a new (!)
instance of MyModel is to be created which I don't want.
So do you understand my scenario and can it be solved somehow?
best regards,
Gilbert
>
> The important thing when talking about DI is always the part code
> creating the instances, if this code does not use DI you are almost lost.
>
> Tom
>
> Am 30.01.13 10:06, schrieb Gilbert Mirenque:
>> Hi Tom,
>> ok I only used PreferencePages in the old 3.x style because I didn't
>> find instruction on how to implement them in the new e4 style. Is this
>> possible?
>> What about plugins not making any contributions to the UI especially to
>> the e4 workbench model? Don't they have any chance to get something
>> injected?
>>
>> best regards,
>> Gilbert
>>
>>
>>
>> Tom Schindl wrote:
>>> Hi,
>>>
>>> You are using the compat.layer which is not using DI, in the end fairly
>>> nothing can use DI in the compat story unless you e.g. use the e4.brigde
>>> which at least provides DI for views and editors.
>>>
>>> Tom
>>>
>>> Am 29.01.13 16:56, schrieb Gilbert Mirenque:
>>>> Hmm, is there no possibility to inject something? What kinds of classes
>>>> can use injection and what kind of classes cannot?
>>>> I thought that this is one big argument for DI: loose coupling between,
>>>> e.g., domain and visualisation? This means for my use case that I have
>>>> to create some kind of singleton for my domain model which is to be
>>>> exposed. THis then can be used by my preference class. So, back to the
>>>> Eclipse roots and no step ahead.
>>>>
>>>> best regards,
>>>> Gilbert
>>>>
>>>> Tom Schindl wrote:
>>>>> the preference pages are not created through DI but they are created
>>>>> through the extension registry IIRC so you can't use injection there.
>>>>>
>>>>> Tom
>>>>>
>>>>> Am 25.01.13 14:21, schrieb Gilbert Mirenque:
>>>>>> Hello,
>>>>>> in an Addon I added an object to the EclipseContext:
>>>>>>
>>>>>> @PostConstruct
>>>>>> public void register(IEclipseContext context) {
>>>>>> MyClass object = new MyClass();
>>>>>> context.set(MyClass.class, object);
>>>>>> }
>>>>>>
>>>>>> Then I have another plugin which contributes a preference page:
>>>>>>
>>>>>> public class MyPreferencePage extends PreferencePage implements
>>>>>> IWorkbenchPreferencePage {
>>>>>>
>>>>>> @Inject
>>>>>> private MyClass object;
>>>>>> @Inject
>>>>>> private IEclipseContext eclipseContext;
>>>>>>
>>>>>> public void init(IWorkbench workbench) {
>>>>>> // init the preference page
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> My problem now is that MyClass object always is null. I tried to inject
>>>>>> the eclipseContext but it is null, too. What am I doing wrong?
>>>>>>
>>>>>> best regards,
>>>>>> Gilbert
>>>>>>
>>>>>
>>>
>
|
|
| |
Re: How to get objects be injected into an preference page? [message #1006412 is a reply to message #1006164] |
Thu, 31 January 2013 09:37 |
Thomas Schindl Messages: 6651 Registered: July 2009 |
Senior Member |
|
|
You get NULL in the perference page because you are pushing the value in
the IEclipseContext of the Addon but try to access it on the
ServiceContext which BTW is a different one than the one you have in
your e4 application.
First of all you should push the value to the context of MApplication in
your Addon:
public void register(MApplication app) {
app.getContext().set(MyModel.class, model);
}
Now the problem is to get access to the correct IEclipseContext in your
preference page.
There's a feature request
(https://bugs.eclipse.org/bugs/show_bug.cgi?id=398297) I hope I have
time to work for Kepler which requests to publish applications as
OSGi-Services so that you can get access to the
MApplication-IEclipseContext.
Because this is not yet implemented you somehow need to publish it
yourself in the OSGi-Service-Registry and then retrieve it in your
preference page as an OSGi-Service-Reference.
Tom
Am 30.01.13 11:06, schrieb Gilbert Mirenque:
> Hi Tom,
>
> Tom Schindl wrote:
>> Before we proceed let's clarify. Are you working on a pure e4
>> application or one that does use the compat layer?
> Some of my plugins use the compat layer because they didn't evolve for
> long. But the new plugins I develop should be real e4 plugins. That's
> why I was asking how to add a preference page in the e4 style.
>
>> Now to your question:
>> It always depends on how you make contributions. The old extension
>> registry has no idea about DI and hence stuff contributed through it are
>> doomed to fail.
> Ok
>
>> I'm not sure what you mean with any contribution to the e4 workbench
>> model. MContribution-Elements where the instance is created by the e4
>> framework get stuff injected. If you create instances yourself using
>> ContextInjectionFactory.make/inject you get stuff injected.
> Ok, consider the following use case. I have an EMF metamodel (ecore) and
> its API generated. All this stuff is contained in a model plugin. Since
> I want to separate generated code, from other code, from UI code I have
> another plugin which I call registration plugin. This plugin creates my
> one and only instance (well, that's my hope) of the aformentioned
> metamodel. I only need one instance of this metamodel, so it acts like a
> singleton. For this reason I thought I could add this only instance to
> the IEclipseContext in my registration plugin and is then available with
> DI in other plugins. So I did the following in the registration plugin:
>
> 1) I registered a fragment at the extension point
> org.eclipse.e4.workbench.model
> 2) In the fragment I added a Addon like this:
>
> <fragments xsi:type="fragment:StringModelFragment" featurename="addons"
> parentElementId="org.eclipse.e4.legacy.ide.application">
> <elements xsi:type="application:Addon"
> contributionURI="bundleclass://my.reegistration.plugin/MyRegistrationClass"/>
> </fragments>
> ( I omitted all ID's)
> 3) MyRegistrationClass is implemented as follows:
>
> class MyRegistrationClass{
> @PostConstruct
> public void register(IEclipseContext context) {
> MyModel model = createSingleModelInstance();
> context.set(MyModel.class, model);
> }
> [..]
> }
>
> 4) I have another UI plugin which should EMF databind the single model
> instance in some preference pages. Since I didn't find any hint on how
> to realise preference pages with the new e4 style I used the old
> mechanism. But as you said the following always resulted in null:
>
> class MyPreferencePage extends PreferencePage implements
> IWorkbenchPreferencePage{
>
> @Inject
> private MyModel model;
> }
>
> This means my UI plugin doesn't make any contribution to the new e4
> workbench/application model because old mechanisms are used. But,
> imagine this is not a UI plugin but only another "invisible" plugin
> intended to make only some analysis on the single metamodel instance I
> registered with the registration plugin, how can this instance be
> retrieved from the analysis plugin which makes no contributions to the
> workbench/application model? Is this possible?
>
> After your hint to the ContextInjectionFactory (which I didn't use so
> long) I tried the following in my registration plugin:
>
> class MyRegistrationClass{
> @PostConstruct
> public void register(IEclipseContext context) {
> MyModel model = createSingleModelInstance();
> context.set(MyModel.class, model);
> context.declareModifiable(MyModel.class);
> context.modify(MyModel.class, model);
> }
> [..]
> }
>
> Then I tried to do the following in my "UI" plugin:
>
> class MyPreferencePage extends PreferencePage implements
> IWorkbenchPreferencePage{
> public void init(IWorkbench workbench) {
> Bundle bundle = FrameworkUtil.getBundle(getClass());
> BundleContext bundleContext = bundle.getBundleContext();
> IEclipseContext context =
> EclipseContextFactory.getServiceContext(bundleContext);
> MyModel model1 = context.get(MyModel.class);
> MyModel model2 = ContextInjectionFactory.make(MyModel.class, context);
> }
> }
>
> But model1 is null and when trying to make model2 I get an
> InjectionException: Could not find satisfiable constructor in MyModel
>
> What disturbs me is that this error message suggests that a new (!)
> instance of MyModel is to be created which I don't want.
>
> So do you understand my scenario and can it be solved somehow?
>
> best regards,
> Gilbert
>
>
>>
>> The important thing when talking about DI is always the part code
>> creating the instances, if this code does not use DI you are almost lost.
>>
>> Tom
>>
>> Am 30.01.13 10:06, schrieb Gilbert Mirenque:
>>> Hi Tom,
>>> ok I only used PreferencePages in the old 3.x style because I didn't
>>> find instruction on how to implement them in the new e4 style. Is this
>>> possible?
>>> What about plugins not making any contributions to the UI especially to
>>> the e4 workbench model? Don't they have any chance to get something
>>> injected?
>>>
>>> best regards,
>>> Gilbert
>>>
>>>
>>>
>>> Tom Schindl wrote:
>>>> Hi,
>>>>
>>>> You are using the compat.layer which is not using DI, in the end fairly
>>>> nothing can use DI in the compat story unless you e.g. use the e4.brigde
>>>> which at least provides DI for views and editors.
>>>>
>>>> Tom
>>>>
>>>> Am 29.01.13 16:56, schrieb Gilbert Mirenque:
>>>>> Hmm, is there no possibility to inject something? What kinds of classes
>>>>> can use injection and what kind of classes cannot?
>>>>> I thought that this is one big argument for DI: loose coupling between,
>>>>> e.g., domain and visualisation? This means for my use case that I have
>>>>> to create some kind of singleton for my domain model which is to be
>>>>> exposed. THis then can be used by my preference class. So, back to the
>>>>> Eclipse roots and no step ahead.
>>>>>
>>>>> best regards,
>>>>> Gilbert
>>>>>
>>>>> Tom Schindl wrote:
>>>>>> the preference pages are not created through DI but they are created
>>>>>> through the extension registry IIRC so you can't use injection there.
>>>>>>
>>>>>> Tom
>>>>>>
>>>>>> Am 25.01.13 14:21, schrieb Gilbert Mirenque:
>>>>>>> Hello,
>>>>>>> in an Addon I added an object to the EclipseContext:
>>>>>>>
>>>>>>> @PostConstruct
>>>>>>> public void register(IEclipseContext context) {
>>>>>>> MyClass object = new MyClass();
>>>>>>> context.set(MyClass.class, object);
>>>>>>> }
>>>>>>>
>>>>>>> Then I have another plugin which contributes a preference page:
>>>>>>>
>>>>>>> public class MyPreferencePage extends PreferencePage implements
>>>>>>> IWorkbenchPreferencePage {
>>>>>>>
>>>>>>> @Inject
>>>>>>> private MyClass object;
>>>>>>> @Inject
>>>>>>> private IEclipseContext eclipseContext;
>>>>>>>
>>>>>>> public void init(IWorkbench workbench) {
>>>>>>> // init the preference page
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> My problem now is that MyClass object always is null. I tried to inject
>>>>>>> the eclipseContext but it is null, too. What am I doing wrong?
>>>>>>>
>>>>>>> best regards,
>>>>>>> Gilbert
>>>>>>>
>>>>>>
>>>>
>>
|
|
|
Re: How to get objects be injected into an preference page? [message #1006470 is a reply to message #1006412] |
Thu, 31 January 2013 12:26 |
Eclipse User |
|
|
|
Hi Tom,
ok. Thanks a lot for your patience. Until the feature request is
realised I will use the OSGi Service Registry.
best regards,
Gilbert
Tom Schindl wrote:
> You get NULL in the perference page because you are pushing the value in
> the IEclipseContext of the Addon but try to access it on the
> ServiceContext which BTW is a different one than the one you have in
> your e4 application.
>
> First of all you should push the value to the context of MApplication in
> your Addon:
>
> public void register(MApplication app) {
> app.getContext().set(MyModel.class, model);
> }
>
> Now the problem is to get access to the correct IEclipseContext in your
> preference page.
>
> There's a feature request
> (https://bugs.eclipse.org/bugs/show_bug.cgi?id=398297) I hope I have
> time to work for Kepler which requests to publish applications as
> OSGi-Services so that you can get access to the
> MApplication-IEclipseContext.
>
> Because this is not yet implemented you somehow need to publish it
> yourself in the OSGi-Service-Registry and then retrieve it in your
> preference page as an OSGi-Service-Reference.
>
> Tom
>
> Am 30.01.13 11:06, schrieb Gilbert Mirenque:
>> Hi Tom,
>>
>> Tom Schindl wrote:
>>> Before we proceed let's clarify. Are you working on a pure e4
>>> application or one that does use the compat layer?
>> Some of my plugins use the compat layer because they didn't evolve for
>> long. But the new plugins I develop should be real e4 plugins. That's
>> why I was asking how to add a preference page in the e4 style.
>>
>>> Now to your question:
>>> It always depends on how you make contributions. The old extension
>>> registry has no idea about DI and hence stuff contributed through it are
>>> doomed to fail.
>> Ok
>>
>>> I'm not sure what you mean with any contribution to the e4 workbench
>>> model. MContribution-Elements where the instance is created by the e4
>>> framework get stuff injected. If you create instances yourself using
>>> ContextInjectionFactory.make/inject you get stuff injected.
>> Ok, consider the following use case. I have an EMF metamodel (ecore) and
>> its API generated. All this stuff is contained in a model plugin. Since
>> I want to separate generated code, from other code, from UI code I have
>> another plugin which I call registration plugin. This plugin creates my
>> one and only instance (well, that's my hope) of the aformentioned
>> metamodel. I only need one instance of this metamodel, so it acts like a
>> singleton. For this reason I thought I could add this only instance to
>> the IEclipseContext in my registration plugin and is then available with
>> DI in other plugins. So I did the following in the registration plugin:
>>
>> 1) I registered a fragment at the extension point
>> org.eclipse.e4.workbench.model
>> 2) In the fragment I added a Addon like this:
>>
>> <fragments xsi:type="fragment:StringModelFragment" featurename="addons"
>> parentElementId="org.eclipse.e4.legacy.ide.application">
>> <elements xsi:type="application:Addon"
>> contributionURI="bundleclass://my.reegistration.plugin/MyRegistrationClass"/>
>> </fragments>
>> ( I omitted all ID's)
>> 3) MyRegistrationClass is implemented as follows:
>>
>> class MyRegistrationClass{
>> @PostConstruct
>> public void register(IEclipseContext context) {
>> MyModel model = createSingleModelInstance();
>> context.set(MyModel.class, model);
>> }
>> [..]
>> }
>>
>> 4) I have another UI plugin which should EMF databind the single model
>> instance in some preference pages. Since I didn't find any hint on how
>> to realise preference pages with the new e4 style I used the old
>> mechanism. But as you said the following always resulted in null:
>>
>> class MyPreferencePage extends PreferencePage implements
>> IWorkbenchPreferencePage{
>>
>> @Inject
>> private MyModel model;
>> }
>>
>> This means my UI plugin doesn't make any contribution to the new e4
>> workbench/application model because old mechanisms are used. But,
>> imagine this is not a UI plugin but only another "invisible" plugin
>> intended to make only some analysis on the single metamodel instance I
>> registered with the registration plugin, how can this instance be
>> retrieved from the analysis plugin which makes no contributions to the
>> workbench/application model? Is this possible?
>>
>> After your hint to the ContextInjectionFactory (which I didn't use so
>> long) I tried the following in my registration plugin:
>>
>> class MyRegistrationClass{
>> @PostConstruct
>> public void register(IEclipseContext context) {
>> MyModel model = createSingleModelInstance();
>> context.set(MyModel.class, model);
>> context.declareModifiable(MyModel.class);
>> context.modify(MyModel.class, model);
>> }
>> [..]
>> }
>>
>> Then I tried to do the following in my "UI" plugin:
>>
>> class MyPreferencePage extends PreferencePage implements
>> IWorkbenchPreferencePage{
>> public void init(IWorkbench workbench) {
>> Bundle bundle = FrameworkUtil.getBundle(getClass());
>> BundleContext bundleContext = bundle.getBundleContext();
>> IEclipseContext context =
>> EclipseContextFactory.getServiceContext(bundleContext);
>> MyModel model1 = context.get(MyModel.class);
>> MyModel model2 = ContextInjectionFactory.make(MyModel.class, context);
>> }
>> }
>>
>> But model1 is null and when trying to make model2 I get an
>> InjectionException: Could not find satisfiable constructor in MyModel
>>
>> What disturbs me is that this error message suggests that a new (!)
>> instance of MyModel is to be created which I don't want.
>>
>> So do you understand my scenario and can it be solved somehow?
>>
>> best regards,
>> Gilbert
>>
>>
>>>
>>> The important thing when talking about DI is always the part code
>>> creating the instances, if this code does not use DI you are almost lost.
>>>
>>> Tom
>>>
>>> Am 30.01.13 10:06, schrieb Gilbert Mirenque:
>>>> Hi Tom,
>>>> ok I only used PreferencePages in the old 3.x style because I didn't
>>>> find instruction on how to implement them in the new e4 style. Is this
>>>> possible?
>>>> What about plugins not making any contributions to the UI especially to
>>>> the e4 workbench model? Don't they have any chance to get something
>>>> injected?
>>>>
>>>> best regards,
>>>> Gilbert
>>>>
>>>>
>>>>
>>>> Tom Schindl wrote:
>>>>> Hi,
>>>>>
>>>>> You are using the compat.layer which is not using DI, in the end fairly
>>>>> nothing can use DI in the compat story unless you e.g. use the e4.brigde
>>>>> which at least provides DI for views and editors.
>>>>>
>>>>> Tom
>>>>>
>>>>> Am 29.01.13 16:56, schrieb Gilbert Mirenque:
>>>>>> Hmm, is there no possibility to inject something? What kinds of classes
>>>>>> can use injection and what kind of classes cannot?
>>>>>> I thought that this is one big argument for DI: loose coupling between,
>>>>>> e.g., domain and visualisation? This means for my use case that I have
>>>>>> to create some kind of singleton for my domain model which is to be
>>>>>> exposed. THis then can be used by my preference class. So, back to the
>>>>>> Eclipse roots and no step ahead.
>>>>>>
>>>>>> best regards,
>>>>>> Gilbert
>>>>>>
>>>>>> Tom Schindl wrote:
>>>>>>> the preference pages are not created through DI but they are created
>>>>>>> through the extension registry IIRC so you can't use injection there.
>>>>>>>
>>>>>>> Tom
>>>>>>>
>>>>>>> Am 25.01.13 14:21, schrieb Gilbert Mirenque:
>>>>>>>> Hello,
>>>>>>>> in an Addon I added an object to the EclipseContext:
>>>>>>>>
>>>>>>>> @PostConstruct
>>>>>>>> public void register(IEclipseContext context) {
>>>>>>>> MyClass object = new MyClass();
>>>>>>>> context.set(MyClass.class, object);
>>>>>>>> }
>>>>>>>>
>>>>>>>> Then I have another plugin which contributes a preference page:
>>>>>>>>
>>>>>>>> public class MyPreferencePage extends PreferencePage implements
>>>>>>>> IWorkbenchPreferencePage {
>>>>>>>>
>>>>>>>> @Inject
>>>>>>>> private MyClass object;
>>>>>>>> @Inject
>>>>>>>> private IEclipseContext eclipseContext;
>>>>>>>>
>>>>>>>> public void init(IWorkbench workbench) {
>>>>>>>> // init the preference page
>>>>>>>> }
>>>>>>>> }
>>>>>>>>
>>>>>>>> My problem now is that MyClass object always is null. I tried to inject
>>>>>>>> the eclipseContext but it is null, too. What am I doing wrong?
>>>>>>>>
>>>>>>>> best regards,
>>>>>>>> Gilbert
>>>>>>>>
>>>>>>>
>>>>>
>>>
>
|
|
|
Re: How to get objects be injected into an preference page? [message #1006473 is a reply to message #1006470] |
Thu, 31 January 2013 12:43 |
Thomas Schindl Messages: 6651 Registered: July 2009 |
Senior Member |
|
|
Hi,
Yes unfortunately this the only solution at the moment.
Tom
Am 31.01.13 13:26, schrieb Gilbert Mirenque:
> Hi Tom,
> ok. Thanks a lot for your patience. Until the feature request is
> realised I will use the OSGi Service Registry.
>
> best regards,
> Gilbert
>
> Tom Schindl wrote:
>> You get NULL in the perference page because you are pushing the value in
>> the IEclipseContext of the Addon but try to access it on the
>> ServiceContext which BTW is a different one than the one you have in
>> your e4 application.
>>
>> First of all you should push the value to the context of MApplication in
>> your Addon:
>>
>> public void register(MApplication app) {
>> app.getContext().set(MyModel.class, model);
>> }
>>
>> Now the problem is to get access to the correct IEclipseContext in your
>> preference page.
>>
>> There's a feature request
>> (https://bugs.eclipse.org/bugs/show_bug.cgi?id=398297) I hope I have
>> time to work for Kepler which requests to publish applications as
>> OSGi-Services so that you can get access to the
>> MApplication-IEclipseContext.
>>
>> Because this is not yet implemented you somehow need to publish it
>> yourself in the OSGi-Service-Registry and then retrieve it in your
>> preference page as an OSGi-Service-Reference.
>>
>> Tom
>>
>> Am 30.01.13 11:06, schrieb Gilbert Mirenque:
>>> Hi Tom,
>>>
>>> Tom Schindl wrote:
>>>> Before we proceed let's clarify. Are you working on a pure e4
>>>> application or one that does use the compat layer?
>>> Some of my plugins use the compat layer because they didn't evolve for
>>> long. But the new plugins I develop should be real e4 plugins. That's
>>> why I was asking how to add a preference page in the e4 style.
>>>
>>>> Now to your question:
>>>> It always depends on how you make contributions. The old extension
>>>> registry has no idea about DI and hence stuff contributed through it are
>>>> doomed to fail.
>>> Ok
>>>
>>>> I'm not sure what you mean with any contribution to the e4 workbench
>>>> model. MContribution-Elements where the instance is created by the e4
>>>> framework get stuff injected. If you create instances yourself using
>>>> ContextInjectionFactory.make/inject you get stuff injected.
>>> Ok, consider the following use case. I have an EMF metamodel (ecore) and
>>> its API generated. All this stuff is contained in a model plugin. Since
>>> I want to separate generated code, from other code, from UI code I have
>>> another plugin which I call registration plugin. This plugin creates my
>>> one and only instance (well, that's my hope) of the aformentioned
>>> metamodel. I only need one instance of this metamodel, so it acts like a
>>> singleton. For this reason I thought I could add this only instance to
>>> the IEclipseContext in my registration plugin and is then available with
>>> DI in other plugins. So I did the following in the registration plugin:
>>>
>>> 1) I registered a fragment at the extension point
>>> org.eclipse.e4.workbench.model
>>> 2) In the fragment I added a Addon like this:
>>>
>>> <fragments xsi:type="fragment:StringModelFragment" featurename="addons"
>>> parentElementId="org.eclipse.e4.legacy.ide.application">
>>> <elements xsi:type="application:Addon"
>>> contributionURI="bundleclass://my.reegistration.plugin/MyRegistrationClass"/>
>>> </fragments>
>>> ( I omitted all ID's)
>>> 3) MyRegistrationClass is implemented as follows:
>>>
>>> class MyRegistrationClass{
>>> @PostConstruct
>>> public void register(IEclipseContext context) {
>>> MyModel model = createSingleModelInstance();
>>> context.set(MyModel.class, model);
>>> }
>>> [..]
>>> }
>>>
>>> 4) I have another UI plugin which should EMF databind the single model
>>> instance in some preference pages. Since I didn't find any hint on how
>>> to realise preference pages with the new e4 style I used the old
>>> mechanism. But as you said the following always resulted in null:
>>>
>>> class MyPreferencePage extends PreferencePage implements
>>> IWorkbenchPreferencePage{
>>>
>>> @Inject
>>> private MyModel model;
>>> }
>>>
>>> This means my UI plugin doesn't make any contribution to the new e4
>>> workbench/application model because old mechanisms are used. But,
>>> imagine this is not a UI plugin but only another "invisible" plugin
>>> intended to make only some analysis on the single metamodel instance I
>>> registered with the registration plugin, how can this instance be
>>> retrieved from the analysis plugin which makes no contributions to the
>>> workbench/application model? Is this possible?
>>>
>>> After your hint to the ContextInjectionFactory (which I didn't use so
>>> long) I tried the following in my registration plugin:
>>>
>>> class MyRegistrationClass{
>>> @PostConstruct
>>> public void register(IEclipseContext context) {
>>> MyModel model = createSingleModelInstance();
>>> context.set(MyModel.class, model);
>>> context.declareModifiable(MyModel.class);
>>> context.modify(MyModel.class, model);
>>> }
>>> [..]
>>> }
>>>
>>> Then I tried to do the following in my "UI" plugin:
>>>
>>> class MyPreferencePage extends PreferencePage implements
>>> IWorkbenchPreferencePage{
>>> public void init(IWorkbench workbench) {
>>> Bundle bundle = FrameworkUtil.getBundle(getClass());
>>> BundleContext bundleContext = bundle.getBundleContext();
>>> IEclipseContext context =
>>> EclipseContextFactory.getServiceContext(bundleContext);
>>> MyModel model1 = context.get(MyModel.class);
>>> MyModel model2 = ContextInjectionFactory.make(MyModel.class, context);
>>> }
>>> }
>>>
>>> But model1 is null and when trying to make model2 I get an
>>> InjectionException: Could not find satisfiable constructor in MyModel
>>>
>>> What disturbs me is that this error message suggests that a new (!)
>>> instance of MyModel is to be created which I don't want.
>>>
>>> So do you understand my scenario and can it be solved somehow?
>>>
>>> best regards,
>>> Gilbert
>>>
>>>
>>>>
>>>> The important thing when talking about DI is always the part code
>>>> creating the instances, if this code does not use DI you are almost lost.
>>>>
>>>> Tom
>>>>
>>>> Am 30.01.13 10:06, schrieb Gilbert Mirenque:
>>>>> Hi Tom,
>>>>> ok I only used PreferencePages in the old 3.x style because I didn't
>>>>> find instruction on how to implement them in the new e4 style. Is this
>>>>> possible?
>>>>> What about plugins not making any contributions to the UI especially to
>>>>> the e4 workbench model? Don't they have any chance to get something
>>>>> injected?
>>>>>
>>>>> best regards,
>>>>> Gilbert
>>>>>
>>>>>
>>>>>
>>>>> Tom Schindl wrote:
>>>>>> Hi,
>>>>>>
>>>>>> You are using the compat.layer which is not using DI, in the end fairly
>>>>>> nothing can use DI in the compat story unless you e.g. use the e4.brigde
>>>>>> which at least provides DI for views and editors.
>>>>>>
>>>>>> Tom
>>>>>>
>>>>>> Am 29.01.13 16:56, schrieb Gilbert Mirenque:
>>>>>>> Hmm, is there no possibility to inject something? What kinds of classes
>>>>>>> can use injection and what kind of classes cannot?
>>>>>>> I thought that this is one big argument for DI: loose coupling between,
>>>>>>> e.g., domain and visualisation? This means for my use case that I have
>>>>>>> to create some kind of singleton for my domain model which is to be
>>>>>>> exposed. THis then can be used by my preference class. So, back to the
>>>>>>> Eclipse roots and no step ahead.
>>>>>>>
>>>>>>> best regards,
>>>>>>> Gilbert
>>>>>>>
>>>>>>> Tom Schindl wrote:
>>>>>>>> the preference pages are not created through DI but they are created
>>>>>>>> through the extension registry IIRC so you can't use injection there.
>>>>>>>>
>>>>>>>> Tom
>>>>>>>>
>>>>>>>> Am 25.01.13 14:21, schrieb Gilbert Mirenque:
>>>>>>>>> Hello,
>>>>>>>>> in an Addon I added an object to the EclipseContext:
>>>>>>>>>
>>>>>>>>> @PostConstruct
>>>>>>>>> public void register(IEclipseContext context) {
>>>>>>>>> MyClass object = new MyClass();
>>>>>>>>> context.set(MyClass.class, object);
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> Then I have another plugin which contributes a preference page:
>>>>>>>>>
>>>>>>>>> public class MyPreferencePage extends PreferencePage implements
>>>>>>>>> IWorkbenchPreferencePage {
>>>>>>>>>
>>>>>>>>> @Inject
>>>>>>>>> private MyClass object;
>>>>>>>>> @Inject
>>>>>>>>> private IEclipseContext eclipseContext;
>>>>>>>>>
>>>>>>>>> public void init(IWorkbench workbench) {
>>>>>>>>> // init the preference page
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> My problem now is that MyClass object always is null. I tried to inject
>>>>>>>>> the eclipseContext but it is null, too. What am I doing wrong?
>>>>>>>>>
>>>>>>>>> best regards,
>>>>>>>>> Gilbert
>>>>>>>>>
>>>>>>>>
>>>>>>
>>>>
>>
|
|
| |
Goto Forum:
Current Time: Tue Mar 19 01:08:12 GMT 2024
Powered by FUDForum. Page generated in 0.02143 seconds
|