À l'aide de 2 versions différentes de la même dll?
J'ai reçu 2 pré-compilé dll:
Common.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f3b12eb6de839f43, processorArchitecture=MSIL
Common.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=f3b12eb6de839f43, processorArchitecture=MSIL
Exemple des différences dans l'API:
Et je suis en train de charger les deux en un seul projet de faire quelque chose comme ceci:
extern alias v10;
extern alias v20;
private static void UpgradeUser()
{
//Load old user
var userOld = new v10::Common.Data.UserData();
userOld.loadData("user.dat");
//Create new user
var userNew = new v20::Common.Data.UserData();
//Copy properties
userNew.FirstName = userOld._firstName;
userNew.LastName = userOld._lastName;
userNew.Age = userOld._age;
//Invoke method from v10 and v20 API
userOld.version();
userNew.DisplayVersion();
if (userNew.GetUserInfo() != userOld.getInfo())
{
throw new Exception("Discrepencies in upgrade ");
}
Console.WriteLine("Upgrade done!");
}
J'ai mis en place mon projet références et app.config
à la suivante. Je suis également copier la dll dans mon dossier de sortie, correspondant à la appconfig hrefs
<!-- [Edited: see history for previous version] -->
<Reference Include="Common.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f3b12eb6de839f43, processorArchitecture=MSIL">
<HintPath>libs\Common.Data.1_0_0_0.dll</HintPath>
<Aliases>v10</Aliases>
</Reference>
<Reference Include="Common.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=f3b12eb6de839f43, processorArchitecture=MSIL">
<HintPath>libs\Common.Data.2_0_0_0.dll</HintPath>
<Aliases>v20</Aliases>
</Reference>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Common.Data" publicKeyToken="f3b12eb6de839f43" culture="neutral" />
<codeBase version="1.0.0.0" href="libs\Common.Data.1_0_0_0.dll" />
<codeBase version="2.0.0.0" href="libs\Common.Data.2_0_0_0.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
J'ai obtenu dans la mesure où pour construire avec succès.
Mais quand j'essaie de le lancer, j'obtiens un MissingMethodException
pour UserData.loadData
.
J'ai été par le biais de multiples stackoverflow postes, msdn et codeproject articles, mais n'arrive pas à le faire fonctionner.
Lien 1,
Lien 2,
Lien 3,
Lien 4
Pense que je vais manquer une étape importante, mais ne peut pas comprendre ce qui, et pourrait utiliser un peu d'aide.
[Edit1]
J'ai essayé d'utiliser la dll séparément, et ils travaillent. (A enlevé le désordre. Voir l'historique des versions pour les captures d'écran)
[Edit2]
J'ai essayé de Mukesh Kumar proposition, et changé mon application.config:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Common.Data"
publicKeyToken="f3b12eb6de839f43"
culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0"
newVersion="2.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
Mais il ne fonctionne toujours pas. Je suis maintenant FileNotFoundException
.
[Edit3]
Ok, je suis presque certain que le <bindingRedirect>
n'est pas correct, et devrait être <codeBase>
à la place.
J'ai essayé de compiler à partir de la CLI:
csc Program.cs /reference:v10=libs/Common.Data.1_0_0_0.dll /reference:v20=libs/Common.Data.2_0_0_0.dll
Et il fonctionne très bien. J'ai été en mesure d'utiliser les deux Api en même temps:
Mais quand j'essaie de le construire à partir de Visual Studio, il se plaint de référence, même si je l'ai déjà précisé, l'alias de référence:
The extern alias 'v10' was not specified in a /reference option
J'ai essayé de modifier <Reference />
pour inclure/exclure <SpecificVersion>True</SpecificVersion>
avec aucun effet.
J'ai trouvé ce post, où la solution a été de supprimer et de rajouter les chemins. À l'aide de cette solution, Visual Studio génère bien, mais je suis de retour à System.MissingMethodException
.
Se sent comme je l'ai presque eu, mais pas tout à fait. Comment puis-je obtenir Visual Studio pour générer correctement?
[Edit4]
J'ai essayé de miguel méthode, mais toujours pas de travail.
Dans cette tentative, j'ai renommé les fichiers dll leur nom d'origine, et de les stocker dans des dossiers différents à la place.
J'ai ensuite mis à jour app.config pour faire un bindingRedirect ainsi que la base de code.
Lors de l'exécution, je m'y MissingMethodException
.
Je n'étais pas sûr de ce que 4- Find the and put in False
dire, donc j'ai essayé toutes les combinaisons de <Private>
, <SpecificVersion>
, ainsi que la mise en <Reference Include>
à la FQNs, mais aucune de ces combinaisons de travail.
En regardant mon 3ème édition, j'ai réussi à compiler et exécuter l'exemple réussi (avec mon renommé dll + app.config de la base de code hrefs) quand fait via la CLI.
Mon problème est maintenant, comment dois-je configurer mon csproj, de sorte qu'il crée le même.
Vous pouvez essayer de retirer le
<runtime>
section de votre config (vous ne devriez pas en avoir besoin) et en ajoutant les global
alias pour vos assemblées. Vous ne savez pas si cela fera une différence, mais je le fais tout le temps sans problèmes et j'ai toujours l'espace de noms global ajoutée, comme "global,v10"
.La raison, la méthode n'est pas trouvé, parce que c'est probablement d'essayer d'utiliser le mauvais assemblage. Pourquoi est -
loadData
et Common.Data.UserDa..
surlignée en rouge? c'est un resharper erreur de droit? que faut-il dire?oui, c'est un resharper erreur
Cannot resolve symbol 'loadData'
, bien que VS construit avec succès. Les dll ont été renommés, c'est pourquoi j'ai ajouté le runtime
élément appconfig. Sans elle, je vais avoir un FileNotFoundException - Could not load file or assembly 'Common.Data...
Étrange. Peut-être que vous pourriez essayer de l'importer le fichier DLL que vous appelez de main sous son nom normal dans le même dossier que l'exécutable, ou de la compilation de votre propre paire de Dll afin de vérifier si il n'y a pas un problème dans les bibliothèques.
OriginalL'auteur jayars | 2017-03-10
Vous devez vous connecter pour publier un commentaire.
Vous devez utiliser un dependentAssembly avec bindingRedirect mais aussi vous avez besoin de mettre les dll dans le dossier différent ou de l'enregistrer avec un nom différent. Avec ce fait, vous devez ajouter la ligne suivante dans votre application.config:
Avec ce code, le compiler et l'exécuter, mais parfois VS supprime ou remplace le code de l'application.config lors de la compile. Vous devez vérifier dans le fichier de configuration de la compilation d'un dossier. Si cela réussit, vous pouvez modifier la .csproj. Pour cela vous devez faire:
Cela fonctionne pour moi. Dans mon projet, je suis à l'aide de deux versions de Automapper.
Enfin, une autre solution est d'utiliser le
AppDomain.CurrentDomain.AssemblyResolve
l'événement de construction et de charger la dll spécifique.Pour cela, vous devez attraper l'événement:
MissingMethodException
. Je suis sûr que juste<codeBase />
est assez (Edit3). Je ne sais pas comment configurer mon csproj de sorte qu'il imite le scc CLI compilation.je vois dans votre application.config code que les versions de BindingRedirect pas correctement, vous devez définir un bindingRedirect comme <bindingRedirect oldVersion="0.0.0.0-1.0.0.0" nouvelleversion="1.0.0.0"/> <bindingRedirect oldVersion="1.0.0.1-2.0.0.0" nouvelleversion="2.0.0.0"/> et quand j'ai dit '4 - Trouver le et le mettre dans le Faux" je voulais dire définir la propriété < AutoGenerateBindingRedirects > False
merci pour le modifier. Il a été
<AutoGenerateBindingRedirect>false</<AutoGenerateBindingRedirect>
qui a fait le tour pour moi. Bien que les deux VS et Resharper se plaint, la compilation a réussi, et a couru comme prévu.pour le site web de la href devrait commencer par "bin\" par exemple <code version="1.0.0.0" href="bin\folder\namedll.dll" />
OriginalL'auteur miguel
Essayez de mettre votre config détails comme ci-dessous.
ici, vous pouvez vous offrir dll ancienne version et la nouvelle version. Vous pouvez simplement suivre ce l'article et aussi cette.
Espère que cela va vous aider.
FileNotFoundException
lors de l'utilisation de<bindingRedirect>
. Note dans mon post que la PublicKeyToken est identique, l'API a changé, et je suis en train d'utiliser à la fois de l'API dans le même temps, sans l'aide de la Réflexion (pour ne pas perdre l'intellisense et des contrôles de compilation). J'ai mis à jour ma question à inclure plus d'information.OriginalL'auteur Mukesh Kumar
Manque une réponse complète qui convient à mes besoins, j'ai décidé de donner ma solution avec le
AssemblyResolve
façon d'utiliser deux dll et la charge de l'pertinentes à partir d'un fichier, à l'aide de la réflexion pour résoudre le type . Pour cette démonstration, j'ai créé deux dll appeléMathFuncs
, en essayant d'invoquer leurAdd.add
fonction de résoudre en deux implémentations différentes.Pour voir les différents résultats de changer de version entier entre les valeurs 1 et 2 :Pour obtenir le nom complet de l'espace de noms pour le
Type.GetType
vous pouvez utiliser powershell :OriginalL'auteur Ohad Bitton