Home » Eclipse Projects » Eclipse 4 » Injection and SWT(Is there a better way?)
Injection and SWT [message #1017300] |
Mon, 11 March 2013 14:33 |
|
Thanks to everyone for previous injection suggestions. I've been trying to percolate injection down into my SWT layers. I've come up with a pattern to migrate my legacy code to. It seems a bit cumbersome, though, and I wondered if there was something more svelte.
So we have class A, which has been appropriately constructed and has access to an IEclipseContext. It wishes to contract class B, which extends a SWT Composite.
Previously:
Class A:
....
B mBCtrl = new B(this, SWT.NULL);
class B extends Composite {
...
public void B(Composite parent, int style) {
super(parent, style);
// some more stuff
I've been migrating this to this pattern:
Class A:
....
B mBCtrl = new B(this, SWT.NULL);
ContextInjectFactory.inject(mBCtrl, mContext);
class B extends Composite {
...
public void B(Composite parent, int style) {
super(parent, style);
}
@PostConstruct
public void init() {
// some more stuff
It works. But I'm not entirely happy with the verbosity of it. It isn't as "clean" as previously. Additionally I'm concerned that it is error prone. As I build this out into my code, if I forget to change one instance of construction, it will not catch it at compile time, and the symptom at run time will be a blank control or a NPE on something that was supposed to have been injected.
I don't suppose there is a way to "construct and inject"? E.g.
mBCtrl = (B)ContextInjectionFactory.make(mContext, B.class, parent, style);
I guess I could write a helper function to do this. Should I do that, or am I missing a better approach?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jo Grant, Senior Software Engineer
Admin and Config Console Architect
OpenPages, IBM
|
|
| |
Re: Injection and SWT [message #1017324 is a reply to message #1017307] |
Mon, 11 March 2013 15:24 |
|
We have to dispose child contexts? Erk. I didn't know that. That adds a wrinkle. Thanks for pointing that out, Christopher.
I like the way you annotate the constructor. That is much cleaner. I'm leaning much more towards a helper function now. I think I can make things much more clean. So, with a helper function that takes the class, the context, and then a variable length argument of pairs to add to the context, it can slim down to this:
Class A:
....
B mBCtrl = ContextInjectionHelper.make(B.class, context, "parent", this, "style", SWT.NULL);
class B extends Composite {
...
@Inject
public void B(@Named("parent") Composite parent, @Named("style") int style) {
super(parent, style);
// some more stuff
Which is, pretty much, no additional lines of code. And it should detect a bad call at compile time. Much better!
Here is the helper code:
public static <T> T make(Class<T> clazz, IEclipseContext context, Object... subContextElements)
{
T o;
if (subContextElements.length == 0)
o = (T)ContextInjectionFactory.make(clazz, context);
else
{
if ((subContextElements.length%2) != 0)
throw new IllegalArgumentException("Expected even number of context element pairs!");
final EclipseContext subContext = new EclipseContext(context);
for (int i = 0; i < subContextElements.length; i += 2)
if (subContextElements[i] instanceof String)
subContext.set((String)subContextElements[i+0], subContextElements[i+1]);
else if (subContextElements[i] instanceof Class<?>)
subContext.set((Class)subContextElements[i+0], subContextElements[i+1]);
o = (T)ContextInjectionFactory.make(clazz, subContext);
if (o instanceof Control)
((Control)o).addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent ev)
{
subContext.dispose();
}
});
//else object must take care of disposing context
}
return o;
}
It would be nifty to see this in ContextInjectionFactory, but I think it adds too many constraints to go into core code.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jo Grant, Senior Software Engineer
Admin and Config Console Architect
OpenPages, IBM
|
|
|
Goto Forum:
Current Time: Tue Sep 24 12:09:13 GMT 2024
Powered by FUDForum. Page generated in 0.03467 seconds
|