Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » Custom @Injection problem
Re: Custom @Injection problem [message #883937 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883939 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883941 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883945 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883947 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883949 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883951 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883953 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883955 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883957 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883959 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883961 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883963 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883966 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883969 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883971 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883973 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883975 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883977 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883979 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883981 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883983 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883985 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883987 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883989 is a reply to message #883837] Sat, 09 June 2012 16:57 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
comments below.

On 09/06/2012 16:47, Tom Schindl wrote:
> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>> Thanks Tom,
>> I really want to understand how Injection works, but my experiments seem
>> to lead to conflicting results.
I am just trying to fully understand DI.
I'm sure there are better ways to implement what I need.

>>
>> Comments below.
>>
>> On 08/06/2012 08:11, Tom Schindl wrote:
>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>> you simply try to call IconProvider.getIcon() because you made
>>> everything static.
>>>
>>> Instead you should:
>>> 1. make getIcon and resourceManager not static
>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>> processes fields and methods found in the class hierarchy, including
>> static fields and methods too."
>> Anyways I *did* convert my class to fully instance (no statics).
>>
>>> 2.a. let the system inject IconProvider it into your Part
>> Uhm, no.
>> What I'm trying to @Inject id Resource Manager.
>> IconProvider is a stupid Pojo wrapper around it.
>> Should I make that @Inject-able also?
>>
>> my current (test!) Icon Provider is simply:
>> public class IconProvider {
>> @Inject private IResourceManager resourceManager;
>>
>> public Image getIcon(int size, String s) {
>> return resourceManager.getImage(s, size);
>> }
>> }
>>
>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>> the current IEclipseContext
>> Again, I'm unsure this is what I want to do.
>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>> not at application level.
>>
>> What baffles me completely is everything seems to work Ok from a Part,
>> but not from another class.
>>
>> In my test Part I have:
>> @Inject private IResourceManager resourceManager;
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = resourceManager.getImage(name, 128);
>> lblNewLabel.setImage(image);
>> lblNewLabel.getParent().pack(true);
>> }
>> This works perfectly, while:
>> public void widgetSelected(SelectionEvent e) {
>> String name = getImageName();
>> Image image = iconProvider.getIcon(128, name);
> ^^^^^^^^^^^^^^
> So where is this iconProvider coming from? Show me the code that creates it.

I instantiate it in my test Part creator (class Quote):

private IconProvider iconProvider;
...
public Quote() {
iconProvider = new IconProvider();
}

I attach the whole class, in case it might be useful.

>
> Looking at your sample project you have code like this:
>
>
> return IconProvider.getIconSmall(ve.label) ;
>
> This can't work you never told the DI framework about your IconProvider
> so how should it have injected something?
As said:
IconProvider is a something which knows how to map classes to icon names.
It is a normal Pojo class.
Previously it was completely static because this mapping *is* static,
but I changed it to be a normal instanciated class for my DI testing.

Anyways this is *not* the problem because IconProvider works as I want
it to work.
It is currently nothing else but a wrapper around class ResourceManager.
I do attach current version.

>
> If you modify your master constructor to look like this the
> IResourceManager is injected!
>
>> @Inject
>> public MasterPart(IEclipseContext context) {
>> System.out.println("MasterPart.MasterPart():");
>> ContextInjectionFactory.make(IconProvider.class, context);
>> }
I do not want IResourceManager to be injected int my master Part
constructor.
That works ok even without Your special constructor.
It seems to me Your code makes IconProvider Injectable in my current
IEclipseContext. If I understand this correctly then this is not what
I'm trying to do.
I would like to have IResourceManager to be injected into IconProvider
instances.
Icon provider should not be injected anywhere.

>
> I can only repeat I think the usage of statics is not a good idea I'd
Noted.

> suggest you make your methods none-static and
Done for IconProvider, will do for other classes.

> a) Pass along your resource manager to all code parts
I assume You mean: inject IResouceManager into one Part and then pass it
around.
Ok. I know it works, but I would have liked to inject it directly where
needed (Part or nonPart)

> b) Use DI for your codeparts as well this way you don't need to
> remember all informations you are passing around
I discovered that obtaining an instance of IconProvider via:

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

instead of:
public Quote() {
iconProvider = new IconProvider();
}

indeed produces a working (injected) instance.
I fail to understand the difference between the Part class (Quote) and
the non-Part class (IconProvider) respect to Injection

>
> Remember that statics are a bad design idea something the framework got
> rid in e4 and so should you in your own code.
Noted.
I do not understand the reasons for this, though.
Can You point me to some discussion on the subject?

>
> BTW - did you know that there's a very cool resourcemanager service
> available in ...tools.services which does refcounting so that you don't
> forget to dispose your images once they are not needed any more.
Right now I'm using this to fully understand DI.
Soon I will have a look to the standard resource manager service.

>
> Tom
Thanks a lot
Mauro

package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.osgi.resourcepool.IQuoteService;

import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Quote {

@Inject
private IQuoteService quoteService;
@Inject
private IResourceManager resourceManager;
private IconProvider iconProvider;

private Text txtQuote;
private Label lblNewLabel;
private Button btnGetViaIp;

@Inject
public Quote(IEclipseContext context) {
iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
}

/**
* Create contents of the view part.
*/
@PostConstruct
public void createControls(Composite parent) {
parent.setLayout(new GridLayout(2, false));

Button btnNext = new Button(parent, SWT.NONE);
btnNext.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (quoteService != null) {
String s = quoteService.getQuote();
txtQuote.setText(s);
}
}
});
btnNext.setText("Next");

txtQuote = new Text(parent, SWT.BORDER);
txtQuote.setText("Quote");
txtQuote.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

Button btnNext_1 = new Button(parent, SWT.NONE);
btnNext_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnNext_1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = iconProvider.getIcon(128, name);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnNext_1.setText("Get via IP");

lblNewLabel = new Label(parent, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
lblNewLabel.setText("Icon");

btnGetViaIp = new Button(parent, SWT.NONE);
btnGetViaIp.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String name = getImageName();
Image image = resourceManager.getImage(name, 128);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
});
btnGetViaIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
btnGetViaIp.setText("Get via RM");
}

private static final String[] names = new String[] { "Actor", "ActorFolder", "Actors", "AlienWorld", "ArrowBook", "Assemble", "AxeBook", "Back", "BlueOff", "BlueRefresh",
"Books", "BrushBook", "CleanDocuments", "CleanNewPaper", "ClosePage", "Compass", "CompassBook", "CompassFolder", "Cut", "Decapitated Thugs", "Delete",
"DesktopPublishing", "Down Left", "Down Right Outrageous", "Eclipse", "EditPages", "Export", "Fiends ain't comin' fast enough.", "Forward", "GreenBook",
"I shine you up a nice big pizza.", "Import", "Indeed, I do rock.", "Left Down", "Left Up", "MergeBook", "Minus", "Network", "NewBook", "NewChapter", "NewPage", "Next",
"Open", "PaperTrail", "Pen", "PenBook", "Plus", "Preferences", "Previous", "Printer", "RedBook", "Review", "Right Up", "Save", "Shutdown", "Stop", "TextDocument",
"ThingDrawer", "ThingFolder", "Things", "ThisBook", "Thuggergotchi", "Tick", "Trash Full", "Tree", "TreeBook", "Typeset", "Up Left", "Uploads", "View", "Warning",
"World", "X", "YellowOff", "ZoomIn", "ZoomOut" };

private String getImageName() {
Random random = new Random();
int nextInt = random.nextInt(names.length);
return names[nextInt];
}

@PreDestroy
public void dispose() {
}

@Focus
public void setFocus() {
txtQuote.setFocus();
}

}
package quote;

import it.condarelli.e4.resourcemanager.IResourceManager;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject
private IResourceManager resourceManager;

public Image getIcon(int size, String s) {
return resourceManager.getImage(s, size);
}
}
Re: Custom @Injection problem [message #883990 is a reply to message #883989] Sat, 09 June 2012 17:17 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Am 09.06.12 18:57, schrieb Mauro Condarelli:
> Thanks Tom,
> comments below.
>
> On 09/06/2012 16:47, Tom Schindl wrote:
>> Am 09.06.12 14:30, schrieb Mauro Condarelli:
>>> Thanks Tom,
>>> I really want to understand how Injection works, but my experiments seem
>>> to lead to conflicting results.
> I am just trying to fully understand DI.
> I'm sure there are better ways to implement what I need.
>
>>>
>>> Comments below.
>>>
>>> On 08/06/2012 08:11, Tom Schindl wrote:
>>>> I'm uncertain how you get access to the IconProvider to me it looks like
>>>> you simply try to call IconProvider.getIcon() because you made
>>>> everything static.
>>>>
>>>> Instead you should:
>>>> 1. make getIcon and resourceManager not static
>>> Why? Is this really necessary? As Sopot pointed out: "The DI framework
>>> processes fields and methods found in the class hierarchy, including
>>> static fields and methods too."
>>> Anyways I *did* convert my class to fully instance (no statics).
>>>
>>>> 2.a. let the system inject IconProvider it into your Part
>>> Uhm, no.
>>> What I'm trying to @Inject id Resource Manager.
>>> IconProvider is a stupid Pojo wrapper around it.
>>> Should I make that @Inject-able also?
>>>
>>> my current (test!) Icon Provider is simply:
>>> public class IconProvider {
>>> @Inject private IResourceManager resourceManager;
>>>
>>> public Image getIcon(int size, String s) {
>>> return resourceManager.getImage(s, size);
>>> }
>>> }
>>>
>>>> 2.b. Create an instance using ContextInjectionFactory on your own using
>>>> the current IEclipseContext
>>> Again, I'm unsure this is what I want to do.
>>> I'm trying to make ResourceManager @Injet-able at the OSGI bundle level,
>>> not at application level.
>>>
>>> What baffles me completely is everything seems to work Ok from a Part,
>>> but not from another class.
>>>
>>> In my test Part I have:
>>> @Inject private IResourceManager resourceManager;
>>> public void widgetSelected(SelectionEvent e) {
>>> String name = getImageName();
>>> Image image = resourceManager.getImage(name, 128);
>>> lblNewLabel.setImage(image);
>>> lblNewLabel.getParent().pack(true);
>>> }
>>> This works perfectly, while:
>>> public void widgetSelected(SelectionEvent e) {
>>> String name = getImageName();
>>> Image image = iconProvider.getIcon(128, name);
>> ^^^^^^^^^^^^^^
>> So where is this iconProvider coming from? Show me the code that creates it.
>
> I instantiate it in my test Part creator (class Quote):
>
> private IconProvider iconProvider;
> ...
> public Quote() {
> iconProvider = new IconProvider();
> }
>
> I attach the whole class, in case it might be useful.
>

That can not work. DI only can inject stuff if you tell it about your
class hence you need to create it through ContextInjectionFactory.

>>
>> Looking at your sample project you have code like this:
>>
>>
>> return IconProvider.getIconSmall(ve.label) ;
>>
>> This can't work you never told the DI framework about your IconProvider
>> so how should it have injected something?
> As said:
> IconProvider is a something which knows how to map classes to icon names.
> It is a normal Pojo class.
> Previously it was completely static because this mapping *is* static,
> but I changed it to be a normal instanciated class for my DI testing.
>
> Anyways this is *not* the problem because IconProvider works as I want
> it to work.
> It is currently nothing else but a wrapper around class ResourceManager.
> I do attach current version.
>
>>
>> If you modify your master constructor to look like this the
>> IResourceManager is injected!
>>
>>> @Inject
>>> public MasterPart(IEclipseContext context) {
>>> System.out.println("MasterPart.MasterPart():");
>>> ContextInjectionFactory.make(IconProvider.class, context);
>>> }
> I do not want IResourceManager to be injected int my master Part
> constructor.
> That works ok even without Your special constructor.
> It seems to me Your code makes IconProvider Injectable in my current
> IEclipseContext. If I understand this correctly then this is not what
> I'm trying to do.
> I would like to have IResourceManager to be injected into IconProvider
> instances.
> Icon provider should not be injected anywhere.
>

I used your original project you attached and there I simply made sure
that the DI framework once process the class.

>>
>> I can only repeat I think the usage of statics is not a good idea I'd
> Noted.
>
>> suggest you make your methods none-static and
> Done for IconProvider, will do for other classes.
>
>> a) Pass along your resource manager to all code parts
> I assume You mean: inject IResouceManager into one Part and then pass it
> around.
> Ok. I know it works, but I would have liked to inject it directly where
> needed (Part or nonPart)
>
>> b) Use DI for your codeparts as well this way you don't need to
>> remember all informations you are passing around
> I discovered that obtaining an instance of IconProvider via:
>
> @Inject
> public Quote(IEclipseContext context) {
> iconProvider = ContextInjectionFactory.make(IconProvider.class, context);
> }
>
> instead of:
> public Quote() {
> iconProvider = new IconProvider();
> }
>
> indeed produces a working (injected) instance.
> I fail to understand the difference between the Part class (Quote) and
> the non-Part class (IconProvider) respect to Injection
>

Correct as explained above where should DI know about your IconProvider
class? You need to tell it about. I think you could even write:

public Quote(IconProvider iconProvider) {

}

This should work because if you have a noarg constructor DI will resolve
it when it tries to create the Quote instance.

If you look into the framework code you'll see that the framework
creates instance of your Quote-Class like you do it now your own for
IconProvider

>>
>> Remember that statics are a bad design idea something the framework got
>> rid in e4 and so should you in your own code.
> Noted.
> I do not understand the reasons for this, though.
> Can You point me to some discussion on the subject?
>

This is nothing specific to Eclipse but a general development paradigm
shift coming originally from the web. So I won't repeat what you can
read by simply searching google.

Search for:
* Dependency Injection
* Inversion of Control
* "why java statics are evil"

>>
>> BTW - did you know that there's a very cool resourcemanager service
>> available in ...tools.services which does refcounting so that you don't
>> forget to dispose your images once they are not needed any more.
> Right now I'm using this to fully understand DI.
> Soon I will have a look to the standard resource manager service.
>
>>
>> Tom
> Thanks a lot
> Mauro

Tom
Re: Custom @Injection problem [message #883995 is a reply to message #883990] Sat, 09 June 2012 21:31 Go to previous message
Eclipse UserFriend
Also if you want to know more about Dependency Injection, Prasanna's book Dependency Incjetion helps when facing some conceptual questions. I recommend you to read it, especially the first chapters as it gets really deep. You will also find there why other practises (statics) are not as good as DI and why it was created in the first place. http://www.amazon.com/Dependency-Injection-Dhanji-R-Prasanna/dp/193398855X
Previous Topic:A small Annoyance
Next Topic:Migration from 3.x to Eclipse 4
Goto Forum:
  


Current Time: Thu Apr 25 20:43:05 GMT 2024

Powered by FUDForum. Page generated in 0.05017 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top