Skip to content

_AspNet_Mvc_DependencyInjectionwithAutofac

Michael Powell edited this page Feb 4, 2017 · 11 revisions

Background and ASP.NET migration paths

See ASP.NET migration path for further details.

Dependency Injection with Autofac

Exposing performance measurement into ASP.NET MVC via Autofac is just a bit different than with Castle Windsor.

Package References
MeasureIt.AspNet.Mvc.Autofac
Microsoft.AspNet.Mvc
Autofac
Kingdom.AspNet.Mvc.Core
MeasureIt.AspNet.Mvc.Core
MeasureIt.AspNet.Mvc.Core
Microsoft.AspNet.Mvc
Kingdom.AspNet.Mvc.Core
MeasureIt.Core
MeasureIt.Core

Decorate your classes

See Decorating Your Controllers in ASP.NET MVC.

Wire up your measurement filters

Feel free to review the Global.asax.cs example, which is beyond the immediate scope of this documentation. You have to still do all the normal things you would do connecting your filters, routes, bundles, and so on. Additionally, some specific Autofac things:

Starting from the ContainerBuilder.

ContainerBuilder Builder { get; }
Builder = new ContainerBuilder();

Register the required services with the container.

Builder.RegisterRequiredServices<AutofacDependencyResolver>();

You may get more specific with that if you care to. However, the default TInvoker is the AutofacControllerActionInvoker, which we provide for you.

public static ContainerBuilder RegisterRequiredServices<TInvoker, TResolver>(
    this ContainerBuilder builder)
    where TInvoker : class, IAutofacControllerActionInvoker
    where TResolver : class, IDependencyResolver;

You have to register your controllers as well. While we are there, we also want to InjectActionInvoker.

Builder.RegisterControllers(new [] {typeof(HomeController).Assembly}).InjectActionInvoker();

Now the most important step to instrumentation is to wire up the required discovery services and options.

Builder.EnableMvcMeasurements<
    IMvcActionInstrumentationDiscoveryService
    , MvcActionInstrumentationDiscoveryService>()
;

The basic form is fairly self-explanatory, with more specific versions also available. The default options factory provides the default options.

public static ContainerBuilder EnableMvcMeasurements<TInterface, TService>(
    this ContainerBuilder builder
    , Func<InstrumentationDiscoveryOptions> createOptions = null
    , Action<InstrumentationDiscoveryOptions> optionsActivated = null)
    where TInterface : class, IMvcActionInstrumentationDiscoveryService
    where TService : class, TInterface;
public static ContainerBuilder EnableMvcMeasurements<TInterface, TService, TOptions>(
    this ContainerBuilder builder
    , Func<TOptions> createOptions = null
    , Action<TOptions> optionsActivated = null)
    where TInterface : class, IMvcActionInstrumentationDiscoveryService
    where TService : class, TInterface
    where TOptions : class, IInstrumentationDiscoveryOptions, new();
public static ContainerBuilder EnableMvcMeasurements<TInterface, TService, TOptions, TProvider>(
    this ContainerBuilder builder
    , Func<TOptions> createOptions = null
    , Action<TOptions> optionsActivated = null)
    where TInterface : class, IMvcActionInstrumentationDiscoveryService
    where TService : class, TInterface
    where TOptions : class, IInstrumentationDiscoveryOptions, new()
    where TProvider : class, ITwoStageMeasurementProvider;

After you have built the container, then you must resolve a couple of issues prior to running your instrumented web site.

DependencyResolver.SetResolver(container.Resolve<IDependencyResolver>());

Installing your discovery service context is critical, otherwise measurement will fail since there are no registered resources to back up the performance counter claims. I recommend considering some sort of installation procedure, but this will work for test purposes in the Global warm up.

using (var context = container.Resolve<IInstallerInstrumentationDiscoveryService>()
    .GetInstallerContext())
{
    context.Install();
}

And that's it. Happy measuring!