Freigeben über


Autofac and Azure Mobile Services .NET Backend

When creating an Azure Mobile Service .NET backend we automatically set up Autofac to deal with all things dependency injection. If you are new to Azure Mobile Services then here are tutorials and more. If you are not familiar with Autofac then they have a great wiki with lots of information. If you are not familiar with dependency injection in general then there are several books on the topic including Dependency Injection in .NET by Mark Seemann which I highly recommend.

In essence, dependency injection is about letting a dependency engine manage dependencies instead of having each type manage its own dependencies. To take a trivial example, instead of doing this:

    1: class MyClass1
    2: {
    3:     private readonly DependencyA dependencyA = new DependencyA();
    4:  
    5:     public void DoSomething()
    6:     {
    7:         // Use dependencyA
    8:     }
    9: }

where MyClass1 manages dependencyA manually, with dependency injection you can do this:

    1: public class MyClass2
    2: {
    3:     private readonly DependencyA dependencyA;
    4:  
    5:     public MyClass2(DependencyA dependencyA)
    6:     {
    7:         this.dependencyA = dependencyA;
    8:     }
    9:  
   10:     public void DoSomething()
   11:     {
   12:         // Use dependencyA
   13:     }
   14: }

Where the power of a dependency engine comes in is that it manages all these dependencies making sure they are instantiated correctly and garbage collected when they go out of scope. That is, instead of new’ing up an instance of MyClass2 manually, you register it with the dependency engine which then ensures that it is created with all its dependencies initialized.

The Azure Mobile .NET backend sets up and initializes Autofac to handle all its (and your!) dependencies allowing you to not only add your own dependencies but also to impact the dependencies that the .NET backend uses.

Existing Dependencies

Here are some of the dependencies that are automatically registered or used by the .NET backend. Actually most of the .NET backend uses dependency injection but some of the other dependencies are more esoteric affecting how the .NET backend operates (we will come back to more of these in future blogs).

You may ask whether it is possible to change the dependency engine to something other than Autofac. The answer is that it is technically possible but definitely in the open brain surgery category so not something I would recommend.

API Controllers

By default the .NET backend automatically enumerates all ApiControllers and registers them with Autofac. In addition, the controllers are registered to allow both constructor injection and property injection for those of you who prefer property injection (some consider constructor injection the preferred mechanism but it is really up to you).

The .NET backend provides ApiServices as a dependency you can use anywhere. ApiServices provides access to Azure Notification Hubs, logging, and more. For example, you can get it injected like this:

    1: public class CustomController : ApiController
    2: {
    3:     private ApiServices services;
    4:  
    5:     public CustomController(ApiServices services)
    6:     {
    7:         this.services = services;
    8:     }
    9:  
   10:     public string Get(string input)
   11:     {
   12:         services.Log.Info("Hello from custom controller!");
   13:         return "Hello";
   14:     }
   15: }

Scheduled Jobs

Scheduled jobs are similarly registered with Autofac and also supports both constructor and property injection. This means that you can also get injection of ApiServices and other dependencies for your scheduled job but as the ScheduledJob class is a base class (the actual dependency is on IScheduledJob), we already provide the ApiServices dependency for you:

    1: public class SampleJob : ScheduledJob
    2: {
    3:     public override Task ExecuteAsync()
    4:     {
    5:         Services.Log.Info("Hello from scheduled job!");
    6:         return Task.FromResult(true);
    7:     }
    8: }

Note: In order to activate the scheduled job to get fired on a given schedule you need to register it through the Azure portal.

Notification Handlers

An extensibility point which we discussed in the blog Push Notifications Using Notification Hub and .NET Backend is INotificationHandler which can be used to extend or modify the push notification registration process for Azure Notification Hubs. All INotificationHandler implementations are similarly registered with Autofac and you can leverage dependency injection there as well.

Extending the OWIN Pipeline

One of the things you may find surprising is that the OWIN application pipeline builder is registered with the dependency injection engine allowing you to modify and extend it. There actually are two dependencies that we look for: The first is the IOwinAppBuilder which is responsible for setting up the entire OWIN pipeline including authentication, ASP.NET Web API, and more. That is a very big hammer and so I would recommend looking at the IOwinAppBuilderExtension instead which allows you to simply add to the existing pipeline. In a future blog I will describe how we are using this extensibility point to hook in an exciting new feature to the .NET backend.

Registering Your Own Dependencies

In addition to leveraging the built-in dependencies, you can also register your own which you then can leverage wherever you want to use dependency injection. Simon Pedersen shows this very nicely in his blog Dependency Injection with Azure Mobile Services .NET Backend so I will just summarize here. To register your own dependencies, use the ConfigBuilder class to pass in a Func which is then called when the dependency engine is set up:

    1: public static void Register()
    2: {
    3:     ConfigOptions options = new ConfigOptions();
    4:     ConfigBuilder builder = new ConfigBuilder(options, (httpConfig, autofac) =>
    5:     {
    6:         autofac.RegisterInstance(new MyService()).As<IMyService>();
    7:     });
    8:     HttpConfiguration config = ServiceConfig.Initialize(builder);
    9: }

You can now use your dependency in any of the places above (and more) including your controllers, scheduled jobs, etc.

Have fun!

Henrik

Comments

  • Anonymous
    April 11, 2015
    Thanks