-
Notifications
You must be signed in to change notification settings - Fork 0
_AspNet_WebApi_DependencyInjectionwithAutofac
See ASP.NET migration path for further details.
Exposing performance measurement into ASP.NET Web API via Autofac is just a bit different than with Castle Windsor.
See Decorating Your Controllers in Web API.
Feel free to review the MeasuredStartupFixture.cs example, which is beyond the immediate scope of this documentation. Whether you run with a self-hosted server, you have to still do all the normal things you would do connecting your filters, routes, bundles, and so on. Additionally, some specific Castle Windsor things.
With Web API you generally require an HttpConfiguration
. Starting from the ContainerBuilder
and using the Autofac
IContainer
:
ContainerBuilder Builder { get; }
Builder new ContainerBuilder();
IContainer Container { get; }
Container = Builder.Build();
There are several things that need to occur besides the basics of connecting routes with controllers and actions.
First install the Web API services using, in this case, the StartupFixture
to identify the assembly (or assemblies when otherTypes
is specified) from which to identify ApiController
types.
But before that, it is necessary to install a couple of services for Autofac
usage.
Builder.RegisterApiServices<
AutofacWebApiDependencyResolver
, AutofacHttpControllerActivator
, TraceExceptionLogger>();
In this case we want not only the third-party AutofacWebApiDependencyResolver
, but also our AutofacHttpControllerActivator
, as well as the TraceExceptionLogger
, which is used in the text fixture in order to expose any internal exceptions that may occur during run time warm up.
Following which we register the ApiController
classes found in the assembly.
Builder.RegisterApiControllers(typeof(MeasuredController).Assembly)
After building the Autofac
Container
, then use the container and middleware.
app.UseAutofacWebApi(config);
app.UseAutofacMiddleware(container);
Finally, inform the HttpConfiguration
as to what its DependencyResolver
ought to be.
config.DependencyResolver = container.Resolve<IDependencyResolver>();
Then we much configure for measurements to occur via the MeasuredStartupFixture
:
Builder.EnableApiMeasurements<
IHttpActionInstrumentationDiscoveryService
, HttpActionInstrumentationDiscoveryService>(CreateDiscoveryOptions);
And remember the options:
private static InstrumentationDiscoveryOptions CreateDiscoveryOptions()
{
return new InstrumentationDiscoveryOptions
{
ThrowOnInstallerFailure = false,
ThrowOnUninstallerFailure = false,
Assemblies = new[]
{
typeof(MeasuredController).Assembly
, typeof(AverageTimePerformanceCounterAdapter).Assembly
}
};
}
Enabling measurements can happen in a couple different ways:
public static ContainerBuilder EnableApiMeasurements<TInterface, TService>(
this ContainerBuilder builder
, Func<InstrumentationDiscoveryOptions> createOptions = null)
where TInterface : class, IHttpActionInstrumentationDiscoveryService
where TService : class, TInterface;
public static ContainerBuilder EnableApiMeasurements<TInterface, TService, TOptions>(
this ContainerBuilder builder
, Func<TOptions> createOptions = null)
where TInterface : class, IHttpActionInstrumentationDiscoveryService
where TService : class, TInterface
where TOptions : class, IInstrumentationDiscoveryOptions, new();
public static ContainerBuilder EnableApiMeasurements<TInterface, TService, TOptions, TProvider>(
this ContainerBuilder builder
, Func<TOptions> createOptions = null)
where TInterface : class, IHttpActionInstrumentationDiscoveryService
where TService : class, TInterface
where TOptions : class, IInstrumentationDiscoveryOptions, new()
where TProvider : class, ITwoStageMeasurementProvider;
Then the categories must be installed. In a production environment, something like this might be done via some sort of installation procedure.
private void Install<TDiscoveryService>()
where TDiscoveryService : class, IInstallerInstrumentationDiscoveryService
{
// Where the Container may be found in the calling scope.
var discoveryService = Container.Resolve<TDiscoveryService>();
using (var context = discoveryService.GetInstallerContext())
{
context.Install();
}
}
In the case of the unit testing, I install a couple different ways:
Install<IInstallerInstrumentationDiscoveryService>();
Install<IHttpActionInstrumentationDiscoveryService>();
And that's it. Feel free to run the unit tests for yourself to see how it works. Happy measuring!
- Framework agnostic
- ASP.NET