2

I have a console app that is using AppDomain.CurrentDomain.AssemblyResolve() to load unresolved assemblies. I'm wiring up the handler in a static constructor, and I'm logging every call to the handler.

My console app is starting up a self-hosted webservice, using Microsoft.Owin.Hosting.WebApp.Start().

If I run the app with the following DLLs in the same directory as the .exe, the webservice works correctly:

  • Microsoft.Owin.Diagnostics.dll
  • Microsoft.Owin.dll
  • Microsoft.Owin.Host.HttpListener.dll
  • Microsoft.Owin.Hosting.dll
  • Owin.dll
  • System.Net.Http.Formatting.dll
  • System.Web.Http.dll
  • System.Web.Http.Owin.dll
  • System.Web.Http.WebHost.dll

If I run the app with these DLLs not in the same directory as the .exe, the app starts, and I can see each of these DLLs triggering a call to my handler, and I can see my handler resolving the query, and returning the requested assembly, but the webservice doesn't work.

I get

Exception has been thrown by the target of an invocation. Inner Exception: Entry point was not found.

My guess is that the OWIN web service isn't resolving its loaded assemblies through the initializing app's AssemblyResolve process.

Does OWIN's WebApp() mechanism use a different mechanism for resolving assembly loads?

Or is there something else that might be going on?

If OWIN does have its own assembly resolving mechanism, where is it documented, and how can I hook into it?


I thought I had found an answer here: Self-hosting WebAPI application referencing controller from different assembly

But it's not working for me.

I'm starting my WebApp thus:

 Startup.simpleInjectorContainer = simpleInjectorContainer;

 var startOptions = new StartOptions();
 startOptions.Urls.Add($"http://localhost:{port}/");

 this.webApp = Microsoft.Owin.Hosting.WebApp.Start<Startup>(startOptions);

Where my Startup class:

 public class Startup
 {
      public static Container simpleInjectorContainer;

      public void Configuration(IAppBuilder app)
      {
           var config = new HttpConfiguration
           {
                DependencyResolver = new SimpleInjectorWebApiDependencyResolver(Startup.simpleInjectorContainer)
           };

           config.Services.Replace(typeof(IAssembliesResolver), new CustomAssembliesResolver());

           WebApiConfig.Register(config);
           app.UseWebApi(config);
      }
 }

 public class WebApiConfig
 {
      public static void Register(HttpConfiguration config)
      {
           config.MapHttpAttributeRoutes();

           config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
           );
      }
 }

And my new CustomAssembliesResolver:

public class CustomAssembliesResolver : DefaultAssembliesResolver
{
    public override ICollection<Assembly> GetAssemblies()
    {
        Console.WriteLine("::GetAssemblies()");
        var assemblies = base.GetAssemblies();

        var assembliesToLoad = new[]
        {
            "Microsoft.Owin.Diagnostics",
            "Microsoft.Owin",
            "Microsoft.Owin.Host.HttpListener",
            "System.Net.Http.Formatting",
            "System.Web.Http",
            "System.Web.Http.Owin",
            "System.Web.Http.WebHost",
        };

        foreach (var s in assembliesToLoad)
        {
            Console.WriteLine($"::Trying to load {s}");
            var a = Assembly.Load(s);
            if (a == null)
                Console.WriteLine($"::Could not load {s}");
            else
                Console.WriteLine($"::{s} : {a.FullName}");

            if (!assemblies.Contains(a))
                assemblies.Add(a);
        }

        return assemblies;
    }
}

I'm seeing no difference in behavior, after replacing IAssembliesResolver with a new CustomAssembliesResolver, and I'm not seeing GetAssmblies() being called.


More detail. When I'm walking through in the debugger, when I call

Microsoft.Owin.Hosting.WebApp.Start<Startup>(startOptions);

And when I hit a breakpoint in Startup.Configuration:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        config.Services.Replace(typeof(IAssembliesResolver), new CustomAssembliesResolver());

        ...
    }
}

the app parameter has already thrown a FileNotFoundException: "Cannot load assembly 'Microsoft.Owin'.".

It looks like I need to hook into the assembly resolve earlier.

Any ideas how?

Jeff Dege
  • 11,190
  • 22
  • 96
  • 165
  • IAssembliesResolver is used by webapi framework. But your program fails to initialize the owin host, so webapi is not yet in action and there is nothing to do with IAssembliesResolver to solve your issue. Your answer is maybe here: https://stackoverflow.com/a/30796396/249742 – Eric Boumendil Feb 08 '18 at 18:48
  • As I said, I already have an AssemblyResolve handler configured, and it's not being called. – Jeff Dege Feb 12 '18 at 15:57
  • I understood that you already set up an IAssembliesResolver, but your issue does not seem to be related to that interface. – Eric Boumendil Feb 13 '18 at 16:29

0 Answers0