web-dev-qa-db-fra.com

Partage de classes ou d'interfaces entre différents projets

Je cherchais des réponses dans SO ou ici, mais sans aucun résultat, c'est pourquoi je vous demanderais.

Supposons que j'ai deux projets différents - par exemple, une partie serveur et une partie client d'une application. Je suis en train de développer ma propre partie, pendant que mon ami en fait la deuxième. Mais nous devons tous les deux utiliser des interfaces communes comme User ou AccountInfo ou ChangableAccount... quoi que ce soit afin d'assurer une compatibilité. Par exemple, si un client envoie des données utilisateur au serveur, le serveur doit fonctionner sur la même classe. La même chose avec les interfaces, etc. De plus, s'il y a des changements dans une interface commune, les deux projets devraient ajuster son code à la nouvelle situation.

La seule solution que je peux voir maintenant est de créer un projet supplémentaire dans lequel toutes les choses courantes sont définies. Nous, moi et mon ami, devons ajouter ce projet en tant que dépendance à un projet principal (client ou serveur). Le projet partagé peut être géré par un système de contrôle de version, nous avons donc toujours l'état le plus à jour.

Quelle autre solution proposeriez-vous? Comment ces problèmes sont-ils résolus dans les applications professionnelles?

17
guitar_freak

créer un projet supplémentaire dans lequel toutes les choses courantes sont définies

C'est exactement la première étape pour partager des pièces réutilisables - et c'est la partie facile. La partie la plus difficile consiste à décider si les deux projets qui utilisent la bibliothèque partagée doivent avoir des cycles de publication indépendants (ou non), et s'il devrait être possible que le "projet A" utilise la version 1.0 de votre bibliothèque partagée, tandis que le projet B utilise version 2.0 en même temps.

Si vous voulez que ce dernier soit possible, vous devez avoir un schéma de versioning strict et une gestion des versions pour votre bibliothèque (et des numéros de version dans le nom du fichier de la bibliothèque, comme suggéré par @RoryHunter). Vous devriez également faire attention à la compatibilité descendante de votre bibliothèque dans cette situation. Votre bibliothèque doit être gérée comme un produit distinct, en y ajoutant des tests unitaires pour vous assurer que les différentes versions en production seront une bonne idée, et un outil comme Maven peut aussi avoir du sens.

Si, cependant, vous voulez empêcher cette situation, vous devez gérer le "projet A", le "projet B" et votre bibliothèque comme un projet commun, avec un processus combiné de développement, de construction et de publication. Cela permettra de changer l'interface commune de la bibliothèque partagée beaucoup plus et souvent que dans le premier scénario. Et vous n'aurez pas besoin de quelque chose comme Maven ou des numéros de version dans le nom du fichier de bibliothèque. Mais le compromis est que A et B ne peuvent plus être développés indépendamment.

15
Doc Brown

Votre solution est la bonne. Placez le code partagé dans un autre projet qui crée son propre fichier JAR et utilisez-le dans les deux projets. Lors de la création du fichier JAR, vous souhaiterez peut-être inclure la version dans le nom, par exemple dans le style Debian;

libmyproject-shared-1.0.jar

Cela n'empêche pas les problèmes de version, mais cela devrait aider. Je n'ai jamais utilisé Maven, mais je comprends que cela peut aider dans cette situation.

13
Rory Hunter

créer un projet supplémentaire dans lequel toutes les choses courantes sont définies

C'est exactement la façon dont .Net attend de vous que vous le fassiez.

Résumez ces objets dans une troisième assemblée et référencez-les dans les deux projets. Je suggère de le faire en tant qu'interfaces, ce qui est plus propre, mais ...

Attention à la sérialisation:

  • La seule façon dont je pouvais sérialiser/désérialiser directement des objets entre les deux programmes (certes, c'était il y a pendant en utilisant Framework 2.0) était d'installer l'assembly "partagé" dans le Global Assembly Cache sur le client et le serveur Machines. Si l'Assemblée était "locale" pour chaque projet, le Cadre les considérait comme des types discrets et refusait de [dé] sérialiser l'un dans l'autre.
  • Et [dé] sérialiser des objets appelés Interfaces est un peu un "défi". Le type d'origine non-interface ne semblait pas "passer" par le "tuyau" de sérialisation, de sorte que le récepteur ne savait pas quel type concret "construire" à partir du flux entrant.
2
Phill W.

Comme d'autres l'ont suggéré, votre processus de réflexion est précis. Professionnellement, la plupart utiliseraient quelque chose comme Maven ou Gradle pour gérer ces dépendances efficacement.

1
BrandonV