Avantages de l'utilisation des fichiers .dll par rapport à la liaison de fichiers .cs à des projets (pour mes propres classes auxiliaires / méthodes d'extension génériques)

38

J'ai un projet d'assistance que j'utilise dans toutes les applications que je crée. Il contient des méthodes d'extension et un ensemble de classes d'assistance génériques, de contrôles, etc. Je met à jour / étend le projet d'assistance de temps à autre. Ce sont généralement des projets de petite taille et sans rapport entre eux, et je suis la seule à travailler sur chacun d'entre eux.

J'ai essayé deux approches pour l'utiliser

  • ajouter des fichiers .cs directement (Ajouter comme lien) à chaque projet où je les utilise
  • compilez-le en tant que .dll et ajoutez-le comme référence

Je vois quelques avantages et inconvénients de ces approches.
Le premier:

  • C’est plus simple, car les classes d’aide sont compilées dans le fichier exe. Par conséquent, je peux souvent très facilement fournir un seul fichier .exe qui fonctionnera parfaitement. Étant donné que j’ajoute un lien, je suis pratiquement sûr que, chaque fois que je construirai un projet utilisant l’aide, les fichiers d’aide seront la dernière version.
  • C’est encore plus simple, car je peux séparer les fichiers pour que mes méthodes d’extension qui fonctionnent bien sur .NET 4.0 puissent être référencées séparément de celles qui requièrent .NET 4.5, ce qui signifie que l’application dans son ensemble peut s’exécuter sur .NET 4.0.
  • Permet de déboguer via le code, avec tous les avantages des points d'arrêt etc etc ...
  • ne semble pas être la «meilleure pratique»

Le deuxième:

  • semble être la bonne approche, mais:
  • exige que je fournisse un fichier .dll séparé, ce qui pour une raison quelconque est beaucoup plus difficile pour les utilisateurs (ils ont tendance à partager mes programmes sans le fichier .dll, qui se bloque ensuite au démarrage)
  • lorsqu’il est compilé dans un seul fichier .dll, il aura besoin de la version la plus récente de .NET - beaucoup de mes utilisateurs n’ont pas .NET 4.5 et seuls certains éléments de ma classe d’aide en ont besoin, ce qui signifie que je peux forcer certaines personnes. mettre à jour leurs systèmes sans raison
  • Je dois également m'assurer que chaque fois que je mets à jour l'un de mes programmes, je fournis également le fichier .dll - même si je ne sais pas s'il a été modifié depuis la dernière version, ou non (cela aurait pu l'être, mais pourrait aussi bien être la même version). Je ne vois pas de moyen simple de déterminer cela sans garder de trace de la version de l’assemblage, ce qui représente un travail supplémentaire. Pour le moment, lorsque je mets à jour mes programmes, je ne livre que des exes mis à jour, et j'aime bien le garder petit et discret.

Alors, quel est l’avantage réel d’utiliser le fichier .dll ici? Veuillez noter que je suis la seule personne à éditer le code de toutes les applications et des fichiers auxiliaires.


En outre, pour clarifier les choses, les applications sont généralement très petites, alors que le code contenu dans les classes d’aide est totalement générique pour chacune d’elles (quelques simples comparaisons de chaînes, chemins ou opérations XML, etc.).


En fait, quelqu'un m'a fait comprendre tout à l'heure qu'il existe une troisième option. Comme j'ai le code d'assistance dans un projet séparé, je peux ajouter ce projet aux solutions de chacune de mes applications distinctes - ce qui fonctionne un peu comme "Ajouter en tant que lien" pour des fichiers uniques, sauf que je n'ajoute qu'un seul projet ... Mais comme l'a remarqué Doc Brown, cela signifie essentiellement que .dll devra de toute façon être ajouté au projet ...

Une autre chose qui favorise en quelque sorte l’utilisation des fichiers dll est la possibilité de déboguer activement à travers la classe helper ...

Bartosz
la source
3
Vous avez raison, et je le fais même, car cela aide en cas d'exigences .NET plus élevées ... Mais je n'aime pas le faire ... Un installateur pour une application de 40 Ko est un peu excessif :)
Bartosz
3
Eh bien, vous pouvez toujours utiliser quelque chose comme Costura , c’est un outil de fusion de DLL. Vous pouvez fusionner toutes les dépendances avec le fichier EXE, en conservant un seul fichier et en vous permettant d'utiliser les bibliothèques nécessaires. Cela peut être automatisé pour le processus de construction, pour plus de simplicité.
Kroltan
2
Lorsque vous ajoutez un projet à une solution, vous devez toujours déployer la DLL de ce projet, avec tous les inconvénients énumérés ci-dessus.
Doc Brown
2
@DocBrown - merde sainte, tu as raison :)
Bartosz
1
La liaison de fichiers .cs ou de projets peut présenter un autre inconvénient. Si vous utilisez ces fichiers partagés dans de nombreux projets et qu'un projet nécessite une modification radicale de vos bibliothèques partagées, vous devez maintenant restructurer vos autres projets. Le référencement des dll vous isole de cela s'il n'y a aucune raison pour que votre code exige la logique mise à jour. Je fais partie d'équipes de développement qui ont rencontré ce problème lorsque les projets partagés impliquent des éléments tels que l'authentification personnalisée. Le client veut essayer de modifier une nouvelle application et vous devez maintenant modifier la version de votre bibliothèque commune. Utiliser des dll fait cela.
Ellesedil

Réponses:

13

Vous avez déjà repéré la plupart des avantages et des inconvénients. L'utilisation de fichiers cs comme références est en effet plus légère et souvent plus facile à gérer. Toutefois, je recommande d’utiliser cette approche exclusivement lorsque vos csfichiers sont entièrement autonomes et ne nécessitent aucune configuration particulière.

Utiliser des DLL séparées

  • rendra explicites les dépendances à d’autres utilitaires ou bibliothèques (donc tant que vous n’avez pas de telles dépendances, cela fonctionnera bien)

  • vous permettra de définir des configurations de construction spécifiques (par exemple, si une classe ne fonctionne que dans une configuration x86 ou nécessite au moins .NET 4.0, la configuration de construction de l'assembly rend cette exigence explicite).

Donc, particulièrement si vous avez beaucoup de composants mono-classe et autonomes, utiliser des références à des fichiers est correct, mais si vous avez des composants référençant d'autres composants, ou des exigences de construction spécifiques, je vous recommanderais d'utiliser des DLL.

Pour atténuer les problèmes liés à la gestion de nombreuses DLL distinctes, vous pouvez créer un package d'installation ou utiliser ILMerge , qui peut incorporer un ensemble d'assemblys dans un seul exécutable. Dans notre environnement, nous traitons le problème différemment en utilisant un script de déploiement pour chaque application. Ce script garantit que toutes les DLL nécessaires sont toujours livrées à la production lorsqu'une nouvelle version de l'application est publiée.

Doc Brown
la source
Ok, merci beaucoup - alors, est-ce que je comprends bien que tant que mes classes d’aide ne font référence à aucune autre DLL externe (ne contenant que du code .NET standard), il n’est pas abominable de les lier simplement?
Bartosz
@ Bartosz: pas de DLL externe, et chaque classe d'assistance ne devrait idéalement pas utiliser une autre classe d'assistance, ou uniquement d'autres classes d'assistance stockées dans le même fichier. Pour être honnête, dans une certaine mesure, vous pouvez gérer la situation dans laquelle la classe d'assistance A a besoin de la classe d'assistance B stockée dans un fichier séparé, mais cette approche ne s'adapte pas correctement.
Doc Brown
1
@ PeterK. - Oui, et je l'ai fait :)
Bartosz
1
@whatsisname: pas que cela ne pourrait pas fonctionner. Cependant, pour moi cela ne ressemble pas à une solution qui simplifierait les choses, mais plutôt à une solution pouvant causer des problèmes inattendus ;-)
Doc Brown
1
@Ozkan: dans notre environnement, il s’agit simplement de déployer xcopy sur un partage réseau (avec quelques étapes supplémentaires pour sauvegarder l’ancienne version et s’assurer que personne n’utilise le programme actuellement - ce qui est obtenu en tentant de renommer le dossier de déploiement en premier). Il sait quelles dll à déployer car nous codifions la liste de la DLL requise dans le script, sans qu'il y ait de magie. Cette solution n’est pas parfaite, mais fonctionne pour nous dans la plupart des cas, à l’exception des programmes très utilisés par des dizaines d’utilisateurs.
Doc Brown le
11

Les DLL sont utiles lorsqu'une application est volumineuse et que certaines pièces nécessitent des mises à jour, mais pas l'application entière. Ainsi, si vous écrivez MS Word, il est pratique d’avoir le code de vérification orthographique dans une DLL pouvant être mis à jour sans devoir mettre à jour l’intégralité de MS Word. Si ce que vous écrivez est une petite application utilitaire (ou une série d'applications autonomes qui utilisent toutes le même code), le fait que le code soit incorporé ou non dans la ou les applications n'a pas beaucoup d'importance.

Dcguest
la source
2

Vous l'avez bien résumé dans votre question, je n'ai que quelques points à ajouter.

Mono Options est un excellent exemple de package NuGet qui utilise très bien la première approche.

Si vous décidez d'utiliser des dll, vous pouvez également utiliser des outils tels que Costura pour incorporer cette référence dans votre exécutable en tant que ressource intégrée. Pour l'utiliser, ajoutez simplement le Costura.Fodypaquet:

Install-Package Costura.Fody
Justin
la source
En fait, il y a encore une chose: avec le projet ou les fichiers incorporés ajoutés en tant que lien, vous pouvez également déboguer activement le code tout au long du fichier d'assistance ...
Bartosz
1
@ Bartosz Je pense que vous pouvez toujours déboguer "tout au long" sans le "fichier d'aide", tant que vous avez le bon fichier pdb.
Zack
J'ai essayé le truc Costura et je l'aime vraiment!
Bartosz
2

Qu'une dll soit plus bénéfique ou non dépend de plusieurs facteurs:

  1. La taille du code (une fois compilé).
  2. Combien d'exes l'utilisent.
  3. Combien de fois vous avez l'intention de mettre à jour le code.
  4. Si les exes sont destinés à être maintenus ensemble ou existent complètement séparément.

Le but d'une bibliothèque partagée est de prendre du code commun à plusieurs exécutables et de le centraliser de sorte que tous les exécutables partagent une copie. Cela vise à économiser de l'espace et à rendre le code plus facile à mettre à jour.

Si la quantité de code dans votre classe d'assistance est très petite, il ne vaut peut-être pas la déplacer dans une dll, car la surcharge du code contenu dans une dll peut neutraliser l'avantage d'économiser de l'espace en étant centralisée.

De plus, si vous ne créez que quelques exécutables, la taille du code dans chaque exécutable peut être suffisamment petite pour ne pas poser de problème. Cependant, plus le nombre de fichiers exécutables que vous utilisez avec le même code est avantageux, plus il serait avantageux de le déplacer dans une dll.

Comme exemple simplifié, supposons que votre classe d'assistance compile 128 octets dans un fichier exe, mais lorsqu'elle est déplacée vers une dll, la dll est de 512 octets. Si vous ne disposez que de 3 exécutables, vous gagneriez de l'espace en incluant le code dans les exécutables. Cependant, si vous aviez 5 exécutables, vous auriez alors intérêt à avoir une dll car l’espace combiné occupé par 5 copies du code (5 * 128 = 640 octets) est supérieur à l’espace occupé. en ayant le code dans une dll (512 octets).

Supposons maintenant que vous trouviez un bogue dans votre code d'assistance. Si vous avez compilé tous vos exécutables avec le code intégré, vous devez recompiler chaque exécutable, puis redistribuer les versions recompilées. Si vous compiliez le code dans une dll, il vous suffirait de recompiler et de redistribuer la dll unique, et le bogue serait automatiquement corrigé pour tous les exécutables l'utilisant.

Enfin, pour qu'un programme trouve une dll, il doit savoir où chercher la dll. Si vous conservez tous vos exécutables ensemble, vous pouvez simplement mettre la DLL dans le même répertoire et ils le trouveront tout de suite. Si vous les gardez intentionnellement séparés, il devient plus difficile de les coordonner pour utiliser la même DLL.

Pharap
la source
1

Votre troisième option est la plus appropriée (ajoutez-la à la solution en tant que projet "bibliothèque de classes" distinct). Ceci combine les avantages de toutes les approches:

  • Votre "projet d'assistance" est toujours à jour sur tous les projets.
  • Vous pouvez référencer le code du projet lorsque vous souhaitez voir rapidement les modifications.
  • Vous pouvez le construire pour la version .NET appropriée à chaque fois.
  • De toute façon, vous pouvez intégrer une DLL dans un fichier exe, alors ne vous inquiétez pas, vous pouvez l'avoir dans votre construction.

Nous faisons cela tout le temps et je ne peux rien faire d'autre que recommander cette approche.

Une quatrième solution que vous n'avez pas mentionnée consiste à le placer sur un référentiel privé NuGet, ce qui vous permettrait de le mettre à jour correctement et de le référencer sans projet supplémentaire dans chaque solution.

Benjamin Gruenbaum
la source
2
Hm, il me semble que lorsque je l'ajoute à la solution en tant que projet, puis que je le référence dans d'autres projets, il est toujours créé en tant que fichier .dll séparé plutôt que d'être intégré ... Faut-il spécifier quoi que ce soit?
Bartosz
1

En tant que développeur, j'aime toujours inclure la référence de la solution de l'utilitaire à mon application, car elle me permet de déboguer le code (et de détecter d'éventuels bogues dans Utility!). Toute modification apportée à l'utilitaire est automatiquement incluse dans l'application.

La décision dépend donc de la maturité de l’utilitaire ! Si vous avez des doutes sur les bogues de l’utilitaire, vous devez toujours inclure le fichier .cs de cet utilitaire pour connaître les bogues. Mais si vous êtes certain que cet utilitaire est suffisamment mature et qu’il ne renverra aucun résultat, il y n’est pas susceptible d’être amélioré dans l’utilitaire, vous pouvez continuer et inclure le fichier DLL.

saruchi arora
la source