Skip to main content
Jump to: navigation, search

Difference between revisions of "Riena Getting Started with Wiring"

m (Conclusion)
 
(25 intermediate revisions by 4 users not shown)
Line 1: Line 1:
== Getting Started with Wiring ==
+
{{#eclipseproject:rt.riena}}
 +
{{RienaBreadcrumbs|
 +
[[Riena Project]] | [[Riena Getting started|Getting Started]] | Wiring }}
  
Before you continue reading this please read [[Riena Getting Started with injecting services and extensions]].
+
{| align="right"
 +
| __TOC__
 +
|}
 +
Please read [[Riena Getting Started with injecting services and extensions]] first before you continue reading this page. A basic understanding of Riena's injection mechanism is necessary for understanding Riena's wiring mechanism.
  
== Use case ==
+
== Use case: Why Wiring? ==
Within an Eclipse RCP based applications components often start their life cycle because they were contributed as an executable extension <code> org.eclipse.core.runtime.IConfigurationElement.createExecutableExtension(String)</code>.
+
In Eclipse-RCP-based applications, components often start their life cycle because they were contributed as an executable extension <code> org.eclipse.core.runtime.IConfigurationElement.createExecutableExtension(String)</code>.
  
Who or what is responsible for injecting the needed services and/or extensions into these objects? And how does it know what to inject?
+
Who or what is responsible for injecting the required services and/or extensions into these objects? And how to know what to inject? Moreover it is often desirable not to invoke an <code>Inject.…</code> sentence within the classes that need injecting.
== Wiring ==
+
 
The answer to this question is ''Wiring''. With the following ''sentence'' it is possible to initiate the wiring, i.e. perform all the necessary injections of services and extensions.
+
The answer to these questions is '''Wiring'''. With the following ''sentence'' it is possible to initiate the wiring, i.e. perform all the necessary injections of services and extensions.
 
<source lang=java>
 
<source lang=java>
 
Wire.instance(object).andStart(context);
 
Wire.instance(object).andStart(context);
 
</source>
 
</source>
Well, that looks really easy, but ''grübel grübel'' how does that work?
+
Well, that looks really easy, but you may wonder how it works? This is the topic of the next section.
 +
 
 +
== Specifying a wiring ==
 +
There are two ways of specifying what needs to be done: Introducing a dedicated class responsible for the wiring, and annotating a method that requires injection.
  
Wiring supports two options for telling what should be done.
+
=== Wiring through a dedicated class ===
== Wiring through a dedicated class ==
+
This option is the most flexible but least convenient way. The class that needs to have services or extensions injected (i.e. the target class) specifies, using an annotation, another class that be responsible for the ''wiring'':
This option is the most flexible but also the least convenient way. The class that needs services or extensions injected has to specify with an annotation another class which is responsible for the ''wiring''.
+
The target class looks like that:
+
 
<source lang=java>
 
<source lang=java>
 
@WireWith(SSLConfigurationWiring.class)
 
@WireWith(SSLConfigurationWiring.class)
Line 23: Line 29:
  
 
public void configure(ISSLProperties properties) {
 
public void configure(ISSLProperties properties) {
..
+
...
 
}
 
}
 
}
 
}
 
</source>
 
</source>
And the actual wiring is than performed by the class defined in the annotation:
+
The actual wiring is then performed by the class defined in the annotation, implementing the methods <code>wire(...)</code> and <code>unwire(...)</code>:
 
<source lang=java>
 
<source lang=java>
 
public class SSLConfigurationWiring extends AbstractWiring {
 
public class SSLConfigurationWiring extends AbstractWiring {
Line 40: Line 46:
 
public void wire(Object bean, BundleContext context) {
 
public void wire(Object bean, BundleContext context) {
 
sslInjector = Inject.extension("org.eclipse.riena.communication.core.ssl").expectingMinMax(0, 1).into(bean).update(
 
sslInjector = Inject.extension("org.eclipse.riena.communication.core.ssl").expectingMinMax(0, 1).into(bean).update(
"configure").andStart(context); //$NON-NLS-1$
+
"configure").andStart(context);
 
}
 
}
 
}
 
}
 
</source>
 
</source>
This code uses the well known <code>Inject.</code> to perform the necessary injections. As mentioned before this the most flexible approach because within the <code>wire</code> and <code>unwire</code> methods you can do anything you like.
+
Here we use Riena's [[Riena Getting Started with injecting services and extensions | well-known]] <code>Inject.</code> to perform the necessary injections. Note how we explicitly specify that the update method shall be named "configure".
  
Since this seldom required there is another approach.
+
This approach is the most flexible because within the <code>wire(...)</code> and <code>unwire(...)</code> methods you can do anything you like. When you do not need this flexibility, you can use a simpler approach, described in the following section.
== Wiring through annotations ==
+
 
The same ''wiring'' could be done with:
+
=== Wiring through annotations ===
 +
The same ''wiring'' can be done with:
 
<source lang=java>
 
<source lang=java>
 
public class SSLConfiguration {
 
public class SSLConfiguration {
Line 54: Line 61:
 
@InjectExtension(id = "org.eclipse.riena.communication.core.ssl", min = 0, max = 1)
 
@InjectExtension(id = "org.eclipse.riena.communication.core.ssl", min = 0, max = 1)
 
public void configure(ISSLProperties properties) {
 
public void configure(ISSLProperties properties) {
..
+
...
 
}
 
}
 
}
 
}
 
</source>
 
</source>
Oops, that´s all? Yes, it is. But as mentioned before less flexible but much more convenient. However, under the hood it will do exactly the same as shown in the ''less'' convenient approach.
+
You might ask: That's all? Yes, it is. Under the hood it will do exactly the same as the previous less-convenient approach. For example, there is no longer any need to specify how the update method needs to be called, because we denote this by ''annotating'' the method to be used, in this case <code>configure(...)</code>.
 +
 
 +
If the extension point ID is defined as a constant named "ID" in the extension interface:
 +
<source lang=java>
 +
@ExtensionInterface
 +
public interface ISSLProperties {
 +
 
 +
String ID = "org.eclipse.riena.communication.core.ssl";
 +
...
 +
}
 +
</source>
 +
… wiring can be even more concise:
 +
<source lang=java>
 +
public class SSLConfiguration {
 +
 
 +
@InjectExtension(min = 0, max = 1)
 +
public void configure(ISSLProperties properties) {
 +
...
 +
}
 +
}
 +
</source>
 +
 
 +
Of course, you can use corresponding annotations for injecting ''services'' through wiring as well. The shortest form is:
 +
<source lang=java>
 +
public class CustomerSearchSubModuleController extends SubModuleController {
 +
 
 +
@InjectService()
 +
public void bind(ICustomerSearch service) {
 +
...
 +
}
 +
 
 +
public void unbind(ICustomerSearch service) {
 +
...
 +
}
 +
}
 +
</source>
 +
This will inject the <code>ICustomerSearch</code> service into the annotated <code>bind(...)</code> method. The <code>unbind(...)</code> method's name is deduced from the name of the annotated bind method by prefixing it with "un". You can also specify explicitly the service class or name, the unbind method name and other properties with parameters of the annotation.
 +
 
 
== Back to our use case ==
 
== Back to our use case ==
If you define executable extensions that need to be wired, you don´t have to care. Just provide your class with the approach the suit your needs. And Riena´s extension injector will automatically do the wiring.
+
If you define executable extensions that need to be wired, you don't need to care. Just provide your class with the approach that suits your needs best. And Riena's extension injector will automatically do the wiring.
  
Of course you can initiate wiring everywhere you want by explicitly calling <code>Wire...</code>
+
Of course you can initiate wiring everywhere you want by explicitly calling <code>Wire.</code>
  
== Wrap up ==
+
== Wrap-up ==
Riena´s wiring simplifies writing of components that need services or extensions injected. Especially when those components start their life cycle through executable extensions.
+
Riena's wiring simplifies writing components that need services or extensions injected. Especially when those components start their life cycle through executable extensions.
  
  
 
[[Category:Riena]]
 
[[Category:Riena]]

Latest revision as of 03:40, 8 July 2011

{{#eclipseproject:rt.riena}}

Please read Riena Getting Started with injecting services and extensions first before you continue reading this page. A basic understanding of Riena's injection mechanism is necessary for understanding Riena's wiring mechanism.

Use case: Why Wiring?

In Eclipse-RCP-based applications, components often start their life cycle because they were contributed as an executable extension org.eclipse.core.runtime.IConfigurationElement.createExecutableExtension(String).

Who or what is responsible for injecting the required services and/or extensions into these objects? And how to know what to inject? Moreover it is often desirable not to invoke an Inject.… sentence within the classes that need injecting.

The answer to these questions is Wiring. With the following sentence it is possible to initiate the wiring, i.e. perform all the necessary injections of services and extensions.

Wire.instance(object).andStart(context);

Well, that looks really easy, but you may wonder how it works? This is the topic of the next section.

Specifying a wiring

There are two ways of specifying what needs to be done: Introducing a dedicated class responsible for the wiring, and annotating a method that requires injection.

Wiring through a dedicated class

This option is the most flexible but least convenient way. The class that needs to have services or extensions injected (i.e. the target class) specifies, using an annotation, another class that be responsible for the wiring:

@WireWith(SSLConfigurationWiring.class)
public class SSLConfiguration {
 
	public void configure(ISSLProperties properties) {
	...
	}
}

The actual wiring is then performed by the class defined in the annotation, implementing the methods wire(...) and unwire(...):

public class SSLConfigurationWiring extends AbstractWiring {
	private ExtensionInjector sslInjector;
 
	@Override
	public void unwire(Object bean, BundleContext context) {
		sslInjector.stop();
	}
 
	@Override
	public void wire(Object bean, BundleContext context) {
		sslInjector = Inject.extension("org.eclipse.riena.communication.core.ssl").expectingMinMax(0, 1).into(bean).update(
				"configure").andStart(context);
	}
}

Here we use Riena's well-known Inject.… to perform the necessary injections. Note how we explicitly specify that the update method shall be named "configure".

This approach is the most flexible because within the wire(...) and unwire(...) methods you can do anything you like. When you do not need this flexibility, you can use a simpler approach, described in the following section.

Wiring through annotations

The same wiring can be done with:

public class SSLConfiguration {
 
	@InjectExtension(id = "org.eclipse.riena.communication.core.ssl", min = 0, max = 1)
	public void configure(ISSLProperties properties) {
	...
	}
}

You might ask: That's all? Yes, it is. Under the hood it will do exactly the same as the previous less-convenient approach. For example, there is no longer any need to specify how the update method needs to be called, because we denote this by annotating the method to be used, in this case configure(...).

If the extension point ID is defined as a constant named "ID" in the extension interface:

@ExtensionInterface
public interface ISSLProperties {
 
	String ID = "org.eclipse.riena.communication.core.ssl";
	...
}

… wiring can be even more concise:

public class SSLConfiguration {
 
	@InjectExtension(min = 0, max = 1)
	public void configure(ISSLProperties properties) {
	...
	}
}

Of course, you can use corresponding annotations for injecting services through wiring as well. The shortest form is:

public class CustomerSearchSubModuleController extends SubModuleController {
 
	@InjectService()
	public void bind(ICustomerSearch service) {
	...
	}
 
	public void unbind(ICustomerSearch service) {
	...
	}
}

This will inject the ICustomerSearch service into the annotated bind(...) method. The unbind(...) method's name is deduced from the name of the annotated bind method by prefixing it with "un". You can also specify explicitly the service class or name, the unbind method name and other properties with parameters of the annotation.

Back to our use case

If you define executable extensions that need to be wired, you don't need to care. Just provide your class with the approach that suits your needs best. And Riena's extension injector will automatically do the wiring.

Of course you can initiate wiring everywhere you want by explicitly calling Wire.…

Wrap-up

Riena's wiring simplifies writing components that need services or extensions injected. Especially when those components start their life cycle through executable extensions.

Back to the top