asp.netapplicationhost

Using ApplicationHost.CreateApplicationHost() to create an Asp.Net post, while loading assemblies from another location


I'm trying to use CreateApplicationHost to create an Asp.Net application host for a simple web server, however I'm getting a System.IO.FileNotFoundException when it attempts to create an instance of my marshalling object:

host = (MyMarshaller)ApplicationHost.CreateApplicationHost((MyMarshaller), virtualDir, physicalDir);

I believe that this error is because it cannot find the assembly containing the class MyMarshaller - if I put this assembly in the bin directory of physicalDir then everything works fine, however I don't want to do this (I also don't want to place my assembly in the GAC either).

Is there any way that I can control where CreateApplicationHost looks for my assembly? (Note that MyMarshaller class is conted in the same assembly as the above line of code)


Solution

  • The short answer is that it isn't possible to do this, however the Cassini source revealed an alternative solution.


    Update

    The above link no longer works, however the CassiniDev project on CodePlex appears to be pretty close (possibly a derivative work) and contains the same solution.

    The solution is to avoid using CreateApplicationHost and "do it yourself" instead - in this case use reflection to create an instance of the internal "BuildManagerHost" type and call "RegisterAssembly", like so

    /// <remarks>
    /// This is Dmitry's hack to enable running outside of GAC.
    /// There are some errors being thrown when running in proc
    /// </remarks>
    private object CreateWorkerAppDomainWithHost(string virtualPath, string physicalPath, Type hostType,int port)
    {
        // create BuildManagerHost in the worker app domain
        //ApplicationManager appManager = ApplicationManager.GetApplicationManager();
        Type buildManagerHostType = typeof(HttpRuntime).Assembly.GetType("System.Web.Compilation.BuildManagerHost");
        IRegisteredObject buildManagerHost = ApplicationManager.CreateObject(_appId, buildManagerHostType, virtualPath,
                                                                      physicalPath, false);
        
        // call BuildManagerHost.RegisterAssembly to make Host type loadable in the worker app domain
        buildManagerHostType.InvokeMember("RegisterAssembly",
                                          BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.NonPublic,
                                          null,
                                          buildManagerHost,
                                          new object[] { hostType.Assembly.FullName, hostType.Assembly.Location });
        
        // create Host in the worker app domain
        // FIXME: getting FileLoadException Could not load file or assembly 'WebDev.WebServer20, Version=4.0.1.6, Culture=neutral, PublicKeyToken=f7f6e0b4240c7c27' or one of its dependencies. Failed to grant permission to execute. (Exception from HRESULT: 0x80131418)
        // when running dnoa 3.4 samples - webdev is registering trust somewhere that we are not
        return ApplicationManager.CreateObject(_appId, hostType, virtualPath, physicalPath, false);
    }