ASP.NET Core Inversion of Control and Dependency Injection

Introduction

There are quite a few good posts out there on Inversion of Control (IoC) and Dependency Injection (DI) in the ASP.NET Core world, but I felt there was still something to be said, hence this post! Mind you, this is going to be a long one! I once wrote another post on the history of dependency resolution in .NET, you may want to have a look at it. Always keep in mind that this is based on the latest bits, and may still change when it gets to the final version.

Services Registration

At bootstrap, ASP.NET Core will either call the ConfigureServices method, or one with a name following the convention Configure<environment>Services, where <environment> comes from the Hosting:Environment environment variable, and you can also set it in Visual Studio:

image

It is commonly set to “Development”, “Production”, “Staging”, etc. Keep in mind that if the environment-specific method exists (e.g., ConfigureDevelopmentServices), then the generic one (ConfigureServices) is not called.

The Configure*Services method is passed an instance of IServiceCollection, which is where we get to store our service registrations, so that they can be used by ASP.NET Core further along the pipeline. A service registration needs three things:

  • A key type, normally an interface or an abstract base class;
  • A concrete implementation of the key type;
  • A lifetime.

The lifetime determines how many times the concrete implementation is going to be built. The ASP.NET Core service provider implementation knows about three different lifetimes:

  • Scoped: an instance is created the first time it is requested during the same HTTP request, and during that request, this same instance is always returned;
  • Singleton: an instance is created the first time it is requested, and this same instance is always returned in all subsequent calls;
  • Transient: a new instance is always created, whenever it is requested.

A registration is an instance of the ServiceDescriptor class that is added to the IServiceCollection instance:

services.Add(new ServiceDescriptor(typeof(IMyService), typeof(MyService), ServiceLifetime.Singleton));

There are several extension methods that make this registration even easier.

What if you want to have custom processing when a service is returned? Simple:

services.AddTransient<IMyService>(sp =>

{

    var something = sp.GetService(typeof(ISomething)) as ISomething;

    var other = new OtherService();

    //do something with it

    return new MyService(other);

});

Keep in mind that the concrete service must either implement or inherit from the key service. Also, for the Scoped lifetime, if the concrete class implements IDisposable, the service provider will honor it and call Dispose at the end of the HTTP request.

After Configure*Services, ASP.NET Core calls Configure, also in the Startup class. This is where the core initialization occurs, like, adding all middleware, such as the MVC one, that makes the application works the way we expect it. The Configure method can either have no parameters or it can receive one or more parameters with types that match the registered services. For example, we will always have IApplicationBuilder, IHostingEnvironment, ILoggerFactory, so we can add them as parameters together with our own:

public void Configure(

    IApplicationBuilder app,

    IHostingEnvironment env,

    ILoggerFactory loggerFactory,

    IMyService service)

{

    //do something with the services

}

It gives us a good chance to initialize them before the actual fun begins. If we want, we can also pass it just an instance of the dependency resolution service, represented by the IServiceProvider interface, which has been around since the early days of .NET. The ASP.NET Core service provider implements this interface, so having it here just means: “get me the service provider implementation so that I can retrieve services from it”:

public void Configure(IServiceProvider serviceProvider)

{

    var env = serviceProvider.GetService(typeof(IHostingEnvironment)) as IHostingEnvironment;

    var service = serviceProvider.GetService(typeof(IMyService)) as IMyService;

}

In the latest version of ASP.NET Core, there is no globally accessible reference to the built-in service provider, something known as the service locator, of bad reputation. If, for any reason you feel you need it, here is the place to store it. By the way, the Microsoft.Extensions.DependencyInjection package has some good strongly typed extension methods for IServiceProvider, make sure you include it.

Services

Each concrete service class itself can be dependency-injected: by default, it should be a concrete class and have a public parameter-less constructor; if, however, we want to inject dependencies into it, which also need to be registered in the service provider, we can have a constructor that takes these dependencies:

public class MyService : IMyService

{

    public MyService(IServiceProvider serviceProvider)

    {

        //get something from the service provider

    }

}

Notice the usage of IServiceProvider again. Another option is to have the constructor contain more concrete dependencies:

public class MyService : IMyService

{

    public MyService(ILoggerFactory loggerFactory)

    {

        //do something with the logger factory

    }

}

You can pass any number of parameters, of any type that is registered in the service provider, normally in one of the Configure*Services methods. If the specified service type is not registered, you get an exception at runtime.

Controllers

An MVC controller can have dependencies injected through its constructor, like I’ve shown for services:

public class HomeController : Controller

{

    public HomeController(IMyService service)

    {

        //do something with the service

    }

}

The same pattern applies: we can either declare a parameter as IServiceProvider or as a more specific type. It doesn’t matter if our controller inherits from Controller or is a POCO controller.

There was another dependency injection possibility with MVC controllers, which consisted in decorating public properties with a [FromServices] attribute: if a registration exists that matched the property’s type, it would be injected into the property just after the controller is constructed:

public class HomeController

{

    [FromServices]

    public IService Service { get; set; }

}

This is no longer possible, and the functionality was removed in DNX RC2, although it will still work in RC1. Forget about it.

By default, controller classes themselves do not come from the dependency resolution mechanism. You can achieve that, if, in Configure*Services, you call AddControllersAsServices, passing it either a Type or an Assembly collection:

services

    .AddMvc()

    .AddControllersAsServices(new[] { typeof(HomeController).GetTypeInfo().Assembly });

This allows you to do this:

services.AddSingleton<HomeController, SingletonHomeController>();

Each time MVC tries to build an HomeController, it will instead get the same SingletonHomeController. Note that I am not saying that you should do this, but I think you get the idea!

Filters

Filters in MVC allow you to intercept action method calls, results and exceptions, and do stuff before, after of instead of the real actions. You have global filters and attribute filters: global filters apply always, and attribute filters only apply in the scope where they are declared – a controller’s class or an action method. Filters themselves can have dependencies injected into them.

In order to declare global filters, you use one of the overloads of the AddMvc method, normally in the Configure*Services method, and registering the filter as a service:

services.AddMvc(mvc => mvc.Filters.AddService(typeof(GlobalFilter)));

MVC will try to resolve the filter type, if necessary, injecting it any dependencies, in the usual way:

public class GlobalFilter : IActionFilter

{

    public GlobalFilter(IMyService service)

    {

        //do something with the service

    }

 

    public void OnActionExecuted(ActionExecutedContext context)

    {            

    }

 

    public void OnActionExecuting(ActionExecutingContext context)

    {

    }

}

The other option for filters is attributes, but attributes require a public parameter-less constructor. The MVC team came up with an alternative for that, in the form of the ServiceFilterAttribute and TypeFilterAttribute attributes. Both receive a Type and the difference is that the first will try to resolve that type from the services registration and the last one will just instantiate it. Let’s see an example:

[ServiceFilter(typeof(GlobalFilter))]

public class HomeController : Controller

{

    [TypeFilter(typeof(SomeFilter))]

    public IActionResult Index()

    {

        //...

    }

}

So, GlobalFilter is retrieved from the services registration, and, if it is a filter, it will behave accordingly to the context where it is located, in this case, it is the whole controller. SomeFilter, on the other hand, is just instantiated and used, no need to have it registered. Don’t forget that types passed to ServiceFilterAttribute and TypeFilterAttribute have to implement one of the filter interfaces in namespace Microsoft.AspNet.Mvc.Filters otherwise an exception is thrown.

Models

Model classes are declared as parameters to action methods in an MVC controller. There’s a binding mechanism that fills their properties automatically, but we can also use dependency injection here.

First, the whole model can come from dependency injection:

public IActionResult Index([FromServices] IMyService service)

{

    //...

}

Or, at least, some properties of the model:

public IActionResult Update(Model model)

{

    //...

}

 

public class Model

{

    [FromServices]

    public IMyService Service { get; set; }

 

    //...

}

Views

MVC views can also take injected services, through the @inject directive:

@inject IMyService service;

 

<p>@service.Serve()</p>

View Components

View components, introduced in ASP.NET MVC Core, can also be injected in pretty much the same way as controllers:

public class MyServiceViewComponent : ViewComponent

{

    public MyServiceViewComponent(IMyService service)

    {

        //do something with the service

    }

    

    public string Invoke()

    {

        //...

    }

}

Tag Helpers

Tag helpers, like view components and controllers, also support constructor injection:

[HtmlTargetElement("service")]

public class ServiceTagHelper : TagHelper

{

    public ServiceTagHelper(IMyService service)

    {

        //do something with the service

    }

 

    public override void Process(TagHelperContext context, TagHelperOutput output)

    {

        //...

    }

}

Middleware

OWIN-style middleware are likewise injectable through the constructor:

public class ServiceMiddleware

{

    private readonly RequestDelegate _next;

    

    public ServiceMiddleware(RequestDelegate next, IMyService service)

    {

        this._next = next;

        //do something with the service

    }

    

    public Task Invoke(HttpContext httpContext)

    {

        //...

    }

}

Using a Custom IoC/DI Container

Now, you may not want to use the built-in service provider and use your own (Unity, Autofac, Ninject, TinyIoC, etc). That is certainly possible!

You need to change the signature of the Configure*Services method so as to return an IServiceProvider:

public IServiceProvider ConfigureServices(IServiceCollection services)

{

    services.AddMvc();

 

    services.AddTransient<IMyService, MyService>();

 

    return new MyIoCContainer(services.BuildServiceProvider());

}

The key here is to create an instance of the service provider we want to use, maybe leveraging on the one produced from the service collection (BuildServiceProvider method), and return it here. Of course, if it has more features and lifetimes than the default one, you are free to use them all. The only contract it has to comply to is that of IServiceProvider.

Dependency Resolution

While running your MVC application, you can explicitly ask for services registered in the global (the default or your own) service provider. The HttpContext class exposes a RequestServices property; here you will find the custom service provider that you returned in Configure*Services, or ASP.NET Core’s built-in one. Whenever you have a reference to the current HttpContext (controllers, view components, tag helpers, views, middleware, filters), you get it as well. The “old” ApplicationServices was removed in recent commits, so it won’t make it to the final version of ASP.NET Core and you shouldn’t be using it.

Conclusion

The dependency injection mechanism was substantially changed in ASP.NET Core. The only identical feature seems to be constructor injection, and it is understandable, since it’s what most people should be using anyway. Now every moving part of ASP.NET Core is injectable through the same mechanism, which I think is a good thing. The problems so far have been the relative instability in the ASP.NET Core, things have been changing a lot, and there is still no light at the end of the tunnel.

The Evolution of .NET Dependency Resolution

Introduction

Dependency Resolution (RS), Dependency Injection (DI) and Inversion of Control (IoC) are hot topics nowadays. Basically all frameworks are aware of it, or offer some mechanisms to help implement it. It all started a long time ago, however, and things are slightly confusing at the moment – but will get better!

In this post, I won’t go through all of the details of all dependency resolution libraries in existence, instead I will only focus on Microsoft libraries. Also, I will only talk about generic dependency resolution, leaving out more specialized usages, such as WCF, WF and SharePoint, which also use similar concepts.

Origins

It all started with the venerable IServiceProvider interface. It basically provided a single method, GetService, that gave answer to “get me an implementation for this type”. That was it, the single parameter was a Type, and the response, a single object. There were no public implementations of it, but Windows Forms designers – auto generated code – used it a lot to request services from the design surfaces (aka, Visual Studio designer). You were free to implement it in any way, the only recommendation was to return null in case no service could be found, instead of throwing an exception.

ASP.NET MVC

ASP.NET MVC started as a built-in template option in Visual Studio but then migrated to NuGet deployment, which is how Microsoft now delivers its fast-moving libraries. MVC 4 introduced its own dependency injection container and API. It was built around IDependencyResolver interface, which did not implement IServiceProvider. although it offered a GetService method that had exactly the same signature – and requirements – as IServiceProvider’s. It also added another method, GetServices, for retrieving all implementations of a given service, again identified by its Type.

This time we had a registration point, which was DependencyResolver.Current. You could set it to your custom implementation, or use the default, which didn’t really return anything.

ASP.NET Web API

Web API came out a bit later than MVC, and, while sharing its philosophy, and also being delivered through NuGet, offered its own APIs, namely, for dependency injection. There was also a IDependencyResolver interface, again, not inheriting from IServiceProvider, but with a slightly more complex inheritance: now we had also IDependencyScope, which was where the GetService and GetServices methods were declared, as well as IDisposable, supposedly so that we could have dependency resolution scopes. The well-known registration point was GlobalConfiguration.Configuration.DependencyResolver.

ASP.NET SignalR

SignalR was something of an outsider in the ASP.NET stack. Like MVC and Web API, it was offered (and still is, for that matter) as a separate NuGet package. No wonder that it also offered its own dependency resolution API, in the form of IDependencyResolver. Again, not related to IServiceProvider, and as such offered a couple of other methods: besides the classic GetService (same signature and contract), we also had GetServices, and even a registration method (RegisterType with a couple of overloads). It was also IDisposable, perhaps to control registration scopes. The registration point was available as GlobalHost.DependencyResolver and there was a default implementation, appropriately named DefaultDependencyResolver.

Entity Framework 6

Leaving ASP.NET land for a moment, Entity Framework 6 also introduced its own (of course…) API for dependency resolution. The IDbDependencyResolver also offered the now classic GetService and GetServices methods, but this time, these also took an optional key parameter. GetService should not throw if a matching service was not found, and GetServices should return an empty enumeration likewise. The registration was done through DbConfiguration.DependencyResolver, no public default implementation. EF 6 expected a number of services to be supplied through dependency resolution, otherwise, it would use its own built-in defaults.

Entity Framework 7

Although still in pre-release, EF 7 shuffles things a bit. For once, the DbContext constructor can now take an instance of IServiceProvider. More details coming soon, I guess, but apparently it seems to be going back to the roots.

Unity

Unity is part of Microsoft’s Enterprise Library and long time readers of my blog should know that it’s what I normally use for inversion of control (IoC), dependency injection (DI) and aspect-oriented programming (AOP). Being an IoC container, it includes its own API, IUnityContainer, which also offered service resolution methods, besides lots of other stuff; this time, the names are Resolve and ResolveAll, with several overloads and generic as well as non-generic versions. Resolve can take an optional key, but a major difference is that the default implementation (UnityContainer) will throw an exception if a service is not found.

Common Service Locator

Because there are lots of dependency resolution libraries out there, offering conceptually similar services but with different APIs, Microsoft sponsored an open-source library for defining a common interface for dependency resolution to which interested parties could comply, or, better, write an adapter for. The code is available in Codeplex and NuGet and several library authors provided adapters for the Common Service Locator, such as Unity, Castle Windsor, Spring.NET, StructureMap, Autofac, MEF, LinFu, Ninject, etc. See a list of NuGet packages matching Common Service Locator here. The Common Service Locator API only prescribes two families of methods in its IServiceLocator API: GetInstance and GetAllInstances. Interestingly, IServiceLocator inherits from IServiceProvider, and it also features an optional key for GetInstance, like EF6 and Unity, as this is the more general case – multiple registrations for the same type under different keys, the default key is null.

ASP.NET 5

ASP.NET 5 is just around the corner, and Microsoft seems to me to be moving in the right direction. MVC, Web API and SignalR are merged together, so the dependency resolution mechanisms should be the same. The IServicesCollection (sorry, no public API documentation) interface allows for the registration and the resolution of services through the conventional Startup.ConfigureServices method and is made available in the HttpContext and IApplicationBuilder implementations as the ApplicationServices and RequestServices properties, of type IServiceProvider. Not that you typically need it, but the default implementation of IServicesCollection is ServicesCollection, and one key difference is that you do not have a global entrypoint to it, you can only access it through the current HttpContext reference, in most cases.

Conclusion

That’s it. Looking forward for your feedback on this.

Unity, Part 9: Integration With Managed Extensibility Framework

This time, I will be talking about integrating Unity with Managed Extensibility Framework (MEF). You can find the other posts in the series here (how to use Unity in a web application), here (adding Interfaces), here (registration by convention), here (injecting values), here (extensions), here (aspect-oriented programming), here (dependency injection) and the first one here (introduction).

The Managed Extensibility Framework (MEF) has been around since the release of .NET 4.0, and even before as a beta, stand-alone package. Basically, it provides an extensible mechanism for detecting and loading plugins. It’s easier to use than the similarly-named Managed Add-In Framework (MAF), and even if it’s not so feature-rich (it doesn’t support sandboxing, for once), unlike MAF, it is well alive!

So, what does MEF offer that can be of use to Unity? Well, MEF knows how to locate exports/plugins from a number of locations, like assemblies and file system directories. It’s just a matter of finding the exports we’re interested in and registering them with Unity.

An export in MEF is some class that is decorated with an ExportAttribute (technically speaking, this is just when using the Attributed Programming Model, since .NET 4.5 there is also the Convention-Based Programming Model). This attribute allows specifying the type to export (ContractType) and also the contract name (ContractName). This matches closely the Unity/IoC concept of contract type and name.

We could find all exports under a given path using MEF using an AssemblyCatalog, a particular implementation of a ComposablePartCatalog:

   1: var catalog = new AssemblyCatalog("some path");

A couple of helper functions for picking up the export’s contract type and name, by leveraging the ReflectionModelServices class:

   1: public static IDictionary<String, Type> GetExportedTypes<T>(this ComposablePartCatalog catalog)

   2: {

   3:     return (GetExportedTypes(catalog, typeof(T)));

   4: }

   5:  

   6: public static IDictionary<String, Type> GetExportedTypes(this ComposablePartCatalog catalog, Type type)

   7: {

   8:     return (catalog.Parts.Where(part => IsComposablePart(part, type) == true).ToDictionary(part => part.ExportDefinitions.First().ContractName, part => ReflectionModelServices.GetPartType(part).Value));

   9: }

  10:  

  11:  

  12: private static Boolean IsComposablePart(ComposablePartDefinition part, Type type)

  13: {

  14:     return (part.ExportDefinitions.Any(def => (def.Metadata.ContainsKey("ExportTypeIdentity") == true) && (def.Metadata["ExportTypeIdentity"].Equals(type.FullName) == true)));

  15: }

This will return a collection of key-value pairs, where the key is the contract name and the value the contract type; this is so there can be multiple contract names for a given contract type. After we have this, it’s just a matter of iterating the results and registering each occurrence:

   1: var type = typeof(ISomeType);

   2: var exports = catalog.GetExportedTypes(type);

   3:  

   4: foreach (var entry in exports)

   5: {

   6:     unity.RegisterType(type, entry.Value, entry.Key);

   7: }

So, given the following contract and implementations:

   1: public interface ISomeType

   2: {

   3:     void SomeMethod();

   4: }

   5:  

   6: [Export("Some", typeof(ISomeType))]

   7: public class SomeImplementation : ISomeType

   8: {

   9:     public void SomeMethod() { }

  10: }

  11:  

  12: [Export("Another", typeof(ISomeType))]

  13: public class AnotherImplementation : ISomeType

  14: {

  15:     public void SomeMethod() { }

  16: }

We can obtain a specific contract type implementation given it’s name:

   1: var myImplementation = unity.Resolve<ISomeType>("MyName");

And also all implementations of the contract that were found:

   1: var all = unity.ResolveAll<ISomeType>();

This can be enhanced in a couple of ways:

  • Use a Unity extension to automatically find and register exports at runtime;
  • Make use of MEF metadata to tell Unity which lifetime managers to use, and other useful properties, such as the default implementation for the contract type.

As usual, I’m looking forward for your comments!