CHAPTER 14

image

Dependency Resolution

Nowadays you could hardly find serious software that does not use one or another form of dependency injection. ASP.NET Web API has been built with this in mind, and in fact it uses a dependency resolution model similar to ASP.NET MVC to resolve its public dependencies. This model allows you to plug in your dependency injection framework of choice.

In this chapter we talk about dependency resolution and its model within ASP.NET Web API. Later on, we look into how to code against the ASP.NET Web API’s dependency resolution model. At the end, we look into implementing dependency resolution model for popular dependency injection frameworks.

It is very likely that you have already used dependency injection (DI) in your projects and are familiar with it—and if you have not, no need to worry! After a brief introduction to DI and a few related terms, we move on to give you an understanding of how these concepts are used in ASP.NET Web API. Even if you have used DI before, this intro might still be useful, as there is a lot of confusion in the community as to exactly what each term means. However, if you think you have a good grasp of the concept, skip to the next topic, whose focus is ASP.NET Web API.

Key Inversion of Control Concepts

What is dependency injection (DI), and how is it different from Inversion of Control (IoC) or Service Location? Let’s look briefly at these concepts.

Inversion of Control (IoC)

Inversion of Control (IoC), a computer science concept linked with Aspect Oriented Programming (AOP), is now mainly used in the context of dependency injection. However, what is Inversion of Control more generally?

Inversion of control is a general principle in software programming by which you change the flow of control in dependent components so that control of the dependencies is outside the dependent component rather than inside it. So if A is dependent on B, instead of A having full knowledge of B, you invert the control so that A has no knowledge of where B resides. This knowledge, which would sit inside an IoC container—in some ways similar to a repository—is responsible for providing dependencies based on the configuration defined by the application. Some frameworks also track the lifetime of the dependencies and manage the lifetime of dependencies they serve so that you do not have to.

Here’s an example. Let’s imagine you have just joined another development team, and the team is going out for lunch. You know neither the name or location of the restaurant nor the usual timing of the lunch (although you guess it is around midday!). So for lunch, you are fully dependent on the team. What would you do? Call up everyone, organize the lunch, and announce how you will get to the restaurant? Not at all! The team will tell you, “Don’t worry, we will pick you up when we go there,” because you are really the person least suited to organizing lunch. In the same way, a dependent component is the worst candidate to resolve its dependencies. Let’s look at the patterns used for achieving IoC.

Dependency Injection

Dependency injection is a pattern (or a technique) to inject the dependencies of a software component into it. In line with the Single Responsibility principle (the first of five principles of software design usually referred to by the acronym SOLID), a software component (let’s say a class) should not be worried about how to get hold of its dependencies to achieve its purpose since it will have too many responsibilities (resolving its dependencies as well as its main purpose). For example, a TaxCalculator class responsible for calculating the VAT (value-added tax) of a purchased item should not be responsible for reading the current value of the VAT percentage from the database (since to do so it would have to know the structure of the database, the technology to connect, etc.). Having to know so much would be having too many responsibilities. Instead it should depend on a TaxConfiguration class, which holds various tax rates. The former class uses the latter to get access to the current VAT rate.

image Note  SOLID is the acronym for a set of five principles in software design presented by Robert C Martin (a.k.a Uncle Bob) in a paper in 1997. Its letters stand for

Single responsibility, Open-closed, Liskov substitution, Interface segregation, and Dependency inversion. Along with DRY (Do not Repeat Yourself) and YAGNI (You Ain’t Gonna Need It), the SOLID principles are some of the patterns and best practices software developers consider and go back to on a daily basis. If they are not familiar to you, time invested in fully understanding them is definitely time well spent.

Another aspect of the DI (the D in SOLID) is to design the types in a way that they depend on abstraction rather than concrete implementation. We normally design classes to depend on interfaces (or abstract classes) rather than actual implementation. This approach is extremely valuable in unit testing, as we can use mock (or stub) objects of the type being tested so that their behavior can be independently tested without the need to test in a real working environment.

There are two DI mechanisms available for classes: property injection and constructor injection. Property injection, the older approach, involves defining public properties of the abstract dependencies on the type. For example:

// a tax calculator implementing ITaxCalculator
// using property injection
public class TaxCalculator : ITaxCalculator
{
    public ITaxConfiguration Configuration {get; set;}
    
    // ... rest of the implementation
}

Here ITaxConfiguration is a service in DI terms since it requires resolving (note that ITaxCalculator can also be a service for other types).

There are several problems with this approach, one of which is that the property injection usually fails silently if it cannot find a matching type. You get null reference errors as soon as you want to use the dependency (as you know, null reference exceptions are hard to debug). Another problem is that these properties normally need to be defined as public read/write, which is not ideal.

A better (and currently standard) approach is to use constructor injection:

// a tax calculator implementing ITaxCalculator
// using constructor injection
public class TaxCalculator : ITaxCalculator
{
    private readonly ITaxConfiguration _configuration;
    
    public TaxCalculator(ITaxConfiguration configuration)
    {
        _configuration = configuration;
    }
        
    // ... rest of the implementation
}

Regardless of property injection or constructor injection, the job of resolving dependencies is with the IoC containers. An IoC container must have knowledge of how to resolve each dependency. There are many DI frameworks (providing IoC containers) to choose from—Castle Windsor, AutoFac, NInject, Unity—as well as other frameworks, such as StructureMap and Spring.NET and even Microsoft Extensibility Framework (MEF), which can be used for dependency injection. The first four are the most popular frameworks, and the coming sections review their use in ASP.NET Web API.

In dependency injection, you create the container and register the types against it. Then the dependencies are automatically resolved at the time of object creation. In the past registration was done through configuration files, but most recent frameworks provide fluent API.

Normally, registering “services” in the IoC container requires registering the abstract type against the container along with its concrete implementation. For example:

// registering ITaxCalculator in AutoFac
var builder = new ContainerBuilder();
builder.RegisterType<TaxCalculator>().As<ITaxCalculator>();
var container = builder.Build(); // 2-stage DI exclusive to AutoFac

The container object, which is the result of the Build() method, is the IoC container. In DI, the container is not directly used to resolve dependencies.

Service Locator

The Service Locator pattern is another pattern to achieve IoC. Unlike DI, where the components are oblivious of their construction and dependency resolution, in the Service Locator pattern, they proactively use the IoC container to resolve their dependencies. For example, we can use the container created above to resolve ITaxCalculator:

// Service Locator pattern in AutoFac
var taxCalculator = container.Resolve<ITaxCalculator>();

The Service Locator pattern is simple to understand but is generally considered inferior to dependency injection. First, it adds a new dependency to all classes: knowledge of the container. Another problem is that while IoC containers are responsible for resolving and possibly creating instance of services, they either track them and are responsible for their disposal (as in Castle Windsor) or provide a transient scope (in other assemblies) so that they are disposed of after use. This cannot happen in the Service Locator pattern unless each class becomes responsible for cleaning up its mess—if this is forgotten, bugs and memory leaks can result.

Having said that, each pattern has its own place, and each can be useful. As you will see, ASP.NET Web API uses the Service Locator pattern while allowing you to use the DI framework of your choice.

Factory Pattern

Another IoC technique is the Factory pattern. In this pattern, instead of taking dependency on the service itself, you take dependency on the Factory that can create the service. Factory generally is another type—or sometimes a Func<> in functional programming—that can create the service. IoC containers themselves are generally considered factories.

The Factory pattern is useful when you have to provide parameters to control various aspects of the object being returned from the factory. Factories are used heavily in ASP.NET Web API and ASP.NET MVC. Every class named with the postfix provider (such as ModelBinderProvider) is a factory.

Registration and Lifetime Scope in Dependency Injection

When registering services against the IoC container, you can register a type (which implements the abstract service), a factory to generate your service, or an instance.

If you register an instance, the instance is provided every time you resolve the service against the container. The instance as such can be seen as a singleton. This is an important concept, since ASP.NET Web API commonly uses this approach.

If you register a concrete type against your service, you normally get to choose a lifetime policy for instances of that service when they are resolved. Many DI frameworks provide different lifetime policies: transient, singleton, per HTTP request, and others. In a transient lifetime policy, you always get a new object from the IoC container. In a per-HTTP-request policy, you have one object per registration for the lifetime of the HTTP request. With a singleton policy, as the name implies, you always get the same object back for a given registration.

Service Location in ASP.NET Web API

ASP.NET Web API registers its services in its own container. It uses the Service Locator pattern to resolve these dependencies when it needs them. By using the container provided by the framework, you can change the default registration and register your own types.

Let’s look at an example that will whet your appetite. Many services defined in the library can be replaced (we look at them later in the chapter), but now let’s look at ITraceWriter, which is responsible for tracing (covered in Chapter 16). Imagine that we have written a trace writer called MyOwnTraceWriter and we need to replace the default trace writer with our own.

// assuming a web hosted service
var config = GlobalConfiguration.Configuration;
config.Services.Replace(typeof(ITraceWriter), new MyOwnTraceWriter()); // note that we registered an instance against the dependency Resolver

Here we are replacing the registered ITraceWriter with our own instance of MyOwnTraceWriter. If you have enabled tracing in your ASP.NET Web API, it will use the type you provide.

The Services property, which sits on the HttpConfiguration class, is of the type ServicesContainer, and it can be looked at as a custom IoC container that implements the Service Locator pattern. Since we register the instance against the type, the registration will be singleton. To better understand these concepts, you’ll need to take a closer look at ServicesContainer class.

This class is a special IoC container registration that you can use to register singleton instances against service types. Also, you may register more than one instance against a single service type. For example, for ModelBinderProvider, a number of ModelBinderProvider instances are registered, including instances of TypeConverterModelBinderProvider and TypeMatchModelBinderProvider.

Remember that this class is mainly designed to resolve dependencies of the framework itself. Registering a custom service against this class will not work.

// this will raise an error
config.Services.Add(typeof(ITaxCalculator), new TaxCalculator); // exception!

Table 14-1. Important Services Registered in ServicesContainer Class

Service Type Description
IActionValueBinder binds parameters of an action
IapiExplorer responsible for gathering information about the API
IContentNegotiator carries out content negotiation in the HTTP pipeline
ItraceWriter responsible for outputting trace in the framework
IHttpControllerSelector finds and selects the controller responsible for a request
IHttpControllerActivator creates/activates an instance of the selected controller
IHttpActionSelector selects the action responsible for serving the request
IHttpActionInvoker invokes the selected action

The ability to replace default implementations provided by the framework is very powerful. For example, you would probably remember that IControllerActivator in ASP.NET MVC was important and could be replaced to hook in your dependency injection framework of choice. In the same fashion, IHttpControllerActivator is responsible for creating (or simply activating) the controller selected by the IHttpControllerSelector. However, ASP.NET Web API provides an easier means to hook in your dependency injection framework.

Dependency Resolution Model in ASP.NET Web API

ASP.NET Web API uses a service location pattern to resolve its public dependencies. The approach is very similar to the DependencyResolver model that has been part of ASP.NET MVC since version 3. However, the ASP.NET team has improved this approach for Web API, especially in terms of lifetime management. This section reviews the dependency resolution model in ASP.NET Web API.

A Typical Dependency Resolution Scenario

Let’s say you use dependency injection in your project and use constructor injection for your classes. How does each relate to your ASP.NET Web API? Let’s look at the controller below:

public class TaxController : ApiController
{
    private readonly ITaxCalculator _taxCalculator;
  
    public TaxController(ITaxCalculator taxCalculator)
    {
        _taxCalculator = taxCalculator;
    }
}

Your controller has a dependency to the ITaxCalculator, and you are relying on your DI framework to inject an instance of the concrete class that has been set up against ITaxCalculator to be passed to the constructor when ASP.NET Web API creates an instance of your controller. But if IHttpControllerActivator creates your controller, how would it know about your DI framework, and thus how could it use the framework to create an instance of your controller? This is where the DependencyResolver model comes into play.

HttpConfiguration class exposes the read/write property DependencyResolver, which is used to hook in the DI framework. This property is of the type IDependencyResolver, which means in order to plug in the DI frameworks, this interface needs to be implemented by you or the library provider. As you will see, there are already implementations available for all major DI libraries.

The IDependencyResolver interface itself is very simple:

public interface IDependencyResolver : IDependencyScope
{
    IDependencyScope BeginScope();
}

That is, IDependencyResolver implements IDependencyScope, which is itself simply a Service Locator interface:

public interface IDependencyScope : IDisposable
{
    object GetService(Type serviceType);
    IEnumerable<object> GetServices(Type serviceType);
}

So starting with IDependencyScope, you see that it contains two methods: one for resolving a single service and a second for resolving all services implementing a type. The latter is particularly important when using the strategy or visitor pattern.

To return to our TaxController example, DefaultHttpControllerActivator (which implements IHttpControllerActivator and is the default activator set up to create instances of your controllers) uses the dependency scope and calls the GetService method. If your DI Framework is hooked up, this will go to your IoC container, and all your types will have automatic resolution.

Depending on the case, internal implementation of ASP.NET Web API knows whether it needs to resolve a single service or multiple services and so calls either GetService() or GetServices(), respectively.

Look very closely at the IDependencyScope, and you will notice that it also implements IDisposable. To understand the disposal side of the dependency scope, you need to take a deeper look into the lifetime scope of the dependency scope.

Understanding the Lifetime of the IDependencyResolver and IDependencyScope

If you have used DI frameworks before, you are probably aware that the IoC container’s lifetime normally is the same as that of the application AppDomain. In other words, you normally create the IoC container when the application is started and dispose of it only at the time the application is closed. Thus, you can think of it as singleton.

// configuration is an instance of HttpConfiguration class
Configuration.DependencyResolver = new MyCustomDependencyResolver(); // assuming
MyCustomDependencyResolver is an implementation of IDependencyResolver

So the IDependencyResolver interface is analogous to your IoC container: it is set once as a singleton on the HttpConfiguration (which itself can be thought of as a singleton, as you have one configuration for each ASP.NET Web API application) and used throughout the application. As you have already seen, IDependencyResolver implements IDisposable (indirectly through implementing IDependencyScope). The Dispose method on the dependency resolver is called only at the end of the application—that is, when AppDomain is being unloaded.

image Note  If you have followed the ASP.NET Web API development since its early beta, you probably remember that the design of the DependencyResolver model underwent a few major changes. It initially used reflection to figure out the methods implementing GetService() and GetServices(). Also there was no BeginScope()—this was added later to complete the picture of creation and disposal of dependencies.

The lifetime of IDependencyScope, however, is the same as that of each request. At the start of each request, ASP.NET Web API calls BeginScope() method on the IDependencyResolver to create an instance of IDependencyScope (its implementation, rather) for the lifetime of the request. This dependency scope is responsible for keeping track of the dependencies resolved for the lifetime of the request and dispose of them when the request is disposed of. So the relationship between IDependencyScope and the request is one to one. Bear in mind that what we mean here by disposing of dependencies is not necessarily calling Dispose() on the objects implementing IDisposable. Some DI frameworks (Castle Windsor among them) keep track of objects created, so they need to know when to release them.

IDependencyScope and HttpRequestMessage

As already said, HttpRequestMessage and IDependencyScope have a one-to-one relationship. In fact, you can access an IDependencyScope instance for an HttpRequestMessage via its properties:

var dependencyScope = (IDependencyScope)
           request.Properties[HttpPropertyKeys.DependencyScope];

You can also use the extension GetDependencyScope() to achieve the same result, although calling this extension method gets hold of an IDependencyScope by calling BeginScope() if it is not already in the properties:

var dependencyScope = request.GetDependencyScope();

ASP.NET Web API breaks the long tradition (a pretty bad one) of storing the context in the HttpContext.Current. Instead, it stores its context directly inside the properties of the request. This is essential, since the HttpContext in some cases does not flow to other threads when a thread switch happens. Thread switching most commonly happens when using the Async model (explained in Chapter 2). When the context is stored in the properties of the request, it does not matter which thread processes the request. HttpContext.Current uses a thread’s local storage area to store the context, while Properties is a plain (but thread-safe) dictionary for storing context.

As soon as an IDependencyScope is associated with an HttpRequestMessage, it is registered by the ASP.NET Web API for disposal. This is achieved using the RegisterForDispose() extension of the HttpRequestMessage. This in turn adds the IDependencyScope to a list stored in the Properties property of the request, later to be looped through, and Dispose() is called upon each object.

Using DependencyResolver Implementations Available for ASP.NET Web API

The ASP.NET Web API DependencyResolver model for common DI frameworks is implemented in the WebApiContrib project (available at GitHub, http://webapicontrib.github.io/), as well as other independent projects. NuGet packages are available that make the process of adding these libraries easier. Visit https://github.com/WebApiContrib to see the list of all projects.

For example, to add NInject DependencyResolver, type this command in the Package Manager console:

PM> Install-Package WebApiContrib.IoC.Ninject

This command will add the NInject library, as well as the DependencyResolver implementation. The next step is to create a NInject Kernel and use it to instantiate a NInject dependency resolver and set the DependencyResolver property against your configuration to your resolver instance:

var kernel = new StandardKernel();
// use kernel to register your dependencies
var dependencyResolver = new NInjectResolver(kernel);
config.DependencyResolver = dependencyResolver; // config is an instance of HttpConfiguration based on your hosting scenario

For other DI frameworks the approach is very similar. To see the full list of available NuGet packages, search for WebApiContrib.IoC in the NuGet gallery.

Implementing DependencyResolver Model in DI Frameworks

Now we look into implementing the DependencyResolver model for some of the popular dependency injection frameworks. The reason you might want to look into implementing the DependencyResolver model yourself is that you might have a custom DI framework or a special requirement or limitation—or you might just be interested in knowing details of the interoperability of DI frameworks with the ASP.NET Web API. Implementation normally results in two classes, one implementing IDependencyResolver and the other IDependencyScope.

Implementing DependencyResolver for AutoFac

Implementing DependencyResolver model in the AutoFac framework is pretty straightforward. AutoFac has a concept of a LifetimeScope that fits the ASP.NET Web API’s DependencyResolver model very well. Listing 14-1 shows this very concept used to implement IDependencyScope. This class expects ILifetimeScope as a constructor parameter.

Listing 14-1.  Using LifetimeScope to Implement IDependencyScope

public class AutoFacDependencyScope : IDependencyScope
{
    private readonly ILifetimeScope _lifetimeScope;

    public AutoFacDependencyScope(ILifetimeScope lifetimeScope)
    {
        _lifetimeScope = lifetimeScope;
    }

    public void Dispose()
    {
        _lifetimeScope.Dispose();
    }

    public object GetService(Type serviceType)
    {
        object instance = null;
        _lifetimeScope.TryResolve(serviceType, out instance);
        return instance;
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        object instance = null;
        var ienumerableType = typeof(IEnumerable<>).MakeGenericType(serviceType);
        _lifetimeScope.TryResolve(ienumerableType, out instance);
        return (IEnumerable<object>)instance;
    }
}

One thing to note is how AutoFac resolves multiple services. You need to ask for IEnumerable<> of the type you are interested in. Listing 14-1 made use of the MakeGenericType() method.

image Note  Please note that when resolving dependencies, null should be returned if the container cannot resolve the dependency. The default behavior in most containers is to throw an exception that should be handled by returning null. The reason is that ASP.NET Web API initially uses DependencyResolver to resolve the dependency. If null is returned, it uses other methods to resolve the dependency. Throwing an exception breaks the work flow.

Listing 14-2 shows the implementation of the IDependencyResolver. In BeginScope() it calls BeginLifetimeScope() to create an ILifetimeScope.

Listing 14-2.  Implementing the Dependency Resolver for AutoFac

public class AutoFacDependencyResolver : IDependencyResolver
{
    private readonly IContainer _container;

    public AutoFacDependencyResolver(IContainer container)
    {
        _container = container;
    }

    public void Dispose()
    {
        _container.Dispose();
    }

    public object GetService(Type serviceType)
    {
        object instance = null;
        _container.TryResolve(serviceType, out instance);
        return instance;
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        object instance = null;
        var ienumerableType = typeof (IEnumerable<>).MakeGenericType(serviceType);
        _container.TryResolve(ienumerableType, out instance);
        return (IEnumerable<object>) instance;
    }

    public IDependencyScope BeginScope()
    {
        return new AutoFacDependencyScope(_container.BeginLifetimeScope());
    }
}

In order to use the AutoFacDependencyResolver with our Web API project, all we have to do is set it to the DependencyResolver property of the configuration, as shown in Listing 14-3 (normally in Application_Start of the global.asax).

Listing 14-3.  Registering the AutoFac Dependency Resolver

var containerBuilder = new ContainerBuilder();
containerBuilder
    .RegisterType<TaxCalculator>()
    .As<ITaxCalculator>()
    .InstancePerLifetimeScope();

containerBuilder
    .RegisterType<ValuesController>()
    .As<ValuesController>();

GlobalConfiguration.Configuration.DependencyResolver =
    new AutoFacDependencyResolver(containerBuilder.Build());

Implementing DependencyResolver for Castle Windsor

Compared with other DI frameworks, Castle Windsor is unique. It differs from all others on a few levels. So if you decide to use it for your project and have used other frameworks, there are a few points to bear in mind.

First of all, it is the only framework that fully tracks your objects by default. If you are not careful, this can lead to memory leaks, and so it provides performance counters to help you identify such possibilities.

Because of the tracking, it also includes a concept that lets it release an object as well as resolve it. This is particularly useful if you have dependencies that implement IDisposable interface—for example, WCF client proxies. The Windsor container disposes of all disposable dependencies.

Another difference in the Castle Windsor framework is that by default, the lifetime of the registered components is singleton. Other frameworks have a default of transient. Yet another important matter is that the concept of a child container is completely different. In most other frameworks, a child container is one that has a shorter life span compared with the root container. In Castle Windsor, the child container does not display the same behavior, and so it is generally recommended not to be used.

In order to ensure that tracked components are released, we use a different technique: we keep track of the resolved dependencies and ask the container to release them at the time of disposing of the scope (see Listing 14-4).

Listing 14-4.  Implementing the Dependency Scope for Castle Windsor

public class WindsorDependencyScope : IDependencyScope
{

    protected readonly IWindsorContainer _container;
    private ConcurrentBag<object> _toBeReleased = new ConcurrentBag<object>();

    public WindsorDependencyScope(IWindsorContainer container)
    {
        _container = container;
    }

    public void Dispose()
    {
        if (_toBeReleased != null)
        {
            foreach (var o in _toBeReleased)
            {
                _container.Release(o);
            }
        }
        _toBeReleased = null;
    }

    public object GetService(Type serviceType)
    {
        if (!_container.Kernel.HasComponent(serviceType))
            return null;

        var resolved = _container.Resolve(serviceType);
        if (resolved != null)
            _toBeReleased.Add(resolved);
        return resolved;

    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        if (!_container.Kernel.HasComponent(serviceType))
            return new object[0];

        var allResolved = _container.ResolveAll(serviceType).Cast<object>();
        if (allResolved != null)
        {
            allResolved.ToList()
                .ForEach(x => _toBeReleased.Add(x));
        }
        return allResolved;

    }
}

As Listing 14-4 shows, we make sure the container contains the dependency before trying to resolve it to avoid throwing an exception. On the other hand, we use a thread-safe bag (an instance of ConcurrentBag<T>) to keep track of resolved dependencies and release them at the end.

The WindsorDependencyResolver is simpler, as Listing 14-5 illustrates.

Listing 14-5.  Implementing the Dependency Resolver for Castle Windsor

public class WindsorDependencyResolver : IDependencyResolver
{
    private readonly IWindsorContainer _container;

    public WindsorDependencyResolver(IWindsorContainer container)
    {
        _container = container;
    }

    public IDependencyScope BeginScope()
    {
        return new WindsorDependencyScope(_container);
    }

    public void Dispose()
    {
        _container.Dispose();
    }

    public object GetService(Type serviceType)
    {
        if (!_container.Kernel.HasComponent(serviceType))
            return null;

        return _container.Resolve(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        if (!_container.Kernel.HasComponent(serviceType))
            return new object[0];

        return _container.ResolveAll(serviceType).Cast<object>();
    }
}

As you see, we have not used the child container. As we said earlier, the Castle Windsor library by default keeps track of the dependencies resolved, and if care isn’t taken, this can lead to memory leaks, since the container will hang on to the resolved container until Release() gets called on the container.

Starting with version 3 of this library, a performance counter has been provided by the library to keep track of the unreleased components. This can be really handy to verify your implementation and make sure all is well and all tracked dependencies get released.

This performance counter is called “Instances tracked by the release policy”. You find it under the “Castle Windsor” category. This is not on by default, so you need some code to enable it:

var counter = LifecycledComponentsReleasePolicy.GetTrackedComponentsPerformanceCounter(
    new PerformanceMetricsFactory());
var diagnostic =
    LifecycledComponentsReleasePolicy.GetTrackedComponentsDiagnostic(container.Kernel);
container.Kernel.ReleasePolicy = new LifecycledComponentsReleasePolicy(diagnostic, counter);

Once the counter can be published, you need to run the Windows Performance Monitoring tool (perfmon.exe) and add the counter underneath the Castle Windsor category for your ASP.NET Web API host, as Figure 14-1 shows.

9781430247258_Fig14-01.jpg

Figure 14-1. Selecting the Castle Windsor performance counter in the Add Counter dialog

From the list of instances, select the process running your application, and click Add. Then press OK to close the dialog. After running your application and hitting your endpoint, you must see the counter value (see Figure 14-2).

9781430247258_Fig14-02.jpg

Figure 14-2. The Castle Windsor counter showing dependencies being released

As Figure 14-2 shows, there are occasional spikes of tracked dependencies, but the counter always returns to the baseline of 0. In other words, all tracked dependencies are released—and that is good news! There is more information on the library at the project’s website, and the library’s documentation is at http://docs.castleproject.org/Windsor.MainPage.ashx.

Implementing DependencyResolver for Unity

Unity, Microsoft’s own DI framework, is lightweight but contains some of the advanced features of other frameworks. In Unity you can use the concept of the child container to implement lifetime scope, as Listing 14-6 shows.

Listing 14-6.  Implementing the Dependency Scope for Unity

public class UnityDependencyScope : IDependencyScope
{
    protected readonly IUnityContainer _container;

    public UnityDependencyScope(IUnityContainer container)
    {
        _container = container;
    }

    public void Dispose()
    {
        _container.Dispose();
    }

    public object GetService(Type serviceType)
    {
        return _container.IsRegistered(serviceType) ?
            _container.Resolve(serviceType) :
            null;
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _container.IsRegistered(serviceType) ?
            _container.ResolveAll(serviceType) :
            new object[0];
    }
}

Creating the dependency resolver is also straightforward. Just create a child container and return (see Listing 14-7).

Listing 14-7.  Implementing the Dependency Resolver for Unity by Inheritance

public class UnityDependencyResolver : UnityDependencyScope, IDependencyResolver
{
    public UnityDependencyResolver(IUnityContainer container) : base(container)
    {
    }

    public IDependencyScope BeginScope()
    {
        return new UnityDependencyScope(_container.CreateChildContainer());
    }
}

Inheriting from the UnityDependencyScope helps to reuse much of the code you have.

Implementing DependencyResolver for NInject

Last but not least, we look into NInject. If you have read the previous codes, you probably have got the hang of implementing the DependencyResolver model. As with other frameworks, you need to start by implementing the dependency scope. Listing 14-8 shows how to take advantage of the fact that NInject always returns all resolvable types.

Listing 14-8.  Implementing the Dependency Scope for NInject

public class NInjectDependencyScope : IDependencyScope
{
    private IResolutionRoot _resolutionRoot;

    public NInjectDependencyScope(IResolutionRoot resolutionRoot)
    {
        _resolutionRoot = resolutionRoot;
    }

    public void Dispose()
    {
        var disposable = _resolutionRoot as IDisposable;
        if(disposable!=null)
            disposable.Dispose();
        _resolutionRoot = null;
    }

    public object GetService(Type serviceType)
    {
        return GetServices(serviceType).FirstOrDefault();
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        var request = _resolutionRoot.CreateRequest(serviceType, null,new IParameter[0], true, true);
        return _resolutionRoot.Resolve(request);
    }
}

Listing 14-9 uses the BeginBlock() to create a block analogous to the child container in Unity.

Listing 14-9.  Implementing the Dependency Resolver for Ninject Using Inheritance

public class NInjectDependencyResolver : NInjectDependencyScope, IDependencyResolver
{
    private IKernel _kernel;

    public NInjectDependencyResolver(IKernel kernel) : base(kernel)
    {
        _kernel = kernel;
    }

    public IDependencyScope BeginScope()
    {
        return new NInjectDependencyScope(_kernel.BeginBlock());
    }
}

Summary

In the journey we took in this chapter, you briefly got to see the difference between Inversion of Control (IoC), dependency injection (DI), and the Service Locator and Factory patterns. You also got to see how they are related.

You then looked at how these concepts and techniques are used in ASP.NET Web API and learned that it uses the Service Locator pattern to resolve dependencies. Then the DependencyResolver model and its two main interfaces, IDependencyScope and IDependencyResolver, were explored.

At the end, you were shown how to use existing libraries built on top of the ASP.NET Web API DependencyResolver model. Finally, this model was implemented for several popular frameworks: AutoFac, Castle Windsor, Unity, and NInject.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.51.157