Wilfried Woivré & .Net

Unity : Enregistrer des types génériques et les résoudre

MARS15

Bon une fois n’est pas coutume, cela fait vraiment longtemps que je n’ai pas publié un billet n’ayant pas de rapport avec la plateforme Windows Azure. Même si j’avoue que je viens d’utiliser cette astuce dans la future version de mon blog sur Azure, mais vous en serez plus très bientôt j’espère !

 

Alors ma problématique est la suivante, je souhaitais faire un cache générique pour mon application, et bien entendu, j’utilise Unity dans tous mes projets, et donc celui ci ne fait pas exception à la règle. J’ai donc cherché à résoudre mes dépendances selon le type dont j’ai besoin.

 

On va donc commencer par créer une interface générique comme celle-ci  :

  1. public interface MyGenericInterface<T>
  2. {
  3.     void DisplayType(T instance);
  4. }

 

On va ensuite l’implémenter dans une classe :

  1. public class MyClass : MyGenericInterface<String>
  2. {
  3.     public void DisplayType(String instance)
  4.     {
  5.         Console.WriteLine(instance.GetType().FullName + Environment.NewLine);
  6.     }
  7. }

 

Voyons maintenant comment l’enregistrer dans un conteneur Unity :

  1. private static void Configure(IUnityContainer container)
  2. {
  3.     container.RegisterType(typeof (MyGenericInterface<>), typeof(MyClass));
  4. }

Comme on peut le voir, on enregistre les types de façon assez classique, il nous faut juste ajout les chevrons afin de définir un paramètre générique.

Si par hasard, vous avez plusieurs paramètres, par exemple, il faudra faire comme ci-dessous afin de définir qu’il y a bien 3 paramètres génériques

  1. private static void Configure(IUnityContainer container)
  2. {
  3.     container.RegisterType(typeof (MyGenericInterface<,,>), typeof(MyClass));
  4. }

 

Et maintenant, voyons comment résoudre nos types, si on prend l’exemple suivant :

  1. UnityRoot.EnsureInitialized();
  2. UnityRoot.Container.Resolve<MyGenericInterface<String>>().DisplayType("Hello");
  3.  
  4. try
  5. {
  6.     UnityRoot.Container.Resolve<MyGenericInterface<Int32>>().DisplayType(42);
  7. }
  8. catch (Exception ex)
  9. {
  10.     Console.ForegroundColor = ConsoleColor.Red;
  11.     Console.WriteLine(ex);
  12.     Console.ForegroundColor = ConsoleColor.White;
  13. }

 

On va donc essayer de résoudre une classe implémentant notre interface avec le type String, et ensuite avec le type Int32. Dans notre cas, nous n’avons ajouté qu’une classe avec une interface avec le type String.

Si nous lançons notre application, nous allons donc avoir ceci  :

image

 

Nous avons bien la résolution de notre premier élément, par contre la deuxième ne marche pas comme prévu, puisque nous n’avons pas enregistrer de classe avec notre interface implémentant le type Int32.

Voilà, je ne vous donne pas le code source de la solution, puisque tout est là, il ne manque que les références à Unity, et pour cela NuGet est votre meilleur ami !

blog comments powered by Disqus