<commit_before>=======
Web API
=======

Web API 2 integration requires the `Autofac.WebApi2 NuGet package <https://www.nuget.org/packages/Autofac.WebApi2>`_.

Web API integration requires the `Autofac.WebApi NuGet package <https://www.nuget.org/packages/Autofac.WebApi/>`_.

Web API integration provides dependency injection integration for controllers, model binders, and action filters. It also adds :doc:`per-request lifetime support <../faq/per-request-scope>`.

**This page explains ASP.NET classic Web API integration.** If you are using ASP.NET Core, :doc:`see the ASP.NET Core integration page <aspnetcore>`.

.. contents::
  :local:

Quick Start
===========
To get Autofac integrated with Web API you need to reference the Web API integration NuGet package, register your controllers, and set the dependency resolver. You can optionally enable other features as well.

.. sourcecode:: csharp

    protected void Application_Start()
    {
      var builder = new ContainerBuilder();

      // Get your HttpConfiguration.
      var config = GlobalConfiguration.Configuration;

      // Register your Web API controllers.
      builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

      // OPTIONAL: Register the Autofac filter provider.
      builder.RegisterWebApiFilterProvider(config);

      // Set the dependency resolver to be Autofac.
      var container = builder.Build();
      config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
    }

The sections below go into further detail about what each of these features do and how to use them.

Get the HttpConfiguration
=========================

In Web API, setting up the application requires you to update properties and set values on an ``HttpConfiguration`` object. Depending on how you're hosting your application, where you get this configuration may be different. Through the documentation, we'll refer to "your ``HttpConfiguration``" and you'll need to make a choice of how to get it.

For standard IIS hosting, the ``HttpConfiguration`` is ``GlobalConfiguration.Configuration``.

.. sourcecode:: csharp

    var builder = new ContainerBuilder();
    var config = GlobalConfiguration.Configuration;
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    var container = builder.Build();
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

For self hosting, the ``HttpConfiguration`` is your ``HttpSelfHostConfiguration`` instance.

.. sourcecode:: csharp

    var builder = new ContainerBuilder();
    var config = new HttpSelfHostConfiguration("http://localhost:8080");
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    var container = builder.Build();
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

For OWIN integration, the ``HttpConfiguration`` is the one you create in your app startup class and pass to the Web API middleware.

.. sourcecode:: csharp

    var builder = new ContainerBuilder();
    var config = new HttpConfiguration();
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    var container = builder.Build();
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

Register Controllers
====================

At application startup, while building your Autofac container, you should register your Web API controllers and their dependencies. This typically happens in an OWIN startup class or in the ``Application_Start`` method in ``Global.asax``.

By default types that implement ``IHttpController`` and have a name with the suffix ``Controller`` will be registered.

.. sourcecode:: csharp

    var builder = new ContainerBuilder();

    // You can register controllers all at once using assembly scanning...
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

    // ...or you can register individual controlllers manually.
    builder.RegisterType<ValuesController>().InstancePerRequest();

If your controllers do not follow the standard naming convention you may choose to provide a custom suffix using an overload of the ``RegisterApiControllers`` method.

.. sourcecode:: csharp

    // You can also use assembly scanning to register controllers with a custom suffix.
    builder.RegisterApiControllers("MyCustomSuffix", Assembly.GetExecutingAssembly());

Set the Dependency Resolver
===========================

After building your container pass it into a new instance of the ``AutofacWebApiDependencyResolver`` class. Attach the new resolver to your ``HttpConfiguration.DependencyResolver`` to let Web API know that it should locate services using the ``AutofacWebApiDependencyResolver``. This is Autofac's implementation of the ``IDependencyResolver`` interface.

.. sourcecode:: csharp

    var container = builder.Build();
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

Provide Filters via Dependency Injection
========================================
Because attributes are created via the reflection API you don't get to call the constructor yourself. That leaves you with no other option except for property injection when working with attributes. The Autofac integration with Web API provides a mechanism that allows you to create classes that implement the filter interfaces (``IAutofacActionFilter``, ``IAutofacAuthorizationFilter`` and ``IAutofacExceptionFilter``) and wire them up to the desired controller or action method using the registration syntax on the container builder.

Register the Filter Provider
----------------------------

You need to register the Autofac filter provider implementation because it does the work of wiring up the filter based on the registration. This is done by calling the ``RegisterWebApiFilterProvider`` method on the container builder and providing an ``HttpConfiguration`` instance.

.. sourcecode:: csharp

    var builder = new ContainerBuilder();
    builder.RegisterWebApiFilterProvider(config);

Implement the Filter Interface
------------------------------

Instead of deriving from one of the existing Web API filter attributes your class implements the appropriate filter interface defined in the integration. The filter below is an action filter and  implements ``IAutofacActionFilter`` instead of ``System.Web.Http.Filters.IActionFilter``.

.. sourcecode:: csharp

    public class LoggingActionFilter : IAutofacActionFilter
    {
      readonly ILogger _logger;

      public LoggingActionFilter(ILogger logger)
      {
        _logger = logger;
      }

      public Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
      {
        _logger.Write(actionContext.ActionDescriptor.ActionName);
        return Task.FromResult(0);
      }

      public Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
      {
        _logger.Write(actionExecutedContext.ActionContext.ActionDescriptor.ActionName);
        return Task.FromResult(0);
      }
    }

Note in the sample there's no actual async code that runs so it returns ``Task.FromResult(0)``, which is a common way to return an "empty task." If your filter does require async code, you can return a real ``Task`` object or use ``async``/``await`` code just like any other asynchronous method.

Register the Filter
-------------------

For the filter to execute you need to register it with the container and inform it which controller, and optionally action, should be targeted. This is done using the ``AsActionFilterFor()``, ``AsAuthorizationFilterFor()`` and ``AsExceptionFilterFor()`` extension methods on the ``ContainerBuilder``.

These methods require a generic type parameter for the type of the controller, and an optional lambda expression that indicates a specific method on the controller the filter should be applied to. If you don’t provide the lambda expression the filter will be applied to all action methods on the controller in the same way that placing an attribute based filter at the controller level would.

In the example below the filter is being applied to the ``Get`` action method on the ``ValuesController``.

.. sourcecode:: csharp

    var builder = new ContainerBuilder();
     
    builder.Register(c => new LoggingActionFilter(c.Resolve<ILogger>()))
        .AsWebApiActionFilterFor<ValuesController>(c => c.Get(default(int)))
        .InstancePerRequest();

When applying the filter to an action method that requires a parameter use the ``default`` keyword with the data type of the parameter as a placeholder in your lambda expression. For example, the ``Get`` action method in the example above required an ``int`` parameter and used ``default(int)`` as a strongly-typed placeholder in the lambda expression.

It is also possible to provide a base controller type in the generic type parameter to have the filter applied to all derived controllers. In addition, you can also make your lambda expression for the action method target a method on a base controller type and have it applied to that method on all derived controllers.

Why We Use Non-Standard Filter Interfaces
-----------------------------------------

If you are wondering why special interfaces were introduced this should become more apparent if you take a look at the signature of the ``IActionFilter`` interface in Web API.

.. sourcecode:: csharp<commit_msg>Added docs about filter overrides.<commit_after>=======
Web API
=======

Web API 2 integration requires the `Autofac.WebApi2 NuGet package <https://www.nuget.org/packages/Autofac.WebApi2>`_.

Web API integration requires the `Autofac.WebApi NuGet package <https://www.nuget.org/packages/Autofac.WebApi/>`_.

Web API integration provides dependency injection integration for controllers, model binders, and action filters. It also adds :doc:`per-request lifetime support <../faq/per-request-scope>`.

**This page explains ASP.NET classic Web API integration.** If you are using ASP.NET Core, :doc:`see the ASP.NET Core integration page <aspnetcore>`.

.. contents::
  :local:

Quick Start
===========
To get Autofac integrated with Web API you need to reference the Web API integration NuGet package, register your controllers, and set the dependency resolver. You can optionally enable other features as well.

.. sourcecode:: csharp

    protected void Application_Start()
    {
      var builder = new ContainerBuilder();

      // Get your HttpConfiguration.
      var config = GlobalConfiguration.Configuration;

      // Register your Web API controllers.
      builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

      // OPTIONAL: Register the Autofac filter provider.
      builder.RegisterWebApiFilterProvider(config);

      // Set the dependency resolver to be Autofac.
      var container = builder.Build();
      config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
    }

The sections below go into further detail about what each of these features do and how to use them.

Get the HttpConfiguration
=========================

In Web API, setting up the application requires you to update properties and set values on an ``HttpConfiguration`` object. Depending on how you're hosting your application, where you get this configuration may be different. Through the documentation, we'll refer to "your ``HttpConfiguration``" and you'll need to make a choice of how to get it.

For standard IIS hosting, the ``HttpConfiguration`` is ``GlobalConfiguration.Configuration``.

.. sourcecode:: csharp

    var builder = new ContainerBuilder();
    var config = GlobalConfiguration.Configuration;
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    var container = builder.Build();
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

For self hosting, the ``HttpConfiguration`` is your ``HttpSelfHostConfiguration`` instance.

.. sourcecode:: csharp

    var builder = new ContainerBuilder();
    var config = new HttpSelfHostConfiguration("http://localhost:8080");
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    var container = builder.Build();
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

For OWIN integration, the ``HttpConfiguration`` is the one you create in your app startup class and pass to the Web API middleware.

.. sourcecode:: csharp

    var builder = new ContainerBuilder();
    var config = new HttpConfiguration();
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    var container = builder.Build();
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

Register Controllers
====================

At application startup, while building your Autofac container, you should register your Web API controllers and their dependencies. This typically happens in an OWIN startup class or in the ``Application_Start`` method in ``Global.asax``.

By default types that implement ``IHttpController`` and have a name with the suffix ``Controller`` will be registered.

.. sourcecode:: csharp

    var builder = new ContainerBuilder();

    // You can register controllers all at once using assembly scanning...
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

    // ...or you can register individual controlllers manually.
    builder.RegisterType<ValuesController>().InstancePerRequest();

If your controllers do not follow the standard naming convention you may choose to provide a custom suffix using an overload of the ``RegisterApiControllers`` method.

.. sourcecode:: csharp

    // You can also use assembly scanning to register controllers with a custom suffix.
    builder.RegisterApiControllers("MyCustomSuffix", Assembly.GetExecutingAssembly());

Set the Dependency Resolver
===========================

After building your container pass it into a new instance of the ``AutofacWebApiDependencyResolver`` class. Attach the new resolver to your ``HttpConfiguration.DependencyResolver`` to let Web API know that it should locate services using the ``AutofacWebApiDependencyResolver``. This is Autofac's implementation of the ``IDependencyResolver`` interface.

.. sourcecode:: csharp

    var container = builder.Build();
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

Provide Filters via Dependency Injection
========================================
Because attributes are created via the reflection API you don't get to call the constructor yourself. That leaves you with no other option except for property injection when working with attributes. The Autofac integration with Web API provides a mechanism that allows you to create classes that implement the filter interfaces (``IAutofacActionFilter``, ``IAutofacAuthorizationFilter`` and ``IAutofacExceptionFilter``) and wire them up to the desired controller or action method using the registration syntax on the container builder.

Register the Filter Provider
----------------------------

You need to register the Autofac filter provider implementation because it does the work of wiring up the filter based on the registration. This is done by calling the ``RegisterWebApiFilterProvider`` method on the container builder and providing an ``HttpConfiguration`` instance.

.. sourcecode:: csharp

    var builder = new ContainerBuilder();
    builder.RegisterWebApiFilterProvider(config);

Implement the Filter Interface
------------------------------

Instead of deriving from one of the existing Web API filter attributes your class implements the appropriate filter interface defined in the integration. The filter below is an action filter and  implements ``IAutofacActionFilter`` instead of ``System.Web.Http.Filters.IActionFilter``.

.. sourcecode:: csharp

    public class LoggingActionFilter : IAutofacActionFilter
    {
      readonly ILogger _logger;

      public LoggingActionFilter(ILogger logger)
      {
        _logger = logger;
      }

      public Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
      {
        _logger.Write(actionContext.ActionDescriptor.ActionName);
        return Task.FromResult(0);
      }

      public Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
      {
        _logger.Write(actionExecutedContext.ActionContext.ActionDescriptor.ActionName);
        return Task.FromResult(0);
      }
    }

Note in the sample there's no actual async code that runs so it returns ``Task.FromResult(0)``, which is a common way to return an "empty task." If your filter does require async code, you can return a real ``Task`` object or use ``async``/``await`` code just like any other asynchronous method.

Register the Filter
-------------------

For the filter to execute you need to register it with the container and inform it which controller, and optionally action, should be targeted. This is done using the following ``ContainerBuilder`` extension methods:

- ``AsWebApiActionFilterFor<TController>()``
- ``AsWebApiActionFilterOverrideFor<TController>()``
- ``AsWebApiAuthorizationFilterFor<TController>()``
- ``AsWebApiAuthorizationOverrideFilterFor<TController>()``
- ``AsWebApiAuthenticationFilterFor<TController>()``
- ``AsWebApiAuthenticationOverrideFilterFor<TController>()``
- ``AsWebApiExceptionFilterFor<TController>()``
- ``AsWebApiExceptionOverrideFilterFor<TController>()``

These methods require a generic type parameter for the type of the controller, and an optional lambda expression that indicates a specific method on the controller the filter should be applied to. If you don’t provide the lambda expression the filter will be applied to all action methods on the controller in the same way that placing an attribute based filter at the controller level would.

You can apply as many filters as you want. Registering a filter of one type does not remove or replace previously registered filters.

In the example below the filter is being applied to the ``Get`` action method on the ``ValuesController``.

.. sourcecode:: csharp

    var builder = new ContainerBuilder();
     
    builder.Register(c => new LoggingActionFilter(c.Resolve<ILogger>()))
        .AsWebApiActionFilterFor<ValuesController>(c => c.Get(default(int)))
        .InstancePerRequest();

When applying the filter to an action method that requires a parameter use the ``default`` keyword with the data type of the parameter as a placeholder in your lambda expression. For example, the ``Get`` action method in the example above required an ``int`` parameter and used ``default(int)`` as a strongly-typed placeholder in the lambda expression.

It is also possible to provide a base controller type in the generic type parameter to have the filter applied to all derived controllers. In addition, you can also make your lambda expression for the action method target a method on a base controller type and have it applied to that method on all derived controllers.

Filter Overrides
----------------
When registering filters, there are basic registration methods like ``AsWebApiActionFilterFor<TController>()`` and override registration methods like ``AsWebApiActionFilterOverrideFor<TController>()``. The point of the override methods is to provide a way to ensure certain filters execute first. You can have as many overrides as you want - these aren't *replacement* filters, just filters that run *first*.

Filters will run in the order:

- Controller-scoped overrides
- Action-scoped overrides
- Controller scoped filters
- Action scoped filters

Why We Use Non-Standard Filter Interfaces
-----------------------------------------

If you are wondering why special interfaces were introduced this should become more apparent if you take a look at the signature of the ``IActionFilter`` interface in Web API.

.. sourcecode:: csharp
{'fraction_non_alphanumeric': 0.09265207789600483, 'fraction_numerical': 0.001003814495081309, 'mean_word_length': 4.44547690625854, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 31, 'https://': 4, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1975928', 'n_tokens_mistral': 4616, 'n_tokens_neox': 4487, 'n_words': 2128}