Lors de l’écriture de mon précédent post [ASP.NET MVC 3] Deep Dive Injection de Dépendance – ModelValidation – Partie 8 je me suis aperçu d’un petit problème avec l’implémentation de IDependencyResolver par le biais de Unity pour la résolution des services multiples. C’était le cas lors de l’enregistrement dynamique de ModelValidatorProvider qui ressemble à ceci :

   1: IUnityContainer container = new UnityContainer();
   2:            
   3: // enregistrement dynamique
   4: container.RegisterType<ModelValidatorProvider, ConventionValidatorProvider>();
   5:  
   6: DependencyResolver.SetResolver(new UnityDependencyResolver(container));

En fait ceci tout simplement ne fonctionnait pas. Rien ne se passait. Après avoir perdu une petite demi-heure j’ai commencé à regarder l’implémentation de mon IDependencyResolver qui pour rappel est comme suit :

   1: public class UnityDependencyResolver : IDependencyResolver
   2: {
   3:     private readonly IUnityContainer _container;
   4:  
   5:     public UnityDependencyResolver(IUnityContainer container)
   6:     {
   7:         if (container == null)
   8:             throw new ArgumentNullException("container", "The container cannot be null");
   9:  
  10:         _container = container;
  11:     }
  12:  
  13:     public object GetService(Type serviceType)
  14:     {
  15:         object instance;
  16:  
  17:         try
  18:         {
  19:             instance = _container.Resolve(serviceType);
  20:         }
  21:         catch
  22:         {
  23:             instance = null;
  24:         }
  25:  
  26:         return instance;
  27:     }
  28:  
  29:     public IEnumerable<object> GetServices(Type serviceType)
  30:     {
  31:         IEnumerable<object> instances;
  32:  
  33:         try
  34:         {
  35:             instances = _container.ResolveAll(serviceType);
  36:         }
  37:         catch
  38:         {
  39:             instances = new object[] { };
  40:         }
  41:  
  42:         return instances;
  43:     }
  44: }

Ce qui nous intéresse plus particulièrement c’est la méthode GetServices qui renvoie une liste de services pour un type donné. Lors du debug pour le type ModelValidatorProvider  je m’attendais à avoir mon ConventionValidatorProvider que j’ai enregistré plus tôt mais la ligne _container.ResolveAll(serviceType) s’obstinait à renvoyer null. Un petit coup d’œil sur MSDN pour trouver la solution :

MSDN_Unity

Ce qui nous intéresse c’est la phrase soulignée en rouge. Cette méthode NE RETOURNE pas d’instance pour une registration par défaut. A chaque fois je me fais avoir par ça. Il faut dire que pour moi ceci ne respecte pas le principe de PoLS. Je m’attends à ce que toutes les instances soient retournées ! C’est ResolveAll et non ResloveAllButNotDefault !

Pour que notre registration fonctionne j’ai juste modifié la ligne d’enregistrement comme ceci :

   1: container.RegisterType<ModelValidatorProvider, ConventionValidatorProvider>("convention");

Je n’aime pas du tout ça mais au moins cela fonctionne Sourire

// Thomas