Sergio Romero
Sergio Romero

Reputation: 6597

Error with Autofac integration with Web Api

We have an application divided in five projects which are the following:

The Web Api services contains references to all the class libraries as well as the Autofac and AutofacWebApiDependencyResolver.

I have already added the necessary code to register the container and resolver as it is explained in the Autofac documentation:

    var builder = new ContainerBuilder();
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

    var container = builder.Build();
    var resolver = new AutofacWebApiDependencyResolver(container);
    GlobalConfiguration.Configuration.DependencyResolver = resolver;

Currently I have a very basic dependency hierarchy to test this which is as follows:

//On the data contracts
public interface IData
{
   void SomeDataMethod();
}

//On the data layer
public class Data : IData
{
   public void SomeDataMethod(){}
}

//On the business contracts
public interface IBusiness
{
   void SomeBusinessMethod();
}

//On the business layer
public class Business : IBusiness
{
   private readonly IData _data;

   public Business(IData data)
   {
      _data = data;
   }
}

//On the Web Api project
[EnableCors("*", "*", "*")]
public class MyController : ApiController
{
   private IBusiness _business;

   public MyController(IBusiness business)
   {
      _business = business;
   }
}

So there's not rocket science at all here but when I run the project I get the following error:

 XMLHttpRequest cannot load http://localhost:61101/api/MyController. No
 'Access-Control-Allow-Origin' header is present on the requested
 resource. Origin 'http://localhost:56722' is therefore not allowed
 access.

If I remove the constructor from the controller the application works perfectly, the controller gets instantiated and its get method gets called.

What could I be doing wrong?

Upvotes: 2

Views: 1815

Answers (2)

Sergio Romero
Sergio Romero

Reputation: 6597

Well apparently the confusing error which would lead you to believe that indeed it is a problem with CORS not being enabled is caused by the fact that the code to register your controllers with the Autofac Web Api integration assembly is not enough, you also need to register all of the dependencies in all the other assemblies manually.

So the code in the Global.asax file ends up being something like this:

    var builder = new ContainerBuilder();
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

    var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
    var appAssemblies = assemblies.Where(a => a.ToString().StartsWith("MyCustomer.MyApplicationName") && !a.ToString().Contains("Services")).ToArray();
    builder.RegisterAssemblyTypes(appAssemblies).AsImplementedInterfaces();

    var container = builder.Build();
    var resolver = new AutofacWebApiDependencyResolver(container);
    GlobalConfiguration.Configuration.DependencyResolver = resolver;

This works because each of my assemblies are named following the convention:

CustomerName.ApplicationName.LayerName

So I want all the types of my application assemblies with the exception of the Services ones to be registered with Autofac.

Upvotes: 2

djikay
djikay

Reputation: 10628

Looks like a CORS issue. Could it be as simple as not having enabled CORS in your Web API WebApiConfig.Register() function? For example, you would add:

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

        // etc.
    }
}

to combine it with your controller's EnableCors attribute.

Alternatively, you could enable CORS globally (as opposed to just your controller) like this:

var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);

Note that it's generally good/safe practice to limit your CORS rules instead of using "*" everywhere.

Upvotes: 1

Related Questions