6
votes

Chargement 2 versions de l'assemblage au moment de l'exécution

J'essaie de craquer celui-ci au cours des deux dernières semaines et je n'ai pas encore trouvé de bonne solution; J'espère que je peux avoir une réponse ici.

J'ai deux assemblages (ZA & ZB), qui pointez sur un projet / DLL commun (ZC), mais qui pourrait être sur une version différente (c'est-à-dire le même nom DLL, mêmes espaces de noms, certaines classes peuvent être différentes). Chaque assemblée fonctionne toutefois, si l'on est chargé par l'autre au moment de l'exécution (par exemple, une charge B), alors je ne peux pas le faire fonctionner. Besoin d'aide.

Voici la configuration:

  • ZA dépend de la version 1.1
  • ZB dépend de la version 1.0

    ZA doit charger des besoins pour charger quelque chose dans ZB (qui dépend de ZC), au moment de l'exécution.

    za est l'application principale. Sous son répertoire bin , il y a un répertoire de plug-ins plugins / plugin-zb sous lequel je voudrais placer tout de ZB et ses dépendances (ZC).

    Voici ce que j'ai essayé jusqu'à présent:

    assembly.load () en utilisant la même version de la DLL - a fonctionné bien.

    assembly.load () à l'aide de différentes versions de DLL - ZB Charges, mais lorsque la méthode fonctionne, je reçois une méthode non trouvée.

    appdomain.load () obtenu un fichier non trouvé d'erreur; J'ai même utilisé le délégué pour résoudre les assemblées.

    Quelques détails concernant ZC: - Certaines méthodes sont statiques publiques (certaines ne sont pas). Par exemple. log.log ("bonjour"); - Certains peuvent renvoyer des valeurs (primitives ou objets). - Certaines méthodes sont non statiques (et valeurs de retour).

    aide? - TIA


0 commentaires

3 Réponses :


1
votes

Outre Jonathan Allen Excellent conseil, un moyen plus "classique" de résoudre le problème consiste à charger les 2 versions de 2 appldomanis différentes. Vous pouvez ensuite utiliser .NET Remoting pour faire les deux communicats AppDomains. Donc, ZA devrait créer une nouvelle appdomaine, chargée dans cette Appdomain ZB et invoquer une certaine opération dans ZB via la télécommande.

Notez que .NET Remoting a quelques exigences sur les classes que vous souhaitez utiliser (héritage de MarshalbyRef) et créer une appdomaine est une opération coûteuse.

J'espère que cette aide


2 commentaires

"Vous ne pouvez avoir qu'une version d'une assemblée pour une appdomaine" n'est pas vraie. Il est même possible de faire référence à deux versions d'un assemblage à partir d'un seul assemblage, recherchez des alias externs pour plus d'informations, voici la première chose qui apparaît sur Google avec un exemple de la fonctionnalité: blogs.msdn.com/b/ansonh/archive/2006/09/28/...


L'utilisation de deux AppDomains est une solution au problème décrit cependant.



0
votes

J'ai eu deux versions de la même assemblée chargées en même temps. C'est arrivé avec un scénario tout comme vous le décrivez.

Vous devez convaincre l'exécution de charger la même version de ZC pour ZA et ZB. J'ai trouvé deux façons de faire ça:

  1. Utilisez un élément Bindingredirect dans votre fichier app.config. Il y a quelques détails dans Cette question .
  2. Utilisez l'événement appdomain.assemblblyResolve . Il existe des détails dans Cette réponse .

    Le seul problème avec appdomain.assemblyResolve est qu'il déclenche uniquement lorsque l'exécution ne peut pas trouver la version demandée. Si les deux versions sont disponibles, vous devrez utiliser le Bindingredirect . J'ai utilisé l'événement appdomain.assemblayresolve , puis a ajouté un chèque de sécurité qui veille à ce que la bonne version a été chargée en examinant la collection d'assemblages référencés de l'Assemblée. Si ce n'est pas le cas, je me plaint à l'utilisateur qu'une ancienne version de la bibliothèque se trouve et leur dit où elle est.


2 commentaires

Cela ne charge pas deux versions différentes, il charge la même version deux fois.


Lorsque j'ai eu ce problème, @cameron, la version de l'exécution chargée de la version 1.1 de ZC lorsque ZA a commencé. Ensuite, lorsque j'ai chargé le bouchon ZB, le temps d'exécution chargé version 1.0 de ZC avec elle. C'est ce que je veux dire en chargeant deux versions différentes. Pour faire passer des objets ZA et ZB de ZC les uns aux autres, je devais les faire charger la même version de ZC. C'est ce que je décris comment faire dans ma réponse. Ai-je mal compris la question initiale?



3
votes
    m_Assembly1 = Reflection.Assembly.LoadFile(IO.Path.Combine(System.Environment.CurrentDirectory, "Old Version\Some.dll"))
    m_Assembly2 = Reflection.Assembly.LoadFile(IO.Path.Combine(System.Environment.CurrentDirectory, "New Version\Some.dll"))

    Console.WriteLine("Old Version: " & m_Assembly1.GetName.Version.ToString)
    Console.WriteLine("New Version: " & m_Assembly2.GetName.Version.ToString)

    m_OldObject = m_Assembly1.CreateInstance("FullClassName")
    m_NewObject = m_Assembly2.CreateInstance("FullClassName")
From here on out I used late binding and/or reflection to run my tests..NET: Load two version of the same DLL

1 commentaires

Excellent conseil! Je ne savais pas que