Michel Perfetti
Découverte de Unity
Unity est un « application block » dédié à l’injection de dépendances fournit par Microsoft. Dans cet article nous verrons comment l’utiliser pour limiter le couplage de nos applications
Par Michel Perfetti publié le 26/07/2009 à 22:57, lu 2867 fois, 5 pages
 3 | Unity et découplage :
La page principale du projet Unity est sur Codeplex: Unity peut se téléchargé seul pour .Net et Silverlight ou comme directement avec tous les autres « Application Blocks »
Unity ne va pas nous permettre de limiter le couplage : cela est notre responsabilité de découpler les différentes parties du logiciel. Mais Unity va nous simplifier le développement lorsque ce modèle de développement est choisit.
Unity va nous permettre de cacher les classes concrètes derrières des interfaces. Le but est de limiter le couplage à des bibliothèques d’interfaces communes aux couches logicielles. Nous allons voir avec notre exemple comment cela se présente. Unity intervient alors pour faire le lien entre ces interfaces et leurs implémentations.
Unity s’utilise généralement en 2 temps :
  • Référencement des dépendances : interface + classe concrète
  • Utilisation pour la résolution des dépendances
La première phase peut être réalisée soit par fichier de configuration soit par code. La deuxième phase implique que les couches ne seront plus accédées par les classes concrètes mais par les interfaces correspondantes. Nous allons donc pouvoir tester les couches intermédiaires en simulant par exemple les couches sous-jacentes via des technologies comme les « Stubs » ou « Mocks ».
Unity est loin d’être la seule bibliothèque sur la technologie .Net qui permet de réaliser ce genre de manipulations. Il y a par exemple « Castle Windor ».
Préparons le terrain à Unity : découplons notre programme via des interfaces. Pour commencer, nous allons créer un référentiel de donnée indépendant de notre couche de donnée via une bibliothèque supplémentaire. Cette bibliothèque s’appelle : DataLayerInterface.
Voici son code:

public class Customer

{

    public string Id { get; set; }

    public string ContactName { get; set; }

    public string CompanyName { get; set; }

}

 

public interface ICustomerDataAccess

{

    Customer Insert(string id, string contactName, string companyName);

    List<Customer> GetAllCustomer();

}

Que remarque-t-on ? La classe Customer a été déplacée ! En effet elle va être échangée entre les couches qui utilise ICustomerDataAccess et celles qui l’implémentent. Elle n’est donc plus spécifique à une couche de donnée mais à toutes les couches qui implémentent l’interface d’accès aux données.
La couche de donnée est maintenant plus simple (la classe Customer ayant disparue) à un détail près : maintenant la classe CustomerDataAccess implémente ICustomerDataAccess.

public class CustomerDataAccess : ICustomerDataAccess

{

Passons à la couche métier. Elle ne référence plus la couche de donnée mais l’interface, ce qui donne le code suivant :

public class CustomerLogic: ICustomerLogicLayer

{

    ICustomerDataAccess _dataLayer;

 

    public CustomerLogic(ICustomerDataAccess dataLayer)

    {

        _dataLayer = dataLayer;

    }

 

    public Customer Create(string customerName, string companyName)

    {          

        var id = Guid.NewGuid().ToString("N").Substring(0, 5).ToUpper();

        return _dataLayer.Insert(id, customerName, companyName);

    }

 

    public List<Customer> GetAllCustomers()

    {          

        return _dataLayer.GetAllCustomer().OrderBy(cust => cust.ContactName).ToList();

    }

}

L’instance de la couche de donnée est passée par le constructeur (on verra un peu plus loin que cela sera le travail de Unity) et la couche implémente une interface qui va permettre d’abstraire aussi cette couche aux couches appelantes. Cette interface est dans une bibliothèque à part : LogicLayerInterface :

public interface ICustomerLogicLayer

{

    Customer Create(string customerName, string companyName);

    List<Customer> GetAllCustomers();

}

Pour pouvoir utiliser ces couches, l’application de démo est légèrement modifiée pour tenir compte du changement. Les variables « logic » qui contenait les instances des couches métiers ont été modifiées comme suit :

var logic = new LogicLayer.CustomerLogic(new DataLayer.CustomerDataAccess());

Cela sera aussi le rôle de Unity de réaliser cette composition.
Regardons maintenant les dépendances (les interfaces sont en rouge):
 
/content/87a3dd53-da0d-47b5-b8fd-a5d5f353e2f3/image2.png
 
On voit à présent que les couches logiques et données ne sont plus reliées directement mais via les couches d’interface : on a donc réussit à les découpler. Ce qui veut dire que tant que les bibliothèques respectent les contrats d’interfaces elles fonctionneront toujours ensemble. Cela veut dire aussi que si la couche de donnée peut être changée tant qu’elle respecte l’interface correspondante. Cela vaut aussi pour la couche métier.
 
» Démarrer une discussion
 
Discussion démarée par stiiifff le 29/07/2009 à 02:33, 1 commentaire(s).