web-dev-qa-db-fra.com

Puis-je utiliser une bibliothèque .NET 4.0 dans une application .NET 2.0?

Je rencontre des problèmes d’utilisation de mes bibliothèques .NET 4.0 dans des applications .NET 2.0. J'imaginais que j'avais l'impression qu'être une DLL Windows, mes autres applications .NET pourraient y accéder. Ce n'est pas le cas? Des recommandations en termes de prise en charge des applications dans les deux environnements?

EDIT: Je réalise que je devrais installer .NET 4.0 Framework sur le système cible. Y a-t-il d'autres raisons pour lesquelles cela ne fonctionne pas/ne devrait pas fonctionner?

EDIT: aurait probablement dû être plus spécifique. Nous avons une application actuelle, volumineuse/complexe, écrite en .NET 2.0 (ASP.NET soit exact). Nous avons créé un nouvel ensemble d'outils d'intégration et d'éléments de flux de travail dans .NET 4.0. Nous voulions ajouter une des bibliothèques créées 4.0 au projet .NET 2.0 (actuellement dans VS2008) et utiliser quelques-unes de ses méthodes. Lorsque nous faisons cela, nous rencontrons des problèmes, souvent des erreurs cryptiques liées à la mémoire.

Il semblerait qu'Earwicker et Brian Rasmussen aient raison à la fin. Comme je ne suis pas trop enclin à exposer des choses via COM (je ne sais pas si c'est techniquement ou non, mais peu importe), je pense que je vais m'en tenir à l'idée que les deux ne sont pas "compatibles" et rechercher d'autres moyens, ce que je pense nous avons basé sur nos besoins spécifiques. À plus long terme, nous chercherons à déplacer le code .NET 2.0 jusqu'à 4.0.

30
Douglas Anderson

Oui, c'est parfaitement possible. Vous venez d'exposer les composants écrits en 4.0 sous forme d'objets COM. L'application d'hébergement 2.0 les utilise simplement en tant qu'objets COM et n'a aucune idée s'ils sont natifs, 2.0, 4.0 ou autre. COM est l'interface commune que les deux versions d'exécution doivent implémenter de manière identique. 

La nouvelle prise en charge de SxS en cours de processus dans la version 4.0 signifie que, lorsque l'objet COM basé sur la version 4.0 est chargé, il extrait le runtime requis au lieu d'essayer de s'exécuter sur la version 2.0. Les deux runtimes sont donc présents dans le processus gérant leurs propres objets. Bien que vous ne puissiez pas directement passer d'objets CLR entre eux, vous pouvez passer des interfaces COM. Le CLR enveloppe vos objets dans des interfaces COM de manière transparente.

Je ne sais pas si vous pouvez créer un assemblage interop unique pour que les deux versions fonctionnent. Mais vous pouvez évidemment écrire un assembly interop en C # dans 2.0, l'exporter au format .tlb, puis l'importer dans un assembly en 4.0. Cela vous donne deux assemblages d'interopérabilité correspondants décrivant des interfaces COM identiques. (Ou construisez simplement la même source C # dans le projet d'assemblage de chaque version).

Mise à jour des bonus: L'application résultante sera-t-elle basée sur COM (quels que soient les problèmes que cela entraîne)?

Cela dépend comment vous le voyez. Les auteurs des composants en feront des composants COM. L’application hôte doit donc les localiser et les charger en tant que composants COM. Cela signifie bricoler avec le GAC, le registre ou les manifestes SxS, ce qui est beaucoup moins pur que de simplement dire aux auteurs de composants de déposer leur assemblage dans un certain répertoire afin que vous puissiez le charger avec la réflexion.

Et cela a un impact au moment de l'exécution: lorsque l'hôte a une référence à un composant, il n'y aura pas un mais des objets trois . L'hôte a une référence à un RCW, qui a un pointeur sur une interface COM implémentée par un CCW, qui à son tour contient une référence au composant réel. La CCW au milieu est un objet COM à comptage de références et le RCW de l'hôte dispose d'un finaliseur qui appelle Release dans la CCW et, lorsqu'il est détruit, libère la GCRoot qui maintient en vie le composant réel.

Cela signifie que, avec un agencement suffisamment complexe de pointeurs de rappel, etc., le système peut se retrouver confronté à des problèmes de comptage de références circulaires, lorsqu'un "îlot" d'objets déconnectés se référant tous les uns aux autres, ils ne sont donc jamais désalloués.

23
Daniel Earwicker

Veuillez noter que la version 4.0 est plus que de simples assemblys. L'exécution elle-même a également été modifiée dans cette version (nouveau mode GC simultané, nombreuses modifications apportées au pool de threads, mscorwks.dll s'appelle désormais clr.dll, etc.). 

10
Brian Rasmussen

Je viens de publier un post essentiellement ce que Daniel a suggéré.

Comment utiliser un DLL basé sur .NET 4 à partir d'une application basée sur .NET 2

Code source et description sur: http://code.msdn.Microsoft.com/Using-a-NET-4-Based-DLL-bb141db3

10
arik

Cela peut être possible selon l'utilisation que vous en faites. En .Net 4.0, vous avez la possibilité d'une exécution côte à côte en cours de processus (InProc SxS). Cela vous permet d'héberger deux versions différentes de CLR dans le même espace de processus. C'est expliqué ici

Je ne sais pas si vous pouvez en tirer parti dans votre situation. Je n'ai aucune expérience directe pour vous aider. 

Quelques scénarios dans lesquels cela peut être utilisé.

3
softveda

Il semble que la fonctionnalité côte à côte en cours de processus ajoutée à CLR 4 ne soit d'aucune utilité dans la mesure où il souhaite utiliser une bibliothèque .NET4.0 dans une application .NET2.0. Si je comprends bien, SxS en cours de traitement serait utile si le cas était le contraire (consommer un .NET2.0 dans une application .NEt4.0) car le CLR de la 4.0 fonctionnerait côte à côte avec la 2.0 dans le même processus ..

1
Derar

Votre assembly compilé pour .NET 4 contiendra des références à d'autres bibliothèques du framework .NET 4 qui ne sont pas présentes dans .NET 2.0. 

Si vous souhaitez que vos applications soient compatibles avec .NET 2.0, vous pouvez utiliser Visual Studio 2005 ou target vos projets vers .NET 2.0 si vous utilisez Visual Studio 2008 ou 2010. Bien sûr, si vous ciblez vos projets. NET 2.0, vous ne pourrez pas tirer parti des fonctionnalités de .NET 3.5/4.

0
Daniel Melo

J'ai eu un problème similaire avec mon application où je ne pouvais pas référencer une API qui utilisait des composants .net 4.0.
Pour résoudre ce problème, j'ai créé un nouveau projet de bibliothèque de classes référençant mon projet .net 4.0, puis appelé ce nouvel assembly à partir de mon projet .net 2.0. J'ai mappé les données provenant de .net. Projet 4.0 à utiliser par mon projet .net 2.0.
Cela a résolu mon problème. 

0
savvyBrar