Bonjour,
On (sur le web et sur cette liste) a parlé il y a quelques mois du
problème de la multiplication des méthodes de recherche comme décrit
sur le blog d'Ayende :
http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx.
Une des solutions est de créer des QueryObject. C'est la solution que
nous implémentons mais en ajoutant quelques subtilités et c'est là que
j'ai des questions.
1) Nous avons fait des QueryObject de 2 types, soit simples pour gérer
les DateTime, Integer, soit composites pour décomposer des recherches
un peu complexes (comme sur la ligne métier du client des informations
à retourner, i.e recherche sur Information.Client.BusinessLine...),
pour effectuer une requête, on a donc un code du genre :
InformationQueryObject info = new InformationQueryObject(); // inherit
from CompositeQueryObject
info.Client = new ClientQueryObject(); // inherit from
CompositeQueryObject
info.Client.BusinessLine = new BusinessLineQueryObject(); // inherit
from CompositeQueryObject
info.Client.BusinessLine.Id = "12"; // value that come from a
DropDownList.Value for example, converted by BusinessLineQueryObject
into an IntegerQueryObject, which is added to the collection of
component of the composite
ApplicationService.Search(info);
Je suis un peu géné par ce code, mais je ne sais pas trop l'expliquer
comme ça...n'auriez-vous pas des commentaires à faire ?
2) On souhaitait supprimer la corrélation entre les valeurs
particulières gérées dans les listes déroulantes du site et les
filtres appliqués en base, ainsi que la complexité conditionnelle
induite au niveau de l'accès, on a utilisé des SpecialCase des
QueryObject afin de gérer ces cas particuliers, combiné à
l'utilisation du container IoC. Par exemple, on a la classe de base
BusinessLineQueryObject et un SpecialCase AnyBusinessLineQueryObject
(qui hérite de BusinessLineQueryObject pour surcharger le
comportement), la première applique le filtre sur la ligne métier,
alors que le SpecialCase n'applique aucun filtre. On doit donc
instancier la bonne classe en fonction de la valeur sélectionnée dans
la liste déroulante correspondante, ce que nous déléguons à une classe
encapsulant le container IoC (AbstractFactory). Cela donne un code du
genre :
InformationQueryObject info =
AbstractFactory.GetInstance<InformationQueryObject>();
info.Client = AbstractFactory.GetInstance<ClientQueryObject>();
info.Client.BusinessLine =
AbstractFactory.GetInstance<BusinessLineQueryObject>
(dropDownListValue); // if dropDownListValue is "Any", returns an
instance of AnyBusinessLineQueryObject, else returns
BusinessLineQueryObject
info.Client.BusinessLine.Id = dropDownListValue;
ApplicationService.Search(info);
La question ici est de savoir comment faire pour s'abstenir de faire
appel au container IoC (via AbstractFactory, sachant que la méthode
GetInstance<T>(string value) se contente d'appeller Resolve<T>(string
name)) ? Je pense notamment au cas où on utiliserait les ModelBinder
d'un site en MVC, serait-il possible de laisser le ModelBinder faire
cet appel ?
Clément