c# - Resolving controllers using Castle Windsor with dynamically loaded DLLs -


after loading web application, castle windsor cannot find controllers. controller path '' not found or not implement icontroller. when kernel (in customcontrollerfactory) see controllers correctly registered.

the main mvc application loads 3 other dll's. when directly reference dll's in visual studio , load plugin types working. when dynamically loading it, says fails. when request url context being passed getcontrollerinstance correct type parameter null.

i loading assembly using assembload.loadfrom.then retrieve types foreach module, subclass of plugin. results in 3 types have.

assembly assembly = assembly.loadfrom(module);  type plugintype = assembly.gettypes()                     .single(x => x.issubclassof(typeof(plugin))); 

then create instance of plugin, use register routes.

(iplugin)activator.createinstance(type)) 

registerroutes:

    public static void registerroutes(routecollection routes, ienumerable<iplugin> plugins)     {         routes.ignoreroute("{resource}.axd/{*pathinfo}");          var pluginroutedefaults = new {action = "index", id = urlparameter.optional};         foreach (var plugin in plugins)         {             var context = new arearegistrationcontext(plugin.area, routes);             context.maproute(plugin.area, $"{plugin.area}/{{controller}}/{{action}}/{{id}}", pluginroutedefaults, plugin.getcontrollernamespaces().toarray());         }          routes.maproute(               name: "default",               url: "{area}/{controller}/{action}/{id}",               defaults: new { area = "framework", controller = "home", action = "index", id = urlparameter.optional },               namespaces: new string[] { "web.framework.controllers" }               );     } 

customcontrollerfactory:

public class customcontrollerfactory : defaultcontrollerfactory {     private readonly ikernel _kernel;      public vlccontrollerfactory(ikernel kernel)     {         this._kernel = kernel;     }      public override void releasecontroller(icontroller controller)     {         _kernel.releasecomponent(controller);     }      protected override icontroller getcontrollerinstance(requestcontext context, type controllertype)     {         if (controllertype == null)         {             return base.getcontrollerinstance(context, controllertype);         }         try         {             return (icontroller)_kernel.resolve(controllertype);         }         catch         {             return base.getcontrollerinstance(context, controllertype);         }     } } 

registering controllers. after doing can see in modules window in visual studio dll's loaded. appdomain.currentdomain.getassemblies() says dll's loaded.

container.register(             classes.fromthisassembly().basedon<icontroller>().lifestyletransient()); 

mvcapplication class locate dll's.

public class mvcapplication : system.web.httpapplication {     protected void application_start()     {         var directories = directory.getdirectories("c:\projects\main\modules").where(x => !x.endswith("framework"));         string subpath = getsubpath();          list<type> plugintypes = getplugintypes(directories, subpath);         var plugins = getiplugins(plugintypes);         launcher.createwindsorcontainer(plugins.toarray());     }      private static list<iplugin> getiplugins(list<type> plugintypes)     {         list<iplugin> plugins = new list<iplugin>{new mvcinstaller()};          plugintypes.foreach(type => plugins.add((iplugin) activator.createinstance(type)));         return plugins;     }      private static list<type> getplugintypes(ienumerable<string> directories, string subpath)     {         list<type> plugintypes = new list<type>();          foreach (string directory in directories)         {             string module = directory.getfiles(directory + subpath).singleordefault(x => x.endswith("plugin.dll"));              if (!string.isnullorempty(module))             {                 assembly assembly = assembly.loadfrom(module);                 type plugintype = assembly.gettypes()                     .single(x => x.issubclassof(typeof(plugin)));                 plugintypes.add(plugintype);             }         }         return plugintypes;     }      private static string getsubpath()     {         #if debug         var subpath = @"\bin\debug\";         #else         subpath = @"\bin\release\";         #endif          return subpath;     } } 

when omit code , directly reference other dll's , following:

launcher.createwindsorcontainer(new plugina(), new pluginb(), new mvcplugin()); 

then works perfect, loading of dlls, resolving of controllers failing. why can castle windsor not find types when requesting controller?

the problem here not windsor resolution of controllers. defaultcontrollertype.getcontrollertype() method returning null, because didn't add assemblies buildmanager (with buildmanager.addreferencedassembly(assembly)). keep in mind can call before application start, need use [assembly:preapplicationstartupmethod(typeof(...sometype), "publicstaticvoidmethodonsometype").


Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -