2009-07-30 12 views
1

Je tente de créer une application Web ASP.Net qui stocke son "contenu" (ASPX/ASCX et assemblys) ailleurs que dans le fichier système (à l'intérieur d'un service, par exemple) et les charge dynamiquement selon les besoins.Classe de page de chargement dynamique/Assembly: Type ou nom introuvable dans l'espace de noms global

J'ai réussi à créer un VirtualPathProvider qui prend en charge la lecture des fichiers ASPX/Master/ASCX à partir d'autres emplacements, mais je rencontre des problèmes lorsque ces pages ASPX héritent d'une classe.

Merci aux réponses dans another question Je suis maintenant en mesure de charger les assemblages dans l'application au moment de l'exécution. Mais quand mon moteur d'exécution tente de compiler ma page je reçois l'erreur suivante:

"Compiler Error Message: CS0400: The type or namespace name 'Web' could not be found in the global namespace (are you missing an assembly reference?)"

[System.Runtime.CompilerServices.CompilerGlobalScopeAttribute()] public class default_aspx : global::Web.Code.CodeBehind, System.Web.SessionState.IRequiresSessionState, System.Web.IHttpHandler

Je bouillies sur mon code à un simple exemple de ce qui se passe mal pour qu'il soit facile pour vous de voir. You can download this code here.

L'assembly est chargé dynamiquement au moment de l'exécution à l'aide de l'événement AppDomain.AssemblyResolve. Ceci est dans le global.asax et ressemble à ceci:

protected void Application_Start(object sender, EventArgs e) 
{ 
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Assembly_Resolve); 
} 

Assembly Assembly_Resolve(object sender, ResolveEventArgs args) 
{ 
    Assembly assembly = AppDomain.CurrentDomain.Load(Resources.Web_Code); 
    if (args.Name == assembly.FullName) 
    { 
     return assembly; 
    } 
    return null; 
} 

Des idées?

EDIT Si pour une raison quelconque, vous devez mettre à jour l'ensemble de Web.Code - vous devrez le copier dans le dossier « ReferencedAssemblies » du projet Web pour que ces modifications prennent effet.

Répondre

0

OK. Pouvez-vous essayer ce qui suit - supprimer l'événement AssemblyResolve. Nous allons maintenant utiliser la configuration d'exécution web.config pour résoudre ces assemblys. Dans la configuration <runtime> ajouter ce qui suit:

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
    <probing privatePath="ReferencedAssemblies" /> 
</assemblyBinding> 

Je ne peux pas me expliquer pourquoi les deux approches - AppDomain.AssemblyResolve et cette exécution assemblyBinding donnent des résultats différents lorsqu'ils traitent avec PageBuildProvider. Je regardais autour de la classe PageBuildProvider pour trouver des indices sur ce qui se passe, mais toujours pas de chance. Je vais probablement approfondir ce sujet car il a attiré mon attention et sera publié ici si je trouve une solution. Faites-moi savoir si cette solution avec le fichier web.config travaille pour vous. Le seul inconvénient est que vous ne pouvez pas utiliser les ressources pour stocker vos assemblys. Vous devez les stocker sur le système de fichiers, tout dossier qui se trouve sous celui du projet - comme c'est actuellement le cas avec le dossier ReferencedAssemblies.

+0

Hey Ivan, j'étudie actuellement la possibilité d'utiliser cette technique - mais j'espère vraiment ne pas avoir à écrire dans un système de fichiers. Idéalement, ces assemblys ne résideront que dans la mémoire. Une bonne idée cependant. –

+0

C'est ce que je fais, tout fonctionne uniquement si l'assembly est chargé à partir du système de fichiers en utilisant la méthode Assembly.LoadFromFile (...). Il existe différents contextes de charge. http://msdn.microsoft.com/en-us/library/dd153782(v=vs.110).aspx –

1

J'ai rencontré le même problème lorsque vous essayez de charger des assemblys à partir de DB (et en utilisant l'événement AssemblyResolve). Mais cela semble fonctionner correctement si vous chargez des assemblys à partir du disque ou au moins enregistrez une copie du fichier .dll quelque part sur le disque.