Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » Custom @Injection problem
Custom @Injection problem [message #881926] Tue, 05 June 2012 14:02 Go to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Hi,
I'm trying to define my own OSGI service for subsequent @Inject_ion into my e4 App.

I followed Lars Vogel excellent tutorial and, unsurprisingly, it works.

When I tried the "Real Thing" (or something close) @inject silently
fails even though I'm unable to spot relevant differences with the working thing.

Can someone tell me how could I proceed to debug my code?

P.S.: Is Injection supposed to work with static fields/members?
This seems the only difference...

Regards
Mauro

====== details =============
==== service defining plugin: it.condarelli.e4.resourcemanager:
== META-INF/MANIFEST.MF:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: ResourceManager
Bundle-SymbolicName: it.condarelli.e4.resourcemanager
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Export-Package: it.condarelli.e4.resourcemanager
Require-Bundle: org.eclipse.jface
== src/it.condarelli.e4.resourcemanager/IResourceManager.java
package it.condarelli.e4.resourcemanager;


import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.RGB;

public interface IResourceManager {
public String getFontName(FontData[] fds);
public Font getFont(String name);
public String getColorName(RGB rgb);
public Color getColor(String name);
public Color getColor(RGB rgb);
public ImageDescriptor getImageDescriptor(String name);
public ImageDescriptor getImageDescriptor(String name, int size);
public Image getImage(String name, int size);
public ImageData scale(ImageData in, int size);
public Image scale(Image in, int size);
}
==== service implementing plugin: it.condarelli.e4.resourcemanager.impl:
== META-INF/MANIFEST.MF:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Resourcemanager_impl
Bundle-SymbolicName: it.condarelli.e4.resourcemanager.impl
Bundle-Version: 1.0.0.qualifier
Require-Bundle: org.eclipse.jface,
it.condarelli.e4.resourcemanager
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: org.eclipse.core.runtime,
org.osgi.framework;version="1.7.0"
Service-Component: OSGI-INF/component.xml
== OSGI-INF/component.xml
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="it.condarelli.e4.resourcemanager.impl">
<implementation class="it.condarelli.e4.resourcemanager.impl.ResourceManager"/>
<service>
<provide interface="it.condarelli.e4.resourcemanager.IResourceManager"/>
</service>
</scr:component>
== src/it.condarelli.e4.resourcemanager.impl.ResourceManager.java
package it.condarelli.e4.resourcemanager.impl;

import it.condarelli.e4.resourcemanager.IResourceManager;

import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.jface.resource.FontRegistry;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.RGB;

public class ResourceManager implements IResourceManager {

public static final String PLUGIN_ID = "it.condarelli.e4.resourcemanager.impl";

@Override
public String getFontName(FontData[] fds) {
return fds[0].toString();
}
...
private class AveragingRgbRaster {
private int width;
...
}
private ImageData createAveragedImage(ImageData inputImage, int dstwidth, int dstheight) {
int xsrc, ysrc;
...
}
...
@Override
public Image scale(Image in, int size) {
ImageData imgd = scale(in.getImageData(), size);
ImageDescriptor id = ImageDescriptor.createFromImageData(imgd);
Image out = id.createImage();
return out;
}

}
==== service user plugin: it.condarelli.e4.writer:
== META-INF/MANIFEST.MF:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Writer
Bundle-SymbolicName: it.condarelli.e4.writer; singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: it.condarelli.e4.writer.Activator
Bundle-Vendor: Mauro Condarelli
Require-Bundle: it.condarelli.writer.model.world;bundle-version="1.0.0",
javax.inject;bundle-version="1.0.0",
org.eclipse.core.resources;bundle-version="3.8.0",
org.eclipse.core.runtime;bundle-version="3.8.0",
org.eclipse.swt;bundle-version="3.8.0",
org.eclipse.core.databinding;bundle-version="1.4.1",
org.eclipse.core.databinding.beans;bundle-version="1.2.100",
org.eclipse.jface;bundle-version="3.8.0",
org.eclipse.jface.databinding;bundle-version="1.6.0",
org.eclipse.e4.ui.services;bundle-version="0.10.0",
org.eclipse.e4.ui.workbench;bundle-version="0.10.1",
org.eclipse.e4.core.services;bundle-version="1.0.0",
org.eclipse.e4.core.di;bundle-version="1.1.0",
org.eclipse.e4.core.contexts;bundle-version="1.0.0",
org.eclipse.e4.ui.workbench.swt;bundle-version="0.10.0",
org.eclipse.core.databinding.property;bundle-version="1.4.0",
org.eclipse.e4.ui.css.core;bundle-version="0.10.0",
org.w3c.css.sac;bundle-version="1.3.1",
org.eclipse.e4.core.commands;bundle-version="0.10.0",
org.eclipse.e4.ui.bindings;bundle-version="0.10.0",
org.eclipse.e4.ui.di,
org.eclipse.emf.databinding,
org.eclipse.emf.databinding.edit,
it.condarelli.e4.resourcemanager;bundle-version="1.0.0",
it.condarelli.e4.resourcemanager.impl;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: org.eclipse.core.filesystem,
org.osgi.framework;version="1.3.0"
Bundle-ActivationPolicy: lazy
== plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<plugin>

<extension
id="product"
point="org.eclipse.core.runtime.products">
<product
name="it.condarelli.e4.writer"
application="org.eclipse.e4.ui.workbench.swt.E4Application">
<property
name="appName"
value="it.condarelli.e4.writer">
</property>
<property
name="applicationXMI"
value="it.condarelli.e4.writer/Application.e4xmi">
</property>
<property
name="applicationCSS"
value="platform:/plugin/it.condarelli.e4.writer/css/default.css">
</property>
</product>
</extension>

</plugin>
== src/it.condarelli.e4.writer.modelif/IconProvider.java
package it.condarelli.e4.writer.modelif;

import it.condarelli.e4.resourcemanager.IResourceManager;
import it.condarelli.writer.model.world.Actor;
import it.condarelli.writer.model.world.Book;
import it.condarelli.writer.model.world.Chapter;
import it.condarelli.writer.model.world.Item;
import it.condarelli.writer.model.world.Location;
import it.condarelli.writer.model.world.Scene;
import it.condarelli.writer.model.world.World;
import it.condarelli.writer.model.world.impl.ActorImpl;
import it.condarelli.writer.model.world.impl.BookImpl;
import it.condarelli.writer.model.world.impl.ChapterImpl;
import it.condarelli.writer.model.world.impl.ItemImpl;
import it.condarelli.writer.model.world.impl.LocationImpl;
import it.condarelli.writer.model.world.impl.SceneImpl;
import it.condarelli.writer.model.world.impl.WorldImpl;

import java.util.HashMap;
import java.util.Map;

import javax.inject.Inject;

import org.eclipse.swt.graphics.Image;

public class IconProvider {
@Inject static private IResourceManager resourceManager;

static private Map<String, String> iconMap = null;
static private Map<String, String> getIconMap() {
if (iconMap == null) {
....
static public Image getIcon(int size, Object o) {
................vvvvvvvvvvvvvv <-------------------------------- here resourceManager is null
return resourceManager.getImage(imageName(o2s(o)), size);
}
...
}
Re: Custom @Injection problem [message #881937 is a reply to message #881926] Tue, 05 June 2012 14:16 Go to previous messageGo to next message
Christoph Keimel is currently offline Christoph KeimelFriend
Messages: 482
Registered: December 2010
Location: Germany
Senior Member
I think you are missing Bundle-ActivationPolicy: lazy in your bundle manifest. Without this option the service will not be started. This will be included, if you check "Activate this plug-in when one of its classes is loaded" on the overview tab of the manifest edtior.

To test, if the service is started you can add an activate method call to your component definition:

<scr:component ... name="it.condarelli.e4.resourcemanager.impl" activate="activate">

And then check if the message is called in the implementation class:
public void activate(ComponentContext context) {
	logger.info("Service ACTIVATED");		
}
Re: Custom @Injection problem [message #881965 is a reply to message #881926] Tue, 05 June 2012 14:55 Go to previous messageGo to next message
Eclipse UserFriend
Mauro Condarelli wrote on Tue, 05 June 2012 17:02

P.S.: Is Injection supposed to work with static fields/members?


Yes. http://wiki.eclipse.org/Eclipse4/RCP/Dependency_Injection
Re: Custom @Injection problem [message #882617 is a reply to message #881937] Wed, 06 June 2012 21:11 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Re-adding this option (I removed it because in the working example does
not appear) changes nothing.
"activate" method is not called.
I did set a breakpoint to org.eclipse.e4.core.di.InjectionException (and
all its subclasses) but it doesn't get triggered.

Changing the sources to :

public class IconProvider {
@Inject static private IResourceManager resourceManager;
...
static public Image getIcon(int size, Object o) {
if (resourceManager == null) {
resourceManager = new ResourceManager();
}
return resourceManager.getImage(imageName(o2s(o)), size);
}
}

works as expected, but obviously completely defeats @Injection scope.

Can someone suggest some further debugging technique?

TiA
Mauro

On 05/06/2012 16:16, Christoph Keimel wrote:
> I think you are missing Bundle-ActivationPolicy: lazy in your bundle
> manifest. Without this option the service will not be started. This will
> be included, if you check "Activate this plug-in when one of its classes
> is loaded" on the overview tab of the manifest edtior.
>
> To test, if the service is started you can add an activate method call
> to your component definition:
>
> <scr:component ... name="it.condarelli.e4.resourcemanager.impl"
> activate="activate">
>
> And then check if the message is called in the implementation class:
> public void activate(ComponentContext context) {
> logger.info("Service ACTIVATED");
> }
Re: Custom @Injection problem [message #882627 is a reply to message #882617] Wed, 06 June 2012 21:42 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Did you put your bundle into lazy mode? DS does not work without setting
this option in your MANIFEST.MF

Tom

Am 06.06.12 23:11, schrieb Mauro Condarelli:
> Re-adding this option (I removed it because in the working example does
> not appear) changes nothing.
> "activate" method is not called.
> I did set a breakpoint to org.eclipse.e4.core.di.InjectionException (and
> all its subclasses) but it doesn't get triggered.
>
> Changing the sources to :
>
> public class IconProvider {
> @Inject static private IResourceManager resourceManager;
> ...
> static public Image getIcon(int size, Object o) {
> if (resourceManager == null) {
> resourceManager = new ResourceManager();
> }
> return resourceManager.getImage(imageName(o2s(o)), size);
> }
> }
>
> works as expected, but obviously completely defeats @Injection scope.
>
> Can someone suggest some further debugging technique?
>
> TiA
> Mauro
>
> On 05/06/2012 16:16, Christoph Keimel wrote:
>> I think you are missing Bundle-ActivationPolicy: lazy in your bundle
>> manifest. Without this option the service will not be started. This will
>> be included, if you check "Activate this plug-in when one of its classes
>> is loaded" on the overview tab of the manifest edtior.
>>
>> To test, if the service is started you can add an activate method call
>> to your component definition:
>>
>> <scr:component ... name="it.condarelli.e4.resourcemanager.impl"
>> activate="activate">
>>
>> And then check if the message is called in the implementation class:
>> public void activate(ComponentContext context) {
>> logger.info("Service ACTIVATED");
>> }
>
Re: Custom @Injection problem [message #882938 is a reply to message #882627] Thu, 07 June 2012 13:50 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Yes, I did.
I do attach the whole project.
I get NO error (if I forget "lazy" setting I get an error in muy working
test example), but when I get to IconProvider.java#67 resourceManager is
null.
I must have done some stuid error, but I'm unable to find it!

Please help!
Mauro

On 06/06/2012 23:42, Tom Schindl wrote:
> Did you put your bundle into lazy mode? DS does not work without setting
> this option in your MANIFEST.MF
>
> Tom
>
> Am 06.06.12 23:11, schrieb Mauro Condarelli:
>> Re-adding this option (I removed it because in the working example does
>> not appear) changes nothing.
>> "activate" method is not called.
>> I did set a breakpoint to org.eclipse.e4.core.di.InjectionException (and
>> all its subclasses) but it doesn't get triggered.
>>
>> Changing the sources to :
>>
>> public class IconProvider {
>> @Inject static private IResourceManager resourceManager;
>> ...
>> static public Image getIcon(int size, Object o) {
>> if (resourceManager == null) {
>> resourceManager = new ResourceManager();
>> }
>> return resourceManager.getImage(imageName(o2s(o)), size);
>> }
>> }
>>
>> works as expected, but obviously completely defeats @Injection scope.
>>
>> Can someone suggest some further debugging technique?
>>
>> TiA
>> Mauro
>>
>> On 05/06/2012 16:16, Christoph Keimel wrote:
>>> I think you are missing Bundle-ActivationPolicy: lazy in your bundle
>>> manifest. Without this option the service will not be started. This will
>>> be included, if you check "Activate this plug-in when one of its classes
>>> is loaded" on the overview tab of the manifest edtior.
>>>
>>> To test, if the service is started you can add an activate method call
>>> to your component definition:
>>>
>>> <scr:component ... name="it.condarelli.e4.resourcemanager.impl"
>>> activate="activate">
>>>
>>> And then check if the message is called in the implementation class:
>>> public void activate(ComponentContext context) {
>>> logger.info("Service ACTIVATED");
>>> }
>>
>
  • Attachment: w4.zip
    (Size: 178.23KB, Downloaded 328 times)
Re: Custom @Injection problem [message #882941 is a reply to message #882627] Thu, 07 June 2012 13:50 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Yes, I did.
I do attach the whole project.
I get NO error (if I forget "lazy" setting I get an error in muy working
test example), but when I get to IconProvider.java#67 resourceManager is
null.
I must have done some stuid error, but I'm unable to find it!

Please help!
Mauro

On 06/06/2012 23:42, Tom Schindl wrote:
> Did you put your bundle into lazy mode? DS does not work without setting
> this option in your MANIFEST.MF
>
> Tom
>
> Am 06.06.12 23:11, schrieb Mauro Condarelli:
>> Re-adding this option (I removed it because in the working example does
>> not appear) changes nothing.
>> "activate" method is not called.
>> I did set a breakpoint to org.eclipse.e4.core.di.InjectionException (and
>> all its subclasses) but it doesn't get triggered.
>>
>> Changing the sources to :
>>
>> public class IconProvider {
>> @Inject static private IResourceManager resourceManager;
>> ...
>> static public Image getIcon(int size, Object o) {
>> if (resourceManager == null) {
>> resourceManager = new ResourceManager();
>> }
>> return resourceManager.getImage(imageName(o2s(o)), size);
>> }
>> }
>>
>> works as expected, but obviously completely defeats @Injection scope.
>>
>> Can someone suggest some further debugging technique?
>>
>> TiA
>> Mauro
>>
>> On 05/06/2012 16:16, Christoph Keimel wrote:
>>> I think you are missing Bundle-ActivationPolicy: lazy in your bundle
>>> manifest. Without this option the service will not be started. This will
>>> be included, if you check "Activate this plug-in when one of its classes
>>> is loaded" on the overview tab of the manifest edtior.
>>>
>>> To test, if the service is started you can add an activate method call
>>> to your component definition:
>>>
>>> <scr:component ... name="it.condarelli.e4.resourcemanager.impl"
>>> activate="activate">
>>>
>>> And then check if the message is called in the implementation class:
>>> public void activate(ComponentContext context) {
>>> logger.info("Service ACTIVATED");
>>> }
>>
>
  • Attachment: w4.zip
    (Size: 178.23KB, Downloaded 261 times)
Re: Custom @Injection problem [message #882947 is a reply to message #882627] Thu, 07 June 2012 13:50 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Yes, I did.
I do attach the whole project.
I get NO error (if I forget "lazy" setting I get an error in muy working
test example), but when I get to IconProvider.java#67 resourceManager is
null.
I must have done some stuid error, but I'm unable to find it!

Please help!
Mauro

On 06/06/2012 23:42, Tom Schindl wrote:
> Did you put your bundle into lazy mode? DS does not work without setting
> this option in your MANIFEST.MF
>
> Tom
>
> Am 06.06.12 23:11, schrieb Mauro Condarelli:
>> Re-adding this option (I removed it because in the working example does
>> not appear) changes nothing.
>> "activate" method is not called.
>> I did set a breakpoint to org.eclipse.e4.core.di.InjectionException (and
>> all its subclasses) but it doesn't get triggered.
>>
>> Changing the sources to :
>>
>> public class IconProvider {
>> @Inject static private IResourceManager resourceManager;
>> ...
>> static public Image getIcon(int size, Object o) {
>> if (resourceManager == null) {
>> resourceManager = new ResourceManager();
>> }
>> return resourceManager.getImage(imageName(o2s(o)), size);
>> }
>> }
>>
>> works as expected, but obviously completely defeats @Injection scope.
>>
>> Can someone suggest some further debugging technique?
>>
>> TiA
>> Mauro
>>
>> On 05/06/2012 16:16, Christoph Keimel wrote:
>>> I think you are missing Bundle-ActivationPolicy: lazy in your bundle
>>> manifest. Without this option the service will not be started. This will
>>> be included, if you check "Activate this plug-in when one of its classes
>>> is loaded" on the overview tab of the manifest edtior.
>>>
>>> To test, if the service is started you can add an activate method call
>>> to your component definition:
>>>
>>> <scr:component ... name="it.condarelli.e4.resourcemanager.impl"
>>> activate="activate">
>>>
>>> And then check if the message is called in the implementation class:
>>> public void activate(ComponentContext context) {
>>> logger.info("Service ACTIVATED");
>>> }
>>
>
  • Attachment: w4.zip
    (Size: 178.23KB, Downloaded 352 times)
Re: Custom @Injection problem [message #882950 is a reply to message #882627] Thu, 07 June 2012 13:50 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Yes, I did.
I do attach the whole project.
I get NO error (if I forget "lazy" setting I get an error in muy working
test example), but when I get to IconProvider.java#67 resourceManager is
null.
I must have done some stuid error, but I'm unable to find it!

Please help!
Mauro

On 06/06/2012 23:42, Tom Schindl wrote:
> Did you put your bundle into lazy mode? DS does not work without setting
> this option in your MANIFEST.MF
>
> Tom
>
> Am 06.06.12 23:11, schrieb Mauro Condarelli:
>> Re-adding this option (I removed it because in the working example does
>> not appear) changes nothing.
>> "activate" method is not called.
>> I did set a breakpoint to org.eclipse.e4.core.di.InjectionException (and
>> all its subclasses) but it doesn't get triggered.
>>
>> Changing the sources to :
>>
>> public class IconProvider {
>> @Inject static private IResourceManager resourceManager;
>> ...
>> static public Image getIcon(int size, Object o) {
>> if (resourceManager == null) {
>> resourceManager = new ResourceManager();
>> }
>> return resourceManager.getImage(imageName(o2s(o)), size);
>> }
>> }
>>
>> works as expected, but obviously completely defeats @Injection scope.
>>
>> Can someone suggest some further debugging technique?
>>
>> TiA
>> Mauro
>>
>> On 05/06/2012 16:16, Christoph Keimel wrote:
>>> I think you are missing Bundle-ActivationPolicy: lazy in your bundle
>>> manifest. Without this option the service will not be started. This will
>>> be included, if you check "Activate this plug-in when one of its classes
>>> is loaded" on the overview tab of the manifest edtior.
>>>
>>> To test, if the service is started you can add an activate method call
>>> to your component definition:
>>>
>>> <scr:component ... name="it.condarelli.e4.resourcemanager.impl"
>>> activate="activate">
>>>
>>> And then check if the message is called in the implementation class:
>>> public void activate(ComponentContext context) {
>>> logger.info("Service ACTIVATED");
>>> }
>>
>
  • Attachment: w4.zip
    (Size: 178.23KB, Downloaded 336 times)
Re: Custom @Injection problem [message #882953 is a reply to message #882627] Thu, 07 June 2012 13:50 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Yes, I did.
I do attach the whole project.
I get NO error (if I forget "lazy" setting I get an error in muy working
test example), but when I get to IconProvider.java#67 resourceManager is
null.
I must have done some stuid error, but I'm unable to find it!

Please help!
Mauro

On 06/06/2012 23:42, Tom Schindl wrote:
> Did you put your bundle into lazy mode? DS does not work without setting
> this option in your MANIFEST.MF
>
> Tom
>
> Am 06.06.12 23:11, schrieb Mauro Condarelli:
>> Re-adding this option (I removed it because in the working example does
>> not appear) changes nothing.
>> "activate" method is not called.
>> I did set a breakpoint to org.eclipse.e4.core.di.InjectionException (and
>> all its subclasses) but it doesn't get triggered.
>>
>> Changing the sources to :
>>
>> public class IconProvider {
>> @Inject static private IResourceManager resourceManager;
>> ...
>> static public Image getIcon(int size, Object o) {
>> if (resourceManager == null) {
>> resourceManager = new ResourceManager();
>> }
>> return resourceManager.getImage(imageName(o2s(o)), size);
>> }
>> }
>>
>> works as expected, but obviously completely defeats @Injection scope.
>>
>> Can someone suggest some further debugging technique?
>>
>> TiA
>> Mauro
>>
>> On 05/06/2012 16:16, Christoph Keimel wrote:
>>> I think you are missing Bundle-ActivationPolicy: lazy in your bundle
>>> manifest. Without this option the service will not be started. This will
>>> be included, if you check "Activate this plug-in when one of its classes
>>> is loaded" on the overview tab of the manifest edtior.
>>>
>>> To test, if the service is started you can add an activate method call
>>> to your component definition:
>>>
>>> <scr:component ... name="it.condarelli.e4.resourcemanager.impl"
>>> activate="activate">
>>>
>>> And then check if the message is called in the implementation class:
>>> public void activate(ComponentContext context) {
>>> logger.info("Service ACTIVATED");
>>> }
>>
>
  • Attachment: w4.zip
    (Size: 178.23KB, Downloaded 310 times)
Re: Custom @Injection problem [message #882956 is a reply to message #882627] Thu, 07 June 2012 13:50 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Yes, I did.
I do attach the whole project.
I get NO error (if I forget "lazy" setting I get an error in muy working
test example), but when I get to IconProvider.java#67 resourceManager is
null.
I must have done some stuid error, but I'm unable to find it!

Please help!
Mauro

On 06/06/2012 23:42, Tom Schindl wrote:
> Did you put your bundle into lazy mode? DS does not work without setting
> this option in your MANIFEST.MF
>
> Tom
>
> Am 06.06.12 23:11, schrieb Mauro Condarelli:
>> Re-adding this option (I removed it because in the working example does
>> not appear) changes nothing.
>> "activate" method is not called.
>> I did set a breakpoint to org.eclipse.e4.core.di.InjectionException (and
>> all its subclasses) but it doesn't get triggered.
>>
>> Changing the sources to :
>>
>> public class IconProvider {
>> @Inject static private IResourceManager resourceManager;
>> ...
>> static public Image getIcon(int size, Object o) {
>> if (resourceManager == null) {
>> resourceManager = new ResourceManager();
>> }
>> return resourceManager.getImage(imageName(o2s(o)), size);
>> }
>> }
>>
>> works as expected, but obviously completely defeats @Injection scope.
>>
>> Can someone suggest some further debugging technique?
>>
>> TiA
>> Mauro
>>
>> On 05/06/2012 16:16, Christoph Keimel wrote:
>>> I think you are missing Bundle-ActivationPolicy: lazy in your bundle
>>> manifest. Without this option the service will not be started. This will
>>> be included, if you check "Activate this plug-in when one of its classes
>>> is loaded" on the overview tab of the manifest edtior.
>>>
>>> To test, if the service is started you can add an activate method call
>>> to your component definition:
>>>
>>> <scr:component ... name="it.condarelli.e4.resourcemanager.impl"
>>> activate="activate">
>>>
>>> And then check if the message is called in the implementation class:
>>> public void activate(ComponentContext context) {
>>> logger.info("Service ACTIVATED");
>>> }
>>
>
  • Attachment: w4.zip
    (Size: 178.23KB, Downloaded 330 times)
Re: Custom @Injection problem [message #883245 is a reply to message #882938] Fri, 08 June 2012 06:11 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
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
2.a. let the system inject IconProvider it into your Part
2.b. Create an instance using ContextInjectionFactory on your own using
the current IEclipseContext

Tom

Am 07.06.12 15:50, schrieb Mauro Condarelli:
> Yes, I did.
> I do attach the whole project.
> I get NO error (if I forget "lazy" setting I get an error in muy working
> test example), but when I get to IconProvider.java#67 resourceManager is
> null.
> I must have done some stuid error, but I'm unable to find it!
>
> Please help!
> Mauro
>
> On 06/06/2012 23:42, Tom Schindl wrote:
>> Did you put your bundle into lazy mode? DS does not work without setting
>> this option in your MANIFEST.MF
>>
>> Tom
>>
>> Am 06.06.12 23:11, schrieb Mauro Condarelli:
>>> Re-adding this option (I removed it because in the working example does
>>> not appear) changes nothing.
>>> "activate" method is not called.
>>> I did set a breakpoint to org.eclipse.e4.core.di.InjectionException (and
>>> all its subclasses) but it doesn't get triggered.
>>>
>>> Changing the sources to :
>>>
>>> public class IconProvider {
>>> @Inject static private IResourceManager resourceManager;
>>> ...
>>> static public Image getIcon(int size, Object o) {
>>> if (resourceManager == null) {
>>> resourceManager = new ResourceManager();
>>> }
>>> return resourceManager.getImage(imageName(o2s(o)), size);
>>> }
>>> }
>>>
>>> works as expected, but obviously completely defeats @Injection scope.
>>>
>>> Can someone suggest some further debugging technique?
>>>
>>> TiA
>>> Mauro
>>>
>>> On 05/06/2012 16:16, Christoph Keimel wrote:
>>>> I think you are missing Bundle-ActivationPolicy: lazy in your bundle
>>>> manifest. Without this option the service will not be started. This will
>>>> be included, if you check "Activate this plug-in when one of its classes
>>>> is loaded" on the overview tab of the manifest edtior.
>>>>
>>>> To test, if the service is started you can add an activate method call
>>>> to your component definition:
>>>>
>>>> <scr:component ... name="it.condarelli.e4.resourcemanager.impl"
>>>> activate="activate">
>>>>
>>>> And then check if the message is called in the implementation class:
>>>> public void activate(ComponentContext context) {
>>>> logger.info("Service ACTIVATED");
>>>> }
>>>
>>
>
Re: Custom @Injection problem [message #883802 is a reply to message #883245] Sat, 09 June 2012 12:30 Go to previous messageGo to next message
Mauro Condarelli is currently offline Mauro CondarelliFriend
Messages: 428
Registered: September 2009
Senior Member
Thanks Tom,
I really want to understand how Injection works, but my experiments seem
to lead to conflicting results.

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);
lblNewLabel.setImage(image);
lblNewLabel.getParent().pack(true);
}
rises an NPE because resourceManager is null (was not @Inject-ed) in
IconProvider.

Note that if I remove resourceManager injection from my test Part the
service is not started at all, which is consistent with the missing
injection.
I mean: Injection seems not attempted at all, and not failed!

Can You shed some light here?
TiA
Mauro

>
> Tom
>
> Am 07.06.12 15:50, schrieb Mauro Condarelli:
>> Yes, I did.
>> I do attach the whole project.
>> I get NO error (if I forget "lazy" setting I get an error in muy working
>> test example), but when I get to IconProvider.java#67 resourceManager is
>> null.
>> I must have done some stuid error, but I'm unable to find it!
>>
>> Please help!
>> Mauro
>>
>> On 06/06/2012 23:42, Tom Schindl wrote:
>>> Did you put your bundle into lazy mode? DS does not work without setting
>>> this option in your MANIFEST.MF
>>>
>>> Tom
>>>
>>> Am 06.06.12 23:11, schrieb Mauro Condarelli:
>>>> Re-adding this option (I removed it because in the working example does
>>>> not appear) changes nothing.
>>>> "activate" method is not called.
>>>> I did set a breakpoint to org.eclipse.e4.core.di.InjectionException (and
>>>> all its subclasses) but it doesn't get triggered.
>>>>
>>>> Changing the sources to :
>>>>
>>>> public class IconProvider {
>>>> @Inject static private IResourceManager resourceManager;
>>>> ...
>>>> static public Image getIcon(int size, Object o) {
>>>> if (resourceManager == null) {
>>>> resourceManager = new ResourceManager();
>>>> }
>>>> return resourceManager.getImage(imageName(o2s(o)), size);
>>>> }
>>>> }
>>>>
>>>> works as expected, but obviously completely defeats @Injection scope.
>>>>
>>>> Can someone suggest some further debugging technique?
>>>>
>>>> TiA
>>>> Mauro
>>>>
>>>> On 05/06/2012 16:16, Christoph Keimel wrote:
>>>>> I think you are missing Bundle-ActivationPolicy: lazy in your bundle
>>>>> manifest. Without this option the service will not be started. This will
>>>>> be included, if you check "Activate this plug-in when one of its classes
>>>>> is loaded" on the overview tab of the manifest edtior.
>>>>>
>>>>> To test, if the service is started you can add an activate method call
>>>>> to your component definition:
>>>>>
>>>>> <scr:component ... name="it.condarelli.e4.resourcemanager.impl"
>>>>> activate="activate">
>>>>>
>>>>> And then check if the message is called in the implementation class:
>>>>> public void activate(ComponentContext context) {
>>>>> logger.info("Service ACTIVATED");
>>>>> }
>>>>
>>>
>>
>
Re: Custom @Injection problem [message #883837 is a reply to message #883802] Sat, 09 June 2012 14:47 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 14:30, schrieb Mauro Condarelli:
> Thanks Tom,
> I really want to understand how Injection works, but my experiments seem
> to lead to conflicting results.
>
> 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.

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?

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 can only repeat I think the usage of statics is not a good idea I'd
suggest you make your methods none-static and
a) Pass along your resource manager to all code parts
b) Use DI for your codeparts as well this way you don't need to
remember all informations you are passing around

Remember that statics are a bad design idea something the framework got
rid in e4 and so should you in your own code.

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.

Tom
Re: Custom @Injection problem [message #883878 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 #883881 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 #883885 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 #883887 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 #883889 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 #883891 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 #883893 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 #883896 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 #883898 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 #883900 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 #883902 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 #883904 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 #883906 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 #883908 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 #883910 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 #883912 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 #883914 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 #883917 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 #883919 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 #883921 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 #883923 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 #883926 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 #883928 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 #883930 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 #883932 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 #883935 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 #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 Mar 28 14:51:04 GMT 2024

Powered by FUDForum. Page generated in 0.08790 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top