2010-09-13 14 views
3

Je suis confronté à des problèmes d'architecture sur le projet auquel je participe. Le projet est une application ASP.NET MVC 2 qui repose sur DI et surtout sur l'injection de constructeurs avec Unity. L'application est divisée en plusieurs modules (chaque module est un ensemble d'assembies) qui expose des services à d'autres modules. Ces services sont enregistrés dans Unity au démarrage de l'application. Rien de spécial jusqu'à maintenant. Disons que j'ai ceci (chaque module est un assemblage pour la simplification):DI, Constructor Injection, Modules, modèles de conception

ModuleA, ModuleB.

ModuleA expose un service 'IServiceA' avec les méthodes suivantes:

IServiceA (Opération1 - Opération2 - Opération3)

Serviceb des besoins ModuleB IServiceA de ModuleA et il obtient par l'injection de constructeur (avec du béton la mise en oeuvre). Ensuite, il l'utilise. Le problème est lorsque ModuleA est désactivé (nous vérifions dans la base de données si le module est activé pour l'utilisateur courant au démarrage de l'application) donc le serviceA n'est pas enregistré avec Unity.

Ensuite, nous avons une exception au moment de l'exécution car l'unité ne peut pas trouver un enregistrement pour un IServiceA et ServiceB ne peut pas être construit. Ce qui est normal

Je voudrais savoir qu'il existe un ensemble de modèles ou la meilleure pratique pour y faire face. Mon premier était de se débarrasser de l'injection de constructeur pour ServiceB. Mais alors je devrais utiliser la référence au ServiceA et je ne l'aime pas ou utiliser un ServiceLocator qui est encore pire. Je ne veux pas vérifier dans ModuleB si ServiceA est disponible ou non, parce qu'il y aura beaucoup d'autres services que je vérifierais et devrait traiter avec un code qui est infrastructure pure. Je voudrais que ServiceB exécute le même code si le serviceA est disponible ou non (ne sait pas si possible). J'ai regardé un modèle de passerelle mais je ne sais pas si cela peut m'aider.

Toute aide sera appréciée.

Merci,

Répondre

3

Vous aurez besoin d'une sorte de implémentation par défaut qui peut prendre le relais lorsque ModuleA est désactivé. Le motif Null Object sonne comme un ajustement parfait.

Enregistrez simplement votre NullServiceA avec Unity en premier. Ce sera l'IServiceA par défaut, à moins qu'il ne soit écrasé par l'implémentation réelle (appelons-le ConcreteServiceA). Pour une implémentation plus sophistiquée, vous pouvez placer NullServiceA et ConcreteServiceA dans un Composite, ou peut-être un autre formulaire Decorator qui choisit l'un sur l'autre en fonction de la disponibilité. Vous pouvez, par exemple, avoir un composant composite qui utilise toujours la première (ou la dernière) des instances IServiceA qui y sont injectées ... ou peut-être que le critère de sélection peut être basé sur un type de métadonnées qui détermine si Le module est activé ou désactivé (il semblerait que cette information pourrait bien s'intégrer dans une interface IModule hypothétique).

+0

Merci pour votre réponse. Malheureusement, il n'y a pas d'implémentation par défaut. Dans le tout premier esprit de l'application, chaque module devrait «ajouter» de nouvelles fonctionnalités, mais d'autres modules devraient vivre sans, sinon disponibles. Maintenant tous les modules sont connectés et un module en appelle un autre tout le temps. Je pense à propos de l'implémentation d'un objet nul mais je ne sais pas si cela va très bien pour certaines raisons.Comment gérer le Dto que l'opération1, l'opération2 et l'opération3 retournent? Le Dto devrait être faux? Et si Operation4 retourne un booléen? Devrais-je y faire face comme le service réel a rendu cette valeur? –

+1

Chaque fois que vous définissez une interface, réfléchissez bien à ce à quoi ressemblera une implémentation Null Object. Si vous ne pouvez pas trouver une bonne implémentation hypothétique, c'est une odeur de design. Voyez si vous ne pouvez pas tirer le design plus vers le principe de Hollywood. Les méthodes renvoyant void peuvent toujours avoir une implémentation nulle. –

+0

Merci, quelque chose comme passer un contexte à la méthode et changer son implémentation à null? –