2010-03-04 5 views
30

Je rencontre des problèmes avec mes bibliothèques .NET 4.0 dans les applications .NET 2.0. Je suppose que j'étais sous l'impression qu'étant une DLL Windows, mes autres applications .NET seraient en mesure d'y accéder. Ce n'est pas le cas? Des recommandations en termes de support des applications dans les deux environnements?Puis-je utiliser une bibliothèque .NET 4.0 dans une application .NET 2.0?

EDIT: Je me rends compte que j'aurais besoin d'installer .NET 4.0 Framework sur le système cible, y a-t-il d'autres raisons pour lesquelles cela ne fonctionnera pas/ne devrait pas fonctionner?

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

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

+0

Essayez-vous d'utiliser un assembly .NET 4.0 sous * ASP.NET * 2.0? Les numéros de version ici peuvent être déroutants. –

+0

laissez-moi poser une question stupide pourquoi compiler pour net 2.0 quand vous avez net 4.0? o.O juste faire un effort et réécrire les parties qui donnent des avertissements/erreurs – Aviatrix

Répondre

23

Oui, c'est parfaitement possible. Vous venez d'exposer les composants écrits en 4.0 en tant qu'objets COM. L'application d'hébergement 2.0 les utilise simplement comme des 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 SxS in-process dans 4.0 signifie que lorsque l'objet COM 4.0 est chargé, il extrait le runtime requis au lieu d'essayer de s'exécuter sur le 2.0, de sorte que les deux runtimes sont présents dans le processus de gestion de leur propres objets. Bien que vous ne puissiez pas passer directement d'objets CLR entre eux, vous pouvez passer des interfaces COM, et le CLR enveloppe de manière transparente vos objets dans les interfaces COM pour vous.

Je ne sais pas si vous pouvez créer un seul ensemble d'interopérabilité pour les deux versions. Mais il est clair que vous pouvez écrire un assembly interop en C# dans 2.0, l'exporter en .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 créez simplement la même source C# dans le projet d'assemblage de chaque version).

Mise à jour du bonus: L'application résultante sera-t-elle basée sur COM (avec les problèmes que cela implique)?

Cela dépend de la façon dont vous le regardez. Les auteurs de composants les feront en tant que composants COM. L'application hôte doit donc les localiser et les charger en tant que composants COM. Cela signifie se tromper avec le GAC, le registre ou les manifestes SxS, ce qui est beaucoup moins propre que de simplement dire aux auteurs de composants de laisser tomber leur assembly dans un certain répertoire afin de pouvoir le charger par réflexion.

Et il 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 seul mais trois objets impliqués. L'hôte a une référence à un RCW, qui a un pointeur vers une interface COM implémentée par un CCW, qui à son tour contient une référence au composant réel. Le CCW au milieu est un objet COM compté par référence, et le RCW de l'hôte a un finaliseur qui appelle Release sur le CCW, et quand il est détruit il libère le GCRoot qui maintient vivant le composant réel. Cela signifie que - avec un agencement suffisamment complexe de pointeurs de rappel, etc. - le système peut se retrouver avec des problèmes de comptage de référence circulaire, où un "îlot" d'objets déconnectés sont tous liés les uns aux autres et donc jamais obtenir désaffecté.

+0

C'était exactement ma pensée.Je ne le recommanderai pas, car ce n'est pas aussi intuitif que la méthode .NET "normale". Vous aurez toujours besoin de .NET 4 sur votre machine, car la bibliothèque que vous référencez l'utilise toujours. –

+1

Lorsque vous dites que vous ne le recommanderiez pas, que recommanderiez-vous à quelqu'un qui veut prendre en charge les plug-ins .NET 4.0 pour une application de plate-forme de base .NET 2.0? Ou vice versa? C'est exactement ce que cette fonctionnalité de 4.0 a été développée pour supporter. Il n'y a pas d'autre moyen "normal" de le faire - cela n'a jamais été possible auparavant. –

+1

On devrait envisager de migrer la partie 2.0 vers .net 4.0, si .net 4.0 est nécessaire de toute façon. De cette façon, vous n'avez pas les empreintes des deux frameworks et vous pouvez également utiliser les nouvelles fonctionnalités dans votre propre base de code. –

10

Veuillez noter que la version 4.0 est plus que de simples assemblages supplémentaires. Le runtime lui-même a également été modifié dans cette version (nouveau mode GC concurrent, beaucoup de changements dans le pool de threads, mscorwks.dll est maintenant appelé clr.dll, etc.).

+0

Donc je ne peux pas compiler ma bibliothèque .NET 4.0 d'une manière qui va s'exposer comme une DLL Windows traditionnelle? Le Framework .NET 4.0 est installé sur le poste de travail cible, ce n'est pas suffisant? –

+0

@Douglas Anderson - oui, vous pouvez. –

+1

@Douglas Anderson: Comme Earwicker le signale, 4.0 supporte le chargement côte à côte de plusieurs runtimes (il existe un article récent sur le sujet dans le magazine MSDN). Cependant, ce n'était pas pour moi ce que vous essayiez de faire, donc je voulais juste faire remarquer que, contrairement aux versions précédentes, le runtime a été mis à jour aussi bien pour cette version. –

0

Votre assembly compilé pour .NET 4 contiendra des références à d'autres bibliothèques de 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 serez pas en mesure de tirer parti des fonctionnalités .NET 3.5/4.

3

Cela peut être possible selon la façon dont vous l'utilisez. Dans .Net 4.0, vous avez l'option d'exécution côte à côte en cours d'exécution (InProc SxS). Cela vous permet d'héberger deux versions différentes de CLR dans le même espace de traitement. C'est explained here.

Si vous pouvez profiter de cela dans votre établissement, je ne sais pas. Je n'ai aucune expérience directe pour vous aider.

Certains scenarios dans lesquels cela peut être utilisé.

1

On dirait que la fonctionnalité côte à côte en cours de traitement qui a été ajoutée à CLR 4 n'aidera pas dans ce cas, car il veut utiliser une bibliothèque .NET4.0 dans une application .NET2.0. Pour autant que je comprenne, SxS in-process serait utile si le cas était le contraire (consommer un .NET2.0 dans une application .NEt4.0) comme le CLR du 4.0 fonctionnera côte à côte avec 2.0 dans le même processus ..

0

J'ai eu un problème similaire avec ma demande où je ne pouvais pas faire référence à une API, qui utilisait .net 4.0 composants.
Pour résoudre ce problème, j'ai créé un nouveau projet de bibliothèque de classes faisant référence à mon projet .net 4.0, puis j'ai appelé ce nouvel assembly à partir de mon projet .net 2.0. J'ai cartographié les données provenant du projet .net 4.0 à utiliser par mon projet .net 2.0.
Cela a résolu mon problème.

Questions connexes