zeroflaw
zeroflaw

Reputation: 564

How to use AutoFac in Web API to resolve a service at runtime?

I have an API (eg: ItemController.cs) which would obtain the Authorization Token from the Request Header at run time. With the Token, then only I pass into my Service Class (eg: ServiceItem.cs).

Here's how I did.

  1. At the Startup.cs, I register my ServiceItem

    var builder = new ContainerBuilder();
    builder.RegisterType<ServiceItem>();
    container = builder.Build(); //Note that, my container is a static variable
    
  2. In my API, I resolve it in this way:

    [Authorize]
    [Route("GetData")]
    [HttpGet]
    public IHttpActionResult GetData([FromUri] Filter filter)
    {
     using (var scope = Startup.container.BeginLifetimeScope())
     {
        var serviceItem = Startup.container.Resolve<ServiceItem>(
                new NamedParameter("token", Request.GetHeader("Authorization"))
            );
        return Ok(serviceItem.getItem(filter)); //filter is a param from webAPI
     }
    }
    

Question:

Is this how the Autofac normally work in web API? First, i am using a global static IContainer. Second, the codes look repetitive if i expose a few more functions.

I was thinking to resolve the ServiceItem in the constructor of the API. But the authorization token is not available yet.

Any suggestion is appreciated.

P.S.:

Here's my ServiceItem which, in the constructor, has a param 'token'

     public class ServiceItem
     {
          public string token;
          public ServiceItem(string token)
          {
              this.token = token;
          }

          public void doSomething()
          {
              //based on token, do processing
          }
      }

Upvotes: 1

Views: 2350

Answers (1)

mbnx
mbnx

Reputation: 942

It is a bad idea to refer to a static container within your startup class. That way, you introduce tight coupling between the controller and the startup. Your controller dependencies should be satisfied by constructor parameters. Take at http://docs.autofac.org/en/v4.0.0/integration/aspnetcore.html

The Startup.ConfigureServices method can optionally return a IServiceProvider instance, which allows you to plug-in Autofac into the ASP.NET Core Dependency Injection framework:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
  services.AddMvc();

  var builder = new ContainerBuilder();

  builder.RegisterType<MyType>().As<IMyType>();
  builder.Populate(services);
  this.ApplicationContainer = builder.Build();

  return new AutofacServiceProvider(this.ApplicationContainer);
}

After initializing your container, constructor parameters will be automatically resolved by Autofac:

public class MyController
{
    private readonly IMyType theType;
    public MyController(IMyType theType)
    {
        this.theType = theType; 
    }

    ....
}

Upvotes: 3

Related Questions