Comment charger un assembly et toutes ses dépendances au moment de l’exécution en C# pour Reflection ?

StackOverflow https://stackoverflow.com/questions/59220

  •  09-06-2019
  •  | 
  •  

Question

J'écris un utilitaire pour moi-même, en partie comme exercice d'apprentissage de la réflexion C# et en partie parce que je veux réellement l'outil résultant pour mon propre usage.

Ce que je recherche, c'est essentiellement de pointer l'application vers un assembly et de choisir une classe donnée à partir de laquelle sélectionner les propriétés qui doivent être incluses dans un formulaire HTML exporté en tant que champs.Ce formulaire sera ensuite utilisé dans mon application ASP.NET MVC comme début d'une vue.

Comme j'utilise des objets Subsonic pour les applications que je souhaite utiliser, cela devrait être raisonnable et j'ai pensé qu'en voulant inclure des éléments tels que du code HTML de sortie différent en fonction du type de données, Reflection était le moyen d'y parvenir.

Ce que je recherche, cependant, semble insaisissable.J'essaie de prendre la DLL/EXE choisie via OpenFileDialog comme point de départ et de la charger :

String FilePath = Path.GetDirectoryName(FileName);
System.Reflection.Assembly o = System.Reflection.Assembly.LoadFile(FileName);

Cela fonctionne bien, mais comme les objets générés par Subsonic sont en réalité remplis de types d'objets définis dans Subsonic.dll, etc., ces objets dépendants ne sont pas chargés.Entrer:

AssemblyName[] ReferencedAssemblies = o.GetReferencedAssemblies();

Cela aussi contient exactement ce à quoi je m’attendrais.Cependant, ce que j'essaie de comprendre, c'est comment charger ces assemblys afin que mes fouilles dans mes objets fonctionnent correctement.Je comprends que si ces assemblys se trouvaient dans le GAC ou dans le répertoire de l'exécutable en cours d'exécution, je pourrais simplement les charger par leur nom, mais ce n'est probablement pas le cas pour ce cas d'utilisation et c'est mon cas d'utilisation principal.

Donc, cela se résume à comment charger un assembly donné et tous ses assemblys arbitraires en commençant par un nom de fichier et en aboutissant à une arborescence de types, de propriétés, de méthodes, etc. entièrement consultable par réflexion.

Je sais que des outils comme Reflector font cela, je n'arrive tout simplement pas à trouver la syntaxe pour y accéder.

Était-ce utile?

La solution

Quelques options ici :

  1. Attacher à AppDomain.AssemblyResolve et fais-en un autre LoadFile en fonction de l'assemblage demandé.
  2. Faites tourner un autre AppDomain avec le répertoire comme base et chargez les assemblys dans ce AppDomain.

Je recommande fortement de poursuivre l'option 2, car elle sera probablement plus propre et vous permettra de décharger tous ces assemblages par la suite.Pensez également à charger les assemblys dans le contexte de réflexion uniquement si vous avez uniquement besoin d'y réfléchir (voir Assembly.ReflectionOnlyLoad).

Autres conseils

Je travaillais sur Kent BoogaartC'est la deuxième option.En gros, je devais :

1.) Mettre en œuvre le ResolveEventHandler dans une classe distincte, héritant de MarshalByRefObject et en ajoutant le Serializable attribut.

2.) Ajoutez le courant ApplicationBase, essentiellement là où se trouve la DLL du gestionnaire d'événements, au AppDomain PrivateBinPath.

Vous pouvez trouver le code sur github.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top