web-dev-qa-db-fra.com

Une interface doit-elle être définie dans la couche d'infrastructure s'il n'est utilisé que par une classe d'implémentation dans cette couche?

Aperçu

Si une demande est en cours de développement à la suite d'une approche d'architecture propre/DDD, ma compréhension est que le noyau d'application ou la couche de domaine doit contenir des classes et des interfaces qui modélisent directement la logique commerciale et représentent des concepts et des événements que l'utilisateur final de l'application comprend et a une participation dans.

Dans mon cas, j'essaie de mettre en œuvre un service, mais je souhaite que cette implémentation s'appuie sur d'autres services abstraits derrière une interface (pour faciliter la rapidité/testabilité). Le problème est que l'abstraction est seulement tangentiellement En ce qui concerne la logique commerciale, je ne sais donc pas si vous devez créer l'interface (et les événements associés qu'il publie) dans le Couche Domaine ou la couche d'infrastructure .

Fond

J'essaie de développer une application de base ASP.NET à l'aide d'une approche d'architecture propre, avec des projets distincts pour l'API, la logique de l'application et la logique de domaine et l'infrastructure.

Le gist de ce projet est de servir de backend pour un spa qui présente un "tableau de bord de commande" aux gestionnaires de vente, leur permettant de suivre l'avancement des commandes appartenant à différents consultants de produits au sein de la Direction de la société.

Dans ma couche de domaine, j'ai défini des événements, des entités et des services que je suis assez confiant appartient là, car ils sont directement impliqués dans la modélisation de la logique commerciale et représentent des choses que l'utilisateur final (les gestionnaires de vente) comprendrait et une participation dans:

Cependant, la façon dont je prévois de mettre en œuvre IBranchStateMonitor est de le faire souscrire aux flux d'événement de commande dans eventstore puis interrogeez la base de données pour cet ordre particulier (via un Core DBContext de EF). car il est publié (afin de déterminer si l'état de la commande a changé d'une manière pertinente pour cette demande).

Je souhaite découpler la logique pour interroger l'état actuel des commandes de la logique utilisée pour détecter lorsque les États des commandes ont peut-être changé. Par exemple, au lieu de vous inscrire à des flux d'événements dans un service basé sur le cloud, je préférerais une alternative plus simple qui implique simplement de demander à BranchStateMonitor pour réapprocher les états des commandes de la base de données à intervalles réguliers. Sur la base de cela, je voudrais une structure de classe comme celle-ci:

Voici la question suivante: Dois-je définir IOrderChangeNotifier et OrderChanged dans la couche de domaine ou dans la couche d'infrastructure ?

3
Tagc

Par souci de brièveté, je vais y référer comme "l'interface interne" (= uniquement référencée à l'intérieur de son propre montage). Je ne parle pas du modificateur d'accès internal ", bien que (SPOILER ALERTE!) Vous pouvez toujours finir par faire cette" interface interne "internal à la fin.

Cela dépend de qui décide que la mise en œuvre de l'interface enfant doit être utilisée?

Si votre bibliothèque en décide de lui-même, il n'y a aucune raison pour que cette interface enfant (ou ses implémentations) soit jamais exposée publiquement, car par définition Aucun externe Le consommateur sera autorisé à peser sur le processus de prise de décision.

Toutefois, si le consommateur (par exemple service Web) choisit la mise en œuvre de l'enfant, l'interface enfant (et ses implémentations) doit être connue publiquement pour que la décision soit prise.

En bref, l'inversion de contrôle vous oblige à évaluer Qui est censé avoir le contrôle. Cela vous indique si vous devriez exposer votre interface ou non.


Cela étant dit, il y a des architectures où cette distinction est discutée. J'ai travaillé dans plusieurs projets où les interfaces ont été placées dans un projet séparé de leurs implémentations - à quel point vous ne pouvez pas éviter de faire toutes les interfaces publiques.

Il s'agit d'une décision architecturale qui est faite à un niveau supérieur et est généralement définie dans la pierre par le développement de l'époque a progressé dans la mesure où votre question se pose.

0
Flater

À partir du look initial IOrderChangeNotifier et OrderChanged sont clairement une partie du domaine.

Si j'ai bien compris la responsabilité de votre demande correctement, elle présente les commandes et il est d'État aux gestionnaires de vente. Dans ce cas, le IOrderChangeNotifier et OrderChanged est définitivement une partie de votre domaine.

Vous pouvez implémenter IOrderChangeNotifier et OrderChanged dans la couche de domaine. La classe BranchStateMonitor aussi serait dans la couche de domaine, car cela contient la logique de surveillance de la branche qui est une activité principale. Maintenant, la classe BranchStateMonitor pourrait faire référence IOrderChangeNotifier.

Les implémentations de IOderChangeNotifier - EventStoreOrderSubscriber et PeriodicOrderChangeNotifier seront dans la couche d'infrastructure.

Maintenant, l'interface est définie dans la couche de domaine, elle est utilisée (référencée) dans la couche de domaine et est mise en œuvre par classe dans la couche d'infrastructure - tout cela semble parfait pour moi.

0