jeudi 29 septembre 2011 12:36
tja
[ASP.NET MVC 3] Unity et DependencyResolver – Enregistrement des services multiples
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 :

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 
// Thomas
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :