<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>La Fabrick &#187; IOC</title>
	<atom:link href="http://www.lafabrick.com/blog/tag/ioc/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lafabrick.com/blog</link>
	<description>Laboratoire d&#039;interfaces riches (Flex, Flash, Air ...)</description>
	<lastBuildDate>Mon, 28 Nov 2011 22:02:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.4</generator>
		<item>
		<title>Reflex #2 : vous reprendrez bien un peu de IOC ?</title>
		<link>http://www.lafabrick.com/blog/2009/01/15/819-reflex-2-vous-reprendez-bien-un-peu-de-ioc/</link>
		<comments>http://www.lafabrick.com/blog/2009/01/15/819-reflex-2-vous-reprendez-bien-un-peu-de-ioc/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 22:16:49 +0000</pubDate>
		<dc:creator>Fabien</dc:creator>
				<category><![CDATA[Bientôt chez vous]]></category>
		<category><![CDATA[La Fabrick]]></category>
		<category><![CDATA[Nos projets]]></category>
		<category><![CDATA[[Dev] Flash / Flex / AIR...]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[IOC]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[Tutoriels]]></category>

		<guid isPermaLink="false">http://www.lafabrick.com/blog/?p=819</guid>
		<description><![CDATA[Reflex intègre un système d’Injection de contenu, qui est l’une des représentations de l’IOC. Nous allons voir ici à quoi cela sert, et comment le mettre en œuvre dans Reflex. Si ce n’est déjà fait, je vous laisse jeter un œil sur la première partie de cette architecture, et de récupérer le swc avant de [...]]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter" title="reflex image tuto 2" src="http://www.lafabrick.com/labz/reflex/images/reflexImgTuto2.jpg" alt="" width="520" height="230" /><br />
Reflex intègre un système d’Injection de contenu, qui est l’une des représentations de l’IOC.<br />
Nous allons voir ici à quoi cela sert, et comment le mettre en œuvre dans Reflex.</p>
<p>Si ce n’est déjà fait, je vous laisse jeter un œil sur <a href="http://www.lafabrick.com/blog/2009/01/13/786-reflex-1-une-micro-architecture-pour-flex-simple/">la première partie de cette architecture</a>, et de <a href="http://www.lafabrick.com/blog/reflex/">récupérer le swc</a> avant de lire la suite.<br />
<span id="more-819"></span></p>
<h3><strong>A quoi ça sert l’IOC ?</strong></h3>
<p>L’IOC ( Inversion Of Control ) est un patron d’architecture, possédant plusieurs représentations ( inversion de contrôle, injection de dépendance, &#8230;).  Je ne vais pas faire un cours sur l’Injection de contenu : je vous laisse <a href="http://fr.wikipedia.org/wiki/Inversion_de_contr%C3%B4le">voir ici </a>pour plus d’informations.</p>
<p>Dans Reflex, le but du package IOC est de décentraliser les objets de configurations de l’application. En gros, mettre les services d’accès aux données dans un fichier de configuration XML au lieu de les coder en dur dans l&#8217;application Flex.</p>
<p>Certains spécialistes me diront certainement que l’Injection de contenu n’est pas forcement une représentation de l’IOC, et donc un abus de langage pour Reflex : je répondrais par “traduisez ici IOC par Injection Of Content, et laissons tomber les patrons d’architecture !”.</p>
<h3><strong>Au commencement, le ServicesLocator</strong></h3>
<p>Nous avons vu dans la première partie comment réaliser simplement un appel à une méthode distante. Avoir un point d’accès global aux différents services est pratique lorsque l’on commence à avoir plusieurs services, ou si des vues différentes utilisent un service identique. Voyons comment procéder avec le premier exemple.</p>
<p>Reprenons l’exemple du <a href="http://www.lafabrick.com/blog/2009/01/13/786-reflex-1-une-micro-architecture-pour-flex-simple/">tuto #1</a> :  il faut charger <strong>les services</strong> dans le <strong>ServicesLocator</strong>. Nous allons donc modifier notre vue :</p>
<pre class="brush: xml">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Application
	xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
	layout=&quot;absolute&quot;

	creationComplete=&quot;init()&quot;

	xmlns:controller=&quot;controller.*&quot;
	xmlns:model=&quot;model.*&quot;&gt;

	&lt;mx:Script&gt;
		&lt;![CDATA[
			import com.lafabrick.reflex.service.ServicesLocator;

			public static const SERVICE_USER:String = &quot;userService&quot;;
			public static const SERVICE_OTHER:String = &quot;otherService&quot;;

			private function init() : void
			{
				ServicesLocator.addService( SERVICE_USER, remoteUser );
				ServicesLocator.addService( SERVICE_OTHER, remoteOther );

				userControl.service = ServicesLocator.getService( SERVICE_USER );
			}

		]]&gt;
	&lt;/mx:Script&gt;

	&lt;mx:RemoteObject id=&quot;remoteUser&quot;
		destination=&quot;javaFacadeUser&quot; showBusyCursor=&quot;true&quot; /&gt;

	&lt;mx:RemoteObject id=&quot;remoteOther&quot;
		destination=&quot;javaFacadeOther&quot; showBusyCursor=&quot;true&quot; /&gt;

	&lt;controller:UserController id=&quot;userControl&quot; /&gt;

	&lt;model:UserModel id=&quot;userModel&quot; /&gt;

	&lt;mx:VBox&gt;
		&lt;mx:TextInput id=&quot;login&quot; /&gt;
		&lt;mx:TextInput id=&quot;password&quot; displayAsPassword=&quot;true&quot; /&gt;

		&lt;mx:Button label=&quot;connect&quot;
			click=&quot;{userControl.login(login.text, password.text)}&quot; /&gt;

		&lt;mx:Label x=&quot;208&quot; y=&quot;44&quot;
			text=&quot;User Name : {userModel.userLogged.name}&quot;/&gt;
	&lt;/mx:VBox&gt;

&lt;/mx:Application&gt;
</pre>
<ul>
<li>À la création de l’application ( <em>creationComplete</em> ), nous déclenchons la fonction<strong> init();</strong>.</li>
<li>Nous ajoutons les services <strong>RemoteObject</strong> dans le <a href="http://www.lafabrick.com/labz/reflex/apidoc/com/lafabrick/reflex/service/ServicesLocator.html">ServicesLocator</a>. La signature de cette méthode est la suivante :
<pre class="brush: js">
ServicesLocator.addService( serviceName:String, serviceObject:AbstractService )
</pre>
<p> </p>
<ul>
<li>  <strong><em>  serviceName:String</em></strong> est le nom de référence utilisé pour indexer, et plus tard retrouver le bon service.</li>
<li><strong><em>serviceObject:AbstractService</em></strong> est l’identifiant (id) de l’object service (le RemoteObject). </li>
</ul>
</li>
<li>Nous supprimons la propriété <strong><em>service</em></strong> dans la déclaration mxml de <strong>UserController</strong>, pour la déclarer en ActionScript dans la fonction<strong> init()</strong>.   ServicesLocator.getService( serviceName:String ) renvoie l’instance du service défini par serviceName, référencée dans le locator.</li>
</ul>
<p><strong>Note</strong> : Au niveau de l’appel du service, nous pourrions appeler la méthode <strong>getController</strong> de <a href="http://www.lafabrick.com/labz/reflex/apidoc/com/lafabrick/reflex/controller/ControllerLocator.html">ControllerLocator</a>.</p>
<pre class="brush: js">
userControl.login(login.text, password.text); 
</pre>
<p>devient :</p>
<pre class="brush: js">
( ControllerLocator.getController( MonApplication.SERVICE_USER )
	as UserController ).login(login.text, password.text);
</pre>
<p>Dans ce cas, nous devons &laquo;&nbsp;caster&nbsp;&raquo; le retour de <strong>getController(&#8230;)</strong> en <strong>UserController</strong> ( sinon erreur ! Flex ne connaîtrait pas la méthode login )</p>
<h3><strong>Un composant pour la vue</strong></h3>
<p>Histoire de mettre en pratique un peu plus l’utilisation des “locators” de Reflex, nous allons créer un composant MXML étendant <strong>Canvas</strong>, qui va contenir la représentation visuelle de notre application. Nous allons utiliser <strong>ControllerLocator</strong> dans ce fichier pour récupérer le <strong>UserController</strong>.</p>
<pre class="brush: xml">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Canvas
	xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
	width=&quot;100%&quot;
	height=&quot;100%&quot;&gt;

	&lt;mx:Script&gt;
		&lt;![CDATA[
			import model.UserModel;
			import controller.UserController;
			import com.lafabrick.reflex.controller.ControllerLocator;
			import com.lafabrick.reflex.model.ModelLocator;

			[Bindable]
			private var userDataModel:UserModel =
				( ModelLocator.getModel( UserModel ) as UserModel);

		]]&gt;
	&lt;/mx:Script&gt;

	&lt;mx:VBox horizontalCenter=&quot;0&quot; verticalCenter=&quot;0&quot;&gt;
		&lt;mx:TextInput id=&quot;login&quot; /&gt;
		&lt;mx:TextInput id=&quot;password&quot; displayAsPassword=&quot;true&quot; /&gt;

		&lt;mx:Button
			label=&quot;connect&quot;
			click=&quot;{ ( ControllerLocator.getController( UserController )
				as UserController ).login( login.text, password.text )}&quot; /&gt;

		&lt;mx:Label x=&quot;208&quot; y=&quot;44&quot;
			text=&quot;User Name : {userDataModel.userLogged.name}&quot;/&gt;
	&lt;/mx:VBox&gt;

&lt;/mx:Canvas&gt;
</pre>
<p>Pour que le “<strong>Binding</strong>” fonctionne correctement entre la vue et le modèle, nous devons utiliser des pointeurs vers les modèles à utiliser.</p>
<h3><strong>Le fichier de configuration XML (IOC)</strong></h3>
<p>Nous venons de voir comment utiliser le <a href="http://www.lafabrick.com/labz/reflex/apidoc/com/lafabrick/reflex/service/ServicesLocator.html">ServiceLocator</a>. Intégrons maintenant le système <strong>IOC</strong> pour ne plus avoir à le gérer  !</p>
<p>Ce fichier vous permet de décrire des objets, pour ensuite les récupérer et les instancier dans votre application ( via <a href="http://www.lafabrick.com/labz/reflex/apidoc/com/lafabrick/reflex/ioc/ApplicationContext.html">ApplicationContext</a> ). Ce fichier s’inspire fortement des fichiers de configuration de Spring, un framework puissant pour Java.</p>
<p>Ci-dessous le fichier représentant 2 services <strong>RemoteObject</strong> :</p>
<pre class="brush: xml">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;objects&gt;

	&lt;object id=&quot;remotingUser&quot; className=&quot;mx.rpc.remoting.mxml.RemoteObject&quot;&gt;
		&lt;property name=&quot;destination&quot; className=&quot;String&quot;&gt;javaFacadeUser&lt;/property&gt;
		&lt;property name=&quot;showBusyCursor&quot; className=&quot;Boolean&quot;&gt;true&lt;/property&gt;
	&lt;/object&gt;

	&lt;object id=&quot;remotingOther&quot; className=&quot;mx.rpc.remoting.mxml.RemoteObject&quot;&gt;
		&lt;property name=&quot;destination&quot; className=&quot;String&quot;&gt;javaFacadeOther&lt;/property&gt;
		&lt;property name=&quot;showBusyCursor&quot; className=&quot;Boolean&quot;&gt;true&lt;/property&gt;
	&lt;/object&gt;

&lt;/objects&gt;
</pre>
<ul>
<li>Le tag <strong>&lt;objects&gt;</strong> englobe les différents objets définis dans le fichier. Il est défini par :</li>
<li>Un objet <strong>&lt;object&gt;</strong> est défini par :
<ul>
<li>un identifiant <strong><em>id</em></strong>. Cet id est celui que nous utiliserons plus tard dans l’application Flex pour retrouver et instancier l’objet.</li>
<li> un nom de classe <strong><em>className</em></strong> : la classe de référence.</li>
</ul>
</li>
<li>Les propriétés des objets sont définies par :
<ul>
<li>leur nom <strong><em>name</em></strong></li>
<li>leur classe <strong><em>className</em></strong> de référence.</li>
</ul>
</li>
</ul>
<p>Ici, un <a href="http://livedocs.adobe.com/flex/3/langref/mx/rpc/remoting/mxml/RemoteObject.html">RemoteObject</a> a besoin de 2 propriétés : la <em>destination</em> du type String, et éventuellement <em>showBusyCursor</em> du type Boolean.</p>
<h3><strong>Régler le problème d’inclusion de classe</strong></h3>
<p>Le “petit” problème de ce système est que la déclaration externe des objets fait que les classes ne sont pas intégrées dans le projet Flex. Le compilateur Flex ne trouve pas de référence aux classes, et ne les intègre donc pas dans la compilation. Un façon très simple de régler ce problème est de créer un petit fichier actionScript, et d’ajouter des objets bidons du même type que ceux définis dans votre fichier de config.</p>
<p>Exemple avec les services : (fichier includeService.as)</p>
<pre class="brush: js">
import mx.rpc.http.mxml.HTTPService;
import mx.rpc.remoting.mxml.RemoteObject;
import mx.rpc.soap.mxml.WebService;

private var ser1:RemoteObject;
private var ser2:HTTPService;
private var ser3:WebService;
</pre>
<p>Ce fichier sera intégré dans votre application.</p>
<h3><strong>Chargement et gestion du contexte XML</strong></h3>
<p>Vous allez voir : simple comme bonjour !<br />
Nous allons ajouter le chargement du fichier via <a href="http://www.lafabrick.com/labz/reflex/apidoc/com/lafabrick/reflex/ioc/ApplicationContext.html">ApplicationContext</a>. <strong>ApplicationContext</strong> permet de charger automatiquement le contexte cible, et de retrouver, instancier, et<strong> enregistrer automatiquement tous les service</strong>s qui se trouvent dans votre fichier de configuration XML dans le <strong>ServicesLocator</strong>.</p>
<p>Votre application finale :</p>
<pre class="brush: xml">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Application
	xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
	layout=&quot;absolute&quot;

	creationComplete=&quot;init()&quot;

	xmlns:model=&quot;model.*&quot;
	xmlns:view=&quot;view.*&quot;
	xmlns:controller=&quot;controller.*&quot;
	xmlns:service=&quot;service.*&quot;&gt;

	&lt;mx:Script&gt;
		&lt;![CDATA[
			import com.lafabrick.reflex.ioc.event.ContextEvent;
			import com.lafabrick.reflex.ioc.ApplicationContext;
			import com.lafabrick.reflex.controller.ControllerLocator;
			import com.lafabrick.reflex.service.ServicesLocator;

			include &quot;includeService.as&quot;

			private function init() : void
			{
				ApplicationContext.addEventListener(
					ContextEvent.CONTEXT_LOADED, onLoaded );

				ApplicationContext.load( &quot;ioc/application-config.xml&quot; );
			}

			private function onLoaded( event:ContextEvent ) :void
			{
				// Contexte chargé
				// ...
			}

		]]&gt;
	&lt;/mx:Script&gt;

	&lt;controller:UserController id=&quot;userControl&quot; /&gt;

	&lt;model:UserModel id=&quot;userModel&quot; /&gt;

	&lt;view:LoginView id=&quot;view&quot; /&gt;

&lt;/mx:Application&gt;
</pre>
<ul>
<li>Nous continuons à utiliser le “<strong>creationComplete</strong>” pour déclencher la fonction<strong> init()</strong> qui chargera le fichier de configuration.</li>
<li>Il ne faut pas oublier d’inclure au besoin les classes contenues dans notre fichier de config !
<pre class="brush: js">
include &quot;includeService.as&quot;
</pre>
</li>
<li>Dans la fonction<strong> init()</strong>, nous ajoutons un écouteur sur <strong>ApplicationContext</strong> (<a href="http://www.lafabrick.com/labz/reflex/apidoc/com/lafabrick/reflex/ioc/event/ContextEvent.html#CONTEXT_LOADED">ContextEvent.CONTEXT_LOADED</a>), qui déclenchera la fonction <strong>onLoaded</strong> quand le fichier de configuration sera chargé. Puis nous lançons le chargement du fichier de config (<strong> ioc/application-config.xml</strong> ).</li>
<li>&#8230; Et nous incluons la vue LoginView.</li>
</ul>
<h3><strong>Modification de notre UserController</strong></h3>
<p>Dans un soucis de clarté, nous allons créer 2 classes contenants les constantes référençants les noms des services (contenus dans le fichier de configuration), et les noms des méthodes de ces services.</p>
<p>MethodConstant (dans notre exemple uniquement la méthode login)</p>
<pre class="brush: js">
package service
{
	public class MethodConstant
	{
		public static const LOGIN:String = &quot;login&quot;;
	}
}
</pre>
<p>ServiceConstant (les identifiants des objets contenus dans le fichier de configuration)</p>
<pre class="brush: js">
package service
{
	public class ServiceConstant
	{
		public static const SERVICE_USER:String = &quot;remotingUser&quot;;
		public static const SERVICE_OTHER:String = &quot;remotingOther&quot;;
	}
}
</pre>
<p>Nous venons de charger notre fichier de configuration au niveau de notre Application. Nous devons maintenant modifier notre contrôleur pour qu&#8217;il <strong>écoute le chargement du fichier</strong> (événement ContextEvent.CONTEXT_LOADED), et <strong>mette à jour sa propriété service</strong>.</p>
<pre class="brush: js">
package controller
{
	import com.lafabrick.reflex.controller.BaseController;
	import com.lafabrick.reflex.ioc.ApplicationContext;
	import com.lafabrick.reflex.ioc.event.ContextEvent;
	import com.lafabrick.reflex.model.ModelLocator;
	import com.lafabrick.reflex.service.ServicesLocator;

	import dataObject.UserDo;

	import model.UserModel;

	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;

	import service.MethodConstant;
	import service.ServiceConstant;

	public class UserController extends BaseController
	{

		public function UserController() : void
		{
			ApplicationContext.addEventListener(ContextEvent.CONTEXT_LOADED, onLoaded);
		}

		private function onLoaded( event:ContextEvent ) :void
		{
			// Contexte chargé
			this.service = ServicesLocator.getService( ServiceConstant.SERVICE_USER );
		}

		public function login( log:String, pass:String ) : void
		{
			executeMethod(MethodConstant.LOGIN, onLoginResult, onLoginFault, log, pass);
		}

		public function onLoginResult( event:ResultEvent ) : void
		{
			(ModelLocator.getModel( UserModel ) as UserModel).userLogged =
				event.result as UserDo;

			trace((ModelLocator.getModel( UserModel ) as UserModel).userLogged.name);
		}
		public function onLoginFault( event:FaultEvent ) : void
		{
			trace(&quot;resultat pourri ...&quot;+event.fault);
		}

	}
}
</pre>
<p><strong><a href="http://www.lafabrick.com/labz/reflex/tuto/reflexTuto2.zip">Les sources de cette exemple</a></strong></p>
<p>Et voilà ! Je vais préparer d&#8217;autres articles, notemment l&#8217;intégration de Reflex dans un projet Gumbo/Flex4. N&#8217;hésitez pas à poster vos retours, c&#8217;est en flexant qu&#8217;on devient flexeron.Autres articles sur le même sujet
<ul>
<li><a href="http://www.lafabrick.com/blog/2007/10/03/256-titre/" rel="bookmark" title="3 octobre 2007">Utiliser Cairngorm dans un projet Flex / AMFPHP</a></li>
<li><a href="http://www.lafabrick.com/blog/2008/06/06/327-google-language-api-flex/" rel="bookmark" title="6 juin 2008">Google AJAX Language API&#8230; et ton Flex devient polyglotte !</a></li>
<li><a href="http://www.lafabrick.com/blog/2009/01/13/786-reflex-1-une-micro-architecture-pour-flex-simple/" rel="bookmark" title="13 janvier 2009">Reflex #1: une micro-architecture pour Flex&#8230; simple !</a></li>
<li><a href="http://www.lafabrick.com/blog/2010/07/14/1920-flex-4-layouts-viewstack-pure-spark/" rel="bookmark" title="14 juillet 2010">Flex 4 et les layouts &#8211; Faire une ViewStack &laquo;&nbsp;pure&nbsp;&raquo; Spark</a></li>
</ul>
<p><!-- Similar Posts took 12.206 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lafabrick.com/blog/2009/01/15/819-reflex-2-vous-reprendez-bien-un-peu-de-ioc/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

