Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 321201 - Implement an opposite of @Inject
Summary: Implement an opposite of @Inject
Status: CLOSED WONTFIX
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: E4 (show other bugs)
Version: unspecified   Edit
Hardware: PC Mac OS X - Carbon (unsup.)
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-07-29 05:40 EDT by Thomas Schindl CLA
Modified: 2015-08-26 15:19 EDT (History)
8 users (show)

See Also:


Attachments
patch (3.26 KB, patch)
2010-07-29 05:40 EDT, Thomas Schindl CLA
no flags Details | Diff
An implementation start (8.38 KB, patch)
2010-07-29 07:00 EDT, Thomas Schindl CLA
no flags Details | Diff
Working implementation with test (10.61 KB, patch)
2010-07-29 07:44 EDT, Thomas Schindl CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Schindl CLA 2010-07-29 05:40:54 EDT
Created attachment 175463 [details]
patch

The 4.0 release implements the possibility to fetch informations from the context which makes it extremly easy to write code which has 0 dependencies to framework code.

The opposite - pushing back informations into the context - is not possible. What about the idea to have an @ContextValue-Annotation people can annotate a field or method and the Injection-Frame injects them an object of type IContextValue.

Here's how this translates into source code:

-----------8<-----------
public class MyView {
  @ContextValue(contextKey="myKey")
  private IContextValue<MyValue> contextVal;

  @ContextValue(contextKey="myKey",modify=false)
  private IContextValue<MyValue> contextVal2;

  @PostConstruct
  private void init() {
    // Earliest point
    contextVal.set(contextVal);
    contextVal2.set(contextVal);
  }
}
-----------8<-----------

The selection beast:
--------------------
Because the selection in our system is such a special beast we'll probably need a @OutSelection which pushes the selection back in a special way. To keep it consitent I'd also like to propose a @Selection which is what you create today using @Inject @Named(IServiceConstants.ACTIVE_SELECTION). The implementation of it can happen in "org.eclipse.e4.ui.di"
Comment 1 Thomas Schindl CLA 2010-07-29 05:45:00 EDT
Ups should have read like this:

--------------8<--------------
public class MyView {
  @Inject
  @ContextValue(contextKey="myKey")
  private IContextValue<MyValue> contextVal;

  @Inject
  @ContextValue(contextKey="myKey",modify=false)
  private IContextValue<MyValue> contextVal2;

  @PostConstruct
  private void init() {
    // Earliest point
    contextVal.set(contextVal);
    contextVal2.set(contextVal);
  }
}
--------------8<--------------
Comment 2 Thomas Schindl CLA 2010-07-29 07:00:55 EDT
Created attachment 175480 [details]
An implementation start

I only have one problem how to get access to the IEclipseContext but probably my way of doing this is completely wrong :-)
Comment 3 Thomas Schindl CLA 2010-07-29 07:44:59 EDT
Created attachment 175486 [details]
Working implementation with test

I think I now got it
Comment 4 Paul Webster CLA 2010-07-29 07:49:55 EDT
We tried some form of @Out modifier earlier.

But we need to look at this in terms of our overall architecture.  My first guess is that to keep it up to date, we would need to use properties and a getter.

PW
Comment 5 Thomas Schindl CLA 2010-07-29 07:58:08 EDT
(In reply to comment #4)
> We tried some form of @Out modifier earlier.
> 
> But we need to look at this in terms of our overall architecture.  My first
> guess is that to keep it up to date, we would need to use properties and a
> getter.

I don't think this is needed with my approach.

Tom
Comment 6 Paul Webster CLA 2010-07-29 08:02:20 EDT
How are changes in your object's field reflected in the context/RATs?

PW
Comment 7 Thomas Schindl CLA 2010-07-29 08:30:50 EDT
The trick is that the IContextValue is generated by the injection framework itself and a IContextValue#set() simply pushes the value back into the context. (I'm not talking about selection propagation which is more complex and I'm familiar enough yet with the the injection code but I guess Oleg is :-)

The current code

----------8<----------
public class MyObj {
  @Inject
  @ContextValue("bla")
  private IContextValue<Object> bla;

  @PostConstruct
  void init() {
    bla.set("blabla");
  }
}
----------8<----------

would read like this in 4.0:

----------8<----------
public class MyObj {

  @Inject
  private IEclipseContext context;

  @PostCreate
  void init() {
    context.modify("bla","blabla");
  }
}
----------8<----------

I think the problem with using a get() is that you somehow have to inform the system that the value has changed which will bind you once more to framework classes not?

I'm only doing a brain dump and tests to find solutions because I'm not happy with the current status of propagating changes to the context.
Comment 8 Boris Bokowski CLA 2010-07-29 09:23:13 EDT
(In reply to comment #7)
> The trick is that the IContextValue is generated by the injection framework
> itself and a IContextValue#set() simply pushes the value back into the context.

Sounds good to me.

I haven't looked at the patch - does IContextValue only support setting values, or can you get its current value, and if yes, how do you know about changes? ('no' would be a valid answer)
Comment 9 Thomas Schindl CLA 2010-07-29 09:27:14 EDT
(In reply to comment #8)
> (In reply to comment #7)
> > The trick is that the IContextValue is generated by the injection framework
> > itself and a IContextValue#set() simply pushes the value back into the context.
> 
> Sounds good to me.
> 
> I haven't looked at the patch - does IContextValue only support setting values,
> or can you get its current value, and if yes, how do you know about changes?
> ('no' would be a valid answer)

No only set, there's no need to get because that's what @Inject is doing :-)
Comment 10 Oleg Besedin CLA 2010-07-29 11:29:29 EDT
From what I've seen so far the main issue for developers is to figure out the node on the context tree on which the value should be changed. (This is where issues with "current selection" come in.) 

If you just want to change a value on "your" context, the following will do:

  @Inject IEclipseContext myContext;
  ...
  myContext.set("abc", newValue);

It is my understanding that the analog with the new code is:

  @Inject @ContextValue(contextKey="contextField1")
  private IContextValue<String> contextField1;
  ...
  contextField1.set(newValue);

I am not sure how much that improves things. The code from the consumer side looks about the same, but adds new concepts of IContextValue and @ContextValue.
Comment 11 Thomas Schindl CLA 2010-07-29 11:34:38 EDT
I think the advantage with the IContextValue is that the concept stays the same when we go further with e.g. the selection story:

--------8<--------
@Inject
@OutSelection
private IContextValue<Object> mySelection;
--------8<--------

If we manage to get this done the user still uses mySelection.set() but the interals go through the ESelectionService which does the appropriate thing.

So for the user there's only one concept to deal with.
Comment 12 Thomas Schindl CLA 2010-07-29 11:40:30 EDT
Probably we could rename it to IOutValue and move the concept to core DI because it is not only bound to IEclipseContext. 

Ideally a user has only a dependency on core.di and core.di.extensions when writing a bundle not more not less, though a dependency on core.contexts would be acceptable as well probably.

What definately wrong currently is to get a dependency on ui.workbench because of the ESelectionService (should probably moved to ui.services).
Comment 13 Boris Bokowski CLA 2010-07-29 12:24:02 EDT
(In reply to comment #12)
> Probably we could rename it to IOutValue and move the concept to core DI
> because it is not only bound to IEclipseContext. 
> 
> Ideally a user has only a dependency on core.di and core.di.extensions when
> writing a bundle not more not less

That would be my goal, too.

I still agree with John's comments on bug 286444 ("The idea that child contexts can modify values in their parent context seems very dangerous to me"). I believe that the answer lies in a separation of 'consumed selection' and 'produced selection', and logic that wires these in the appropriate way.
Comment 14 Thomas Schindl CLA 2010-07-29 12:35:13 EDT
That's what I mean IContextValue<Object> is able to hide such subtle things and the user only has one concept to learn.
Comment 15 Thomas Schindl CLA 2010-10-08 10:07:32 EDT
If i got the new @Active implementation right one a part can now always push the current-selection in its own context so the problem setting the selection back to the right context is already solved?
Comment 16 Lars Vogel CLA 2012-07-19 13:32:39 EDT
I think this discussion has ended in the current architecture of Eclipse 4.2. Closing as "Won't fix". Please open the bug again, if you disagree.