2017-08-03 2 views
0

Je travaille sur un projet MVC dans lequel nous chargeons dynamiquement des DLL. Dans ces dll sont d'autres projets MVC (nous les appelons modules). Nous faisons cela pour que nous puissions supporter un plug-and-play pour les modules, les mettre à jour sans publier l'ensemble du projet.Impossible de définir @model en classe dans la DLL dynamique chargée

Nous avons plusieurs modules simples qui fonctionnent, maintenant je suis confronté à un problème avec un nouveau module que je développe.

Dans toute la vue du module, nous définissons le modèle comme @model dynamic. Mais parce que je veux utiliser @Html.TextBoxFor() thats pas permis sinon il en résulte

Un arbre d'expression ne peut pas contenir une opération dynamique

Je pensais, pas de problème, je vais juste changer pour @model ModuleNameSpace.ClassName Mais maintenant l'ensemble de la vue ne peut plus être chargé ... l'exception dit:

La vue trouvée à '~/PATH_TO_VIEW_FILE' n'a pas été créée.

Avec @model dynamic la vue fonctionne et lorsque je crée un projet séparé, il travaille aussi avec @model ModuleNameSpace.ClassName. Donc, il semble être un problème parce que nous ajoutons l'assemblage dynamique?

Les modules sont chargés comme ceci:

System.Reflection.AssemblyName name = System.Reflection.AssemblyName.GetAssemblyName(module.FullName); 
      System.Reflection.Assembly assembly = System.Reflection.Assembly.Load(name); 

Répondre

0

J'ai trouvé une solution à mon problème. Le problème était que le modèle ne trouvait pas la classe dans l'assemblage. Je ne sais pas exactement pourquoi mais j'ai trouvé un moyen de le résoudre.

Vous pouvez définir une fonction pour le cas où un assemblage est introuvable. Parce que je fais confiance à la source et qu'il s'agit d'une application interne, je peux établir une confiance totale dans la configuration web. Dans la méthode de résolution, je pointe vers la DLL où se trouve le module, puis la classe est trouvée et cela fonctionne!

Global.asax:

protected void Application_Start() 
    { 
      AppDomain currentDomain = AppDomain.CurrentDomain; 

      currentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 

} 

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
{ 
      var pluginsFolder = GetPluginFolder() 
     return (from f in pluginsFolder.GetFiles("*.dll", SearchOption.AllDirectories) 
        let assemblyName = AssemblyName.GetAssemblyName(f.FullName) 
        where assemblyName.FullName == args.Name || assemblyName.FullName.Split(',')[0] == args.Name 
        select Assembly.LoadFile(f.FullName)).FirstOrDefault(); 
} 

Merci à shawazza