Ross
Ross

Reputation: 2468

Self-hosting WebAPI application referencing controller from different assembly

I came across this gem, which seemed to be close to what I wanted. However, I want to use the already-written controllers from a referenced assembly.

My first crack was to reference the assembly, set up the routing rules the same as the original webAPI project and go, but I get 400s every time I try to call the self-hosted service. I've picked through the innards of the request with Fiddler, and aside from the address differences, the requests against the webAPI project and the self-hosted project are identical.

I feel like this ought to be relatively straightforward, but I haven't found an acceptable answer.

Upvotes: 12

Views: 6308

Answers (3)

cypressx
cypressx

Reputation: 139

This seems to be a known issue. You have to force the .NET to load the assemblies with the Controllers you need.

Before you Self Host the Web API, you should retrieve a type from the Reference Assembly which you want to be loaded by the runtime. Something like this:

Type controllerType = typeof(ReferencedControllers.ControllerType);

This should load the controllers from this assembly and it won't give you 404 error.

Upvotes: 8

Eric Boumendil
Eric Boumendil

Reputation: 2388

Previous posts of Praveen and Janushirsha lead me into the right direction I resume here :

// Not reliable in Release mode :
Type controllerType = typeof(ReferencedControllers.ControllerType);

So, you should replace IAssembliesResolver with :

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

Here is an example of implementation for CustomAssembliesResolver

using System.Web.Http.Dispatcher;
internal class CustomAssembliesResolver : DefaultAssembliesResolver
{
    public override ICollection<System.Reflection.Assembly> GetAssemblies()
    {
        var assemblies = base.GetAssemblies();

        // Interestingly, if we push the same assembly twice in the collection,
        // an InvalidOperationException suggests that there is different 
        // controllers of the same name (I think it's a bug of WebApi 2.1).
        var customControllersAssembly = typeof(AnotherReferencedAssembly.MyValuesController).Assembly;
        if (!assemblies.Contains(customControllersAssembly))
            assemblies.Add(customControllersAssembly);

        return assemblies;
    }
}

This code can easily be adapted if third party assemblies are not referenced or if you want late assembly binding.

Hope this help.

Upvotes: 10

Praveen
Praveen

Reputation: 304

this link saved my day for the same problem :)...

I just need to change below statement to suit for the selfhost webapi configuration.

GlobalConfiguration.Configuration.Services.Replace(typeof(IAssembliesResolver), new CustomAssemblyResolver());

with

var config = new HttpSelfHostConfiguration("http://localhost:8081");
        config.Services.Replace(typeof(IAssembliesResolver), new CustomAssemblyResolver());

Upvotes: 3

Related Questions