|
|
|
|
|
Re: Lifecycles ProcessAdditions - getting the MWindow [message #1034419 is a reply to message #1034347] |
Fri, 05 April 2013 12:10 |
Eclipse User |
|
|
|
Alex, it's all about the context hierarchy. Every MApplication, MWindow, MPerspective and MPart has its own IEclipseContext. Imagine all these contexts arranged in a tree, in a hierarchy. App context as the root, Win contexts as its children, then perspective and parts as you go deeper etc, etc. Now when you try an @Inject MPart in a the part level (e.g when you are writing the Part class URI) there is a look up on this part context and if not found it goes to do a look up on its parent (perspective context) and if it fails it goes up to the win context and so on.
Thus if you look for a part in the e.g. window level you get an InjectionException because the lookup rule does not search downwards but just upwards. The reason is that this way you scope services, like grouping stuff for all children.
All objects available for injection (services, MParts, MWindows etc.) are splattered around in this tree and, depending on where you request your injection, you will get it only if it is (in your local context) or (in one of the nodes on your way up to the root).
Naturally now you are wondering but who puts these objects in the contexts to begin with. In the default way (context#set) it happens in two moments:
- at startup of the application for the higher levels (MApplication etc). For gut-level details check out the E4Application class in the eclipse internals.
- *by the renderers* for the lower levels (MPart etc). When and how it happens is irrelevant because that's the whole idea of dependency injection. Not just encapsulating your dependencies, but also their complete lifecycle (creation, disposal etc).
Back to your case, you try to inject an MWindow on an MApplication level context (also known as Worbkench Context) you are asking for something which resides in its children and you have no chance of getting one, because even if you would, which one would you get (picture an app with 2 top-level windows)? When you ask for an MPart in this specific part's context (as I said, like when you do the @PostConstruct and get the composite) you are requesting it in the context of the part itself, and in this scope there is only one part - the one that you'll get injected.
Do this on a part contribution and see for yourself:
@PostConstruct
public void pc(IEclipseContext localContext){
while (localContext!=null){
system.out.println(localContext);
localContext=localContext.getParent();
}
}
P.S.
If you want to intervene in this rule and do it your way you have the context functions. If you completely want to spectacularly smash this context thing you can use ExtendedObjectSupplier-s, though we (especially Oleg) won't let you do it for @Inject so you'd have to make up your own annotation (like @Preference and @UIEventTopic does).
|
|
|
Powered by
FUDForum. Page generated in 0.03184 seconds