Fournir un nom d'assembly explicite pour le dossier App_Code d'un site Web ASP.NET compilé dynamiquement ?

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

Question

Dans un projet de site Web ASP.NET compilé dynamiquement, l’assembly du dossier App_Code peut-il être explicitement nommé ?

Par exemple, dans des circonstances normales, lorsque j'exécute un site Web ASP.NET, le nom de l'assembly généré dans le fichier Temporary ASP.NET Files\ le dossier est partiellement aléatoire comme App_Code.neizakfo.dllneizakfo est la partie qui peut différer.Puis-je fournir explicitement un nom pour l'assembly comme App_Code_Web1.dll?

Clarification

Pour des raisons commerciales, le site Web ne peut pas être précompilé/déployé.C'est pourquoi je cherche une solution dans le contexte du Temporary ASP.NET Files dossier et les assemblys compilés dynamiquement comme indiqué ci-dessus.


Arrière-plan:
Je suis tombé sur cette question en cherchant un moyen d'effectuer une instanciation de type dynamique sur une classe dans le dossier App_Code d'un site Web en utilisant un nom qualifié d'assembly stocké dans la configuration, mais instancié à partir de la page Web, traversant ainsi une limite d'assembly.Étant donné que la page Web et le code app_code sont compilés par défaut dans deux assemblys différents, le comportement par défaut de la méthode Type.GetType(..) consistant à rechercher le nom du type dans l'assembly en cours d'exécution (la page Web) ou dans mscorlib ne le fait pas. suffisant pour choisir n’importe quel type dans l’assembly App_Code.Étant randomisé, le nom de l'assembly app_code ne m'est pas connu pour être inclus dans la chaîne qualifiée d'assembly.

Je peux mettre le type de données dans une bibliothèque de classes (car elle a un nom prédéfini/exact) pour me débarrasser de ce problème, mais j'aimerais savoir comment faire cela dans le site Web lui-même sans créer de projet de bibliothèque de classes pour le but.

Était-ce utile?

La solution

Vous pouvez en quelque sorte le faire dans un projet WebSite.

Il y a un Article MSDN sur l'utilisation de l'indicateur -fixednames lors de la compilation du projet.

Cela crée effectivement un assembly pour chaque page - default.aspx.dll.Cependant, cela ne vous est que légèrement plus utile, car vous devez toujours connaître le nom du contrôle ou de la page que vous recherchez lors du chargement. Vous devez donc vous assurer que vos types et votre nom sont cohérents.Il doit cependant respecter le nom des classes dans app_code afin que cela puisse fonctionner pour vous.

Une autre chose que vous pouvez faire est de déplacer tout le code de app_code dans son propre assembly, puis de l'ajouter comme référence de projet.Cela simplifierait également ce problème.

Enfin, vous pouvez énumérer toutes les DLL dans le répertoire bin et rechercher dans chacune d'elles le type que vous recherchez.Comme cela coûte assez cher, faites-le une fois et mettez le résultat en cache quelque part afin de ne pas continuer à le faire à chaque fois que vous recherchez ce type.C'est probablement la pire solution.

C'est trivial à faire dans un projet WebApplication, mais je suppose que vous êtes coincé avec celui de WebSite ?

MODIFIER: En guise de mise à jour pour les commentaires ;si j'utilise l'outil Web de publication, alors tout le code de app_code va dans le répertoire bin dans une DLL appelée App_Code.dll - ce comportement ne change pas même si j'utilise une dénomination fixe (toute dénomination fixe affecte la dénomination des DLL pour chaque page, contrôle utilisateur).Si j'utilise ILSpy sur ce fichier, je peux y voir mes cours.Je connais donc le nom de l’assembly et son emplacement – ​​je devrais pouvoir accéder aux types qu’il contient avec un minimum d’effort.Je me demande pourquoi je vois un comportement différent du vôtre !

J'ai créé une classe simple appelée "Personne" avec un identifiant et un nom, je l'ai mise dans App_Code, j'ai compilé le site, puis j'ai exécuté le code suivant :

  Type myType = Assembly.LoadFrom(Server.MapPath("~/bin/App_Code.dll")).GetType("Person", true);
  Response.Write(myType.ToString());

Il a écrit "Personne", comme prévu.

Modifier davantage

Le centime tombe !Si je fais alors :

  object myObject= Activator.CreateInstance("App_Code.dll", "Person");

Et essayez de lancer myObject sur personne, j'obtiens le message suivant :

The type 'Person' exists in both 'App_Code.dll' and 'App_Code.jydjsaaa.dll'

Il est donc temps d'être sournois.

dans Global.asax, sur Application_OnStart, procédez comme suit :

Application["App_Code_Assembly"] = Assembly.GetAssembly(typeof(Person));

Dans ma page de test par défaut, j'ai ensuite fait :

  Assembly app_Code = Application["App_Code_Assembly"] as Assembly;
  Response.Write(app_Code.FullName);

Ce qui m'a donné le code app_code nommé au hasard avec lequel il s'exécute réellement dans les fichiers ASP.Net temporaires.

C'est pourquoi je déteste les projets de sites Web ;-)

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