Owin.Dependencies: An IoC Container Adapter Into OWIN Pipeline

Owin.Dependencies is an IoC container adapter into OWIN pipeline. This post will walk you through the Autofac IoC container implementation and ASP.NET Web API framework adapter for OWIN dependencies.
6 September 2013
6 minutes read

Related Posts

Update on 2013-11-05:

The project has been renamed from Owin.Dependencies to DotNetDoodle.Owin.Dependencies.

Dependency inject is the design pattern that most frameworks in .NET ecosystem have a first class support: ASP.NET Web API, ASP.NET MVC, ASP.NET SignalR, NancyFx and so on. Also, the most IoC container implementations for these frameworks allow us to have a per-request lifetime scope which is nearly always what we want. This's great till we stay inside the borders of our little framework. However, with OWIN, our pipeline is much more extended. I have tried to give some insight on OWIN and its Microsoft implementation: Katana. Also, Ali has pointed out some really important facts about OWIN on his post. Flip also has really great content on OWIN. Don't miss the good stuff from Damian Hickey on his blog and his GitHub repository.

Inside this extended pipeline, the request goes through several middlewares and one of these middlewares may get us into a specific framework. At that point, we will be tied to framework's dependency injection layer. This means that all of your instances you have created inside the previous middlewares (assuming you have a different IoC container there) basically are no good inside your framework's pipeline. This issue had been bitten me and I was searching for a way to at least work around this annoying problem. Then I ended up talking to @randompunter and the idea cam out:

Actually, the idea is so simple:

  • Have a middleware which starts a per-request lifetime scope at the very beginning inside the OWIN pipeline.
  • Then, dispose the scope at the very end when the pipeline ends.

This idea made me create the Owin.Dependencies project. Owin.Dependencies is an IoC container adapter into OWIN pipeline. The core assembly just includes a few interfaces and extension methods. That's all. As expected, it has a pre-release NuGet package, too:

PM> Install-Package DotNetDoodle.Owin.Dependencies -Pre

Besides the Owin.Dependencies package, I have pushed two different packages and I expect more to come (from and from you, the bright .NET developer). Basically, we have two things to worry about here and these two parts are decoupled from each other:

  • IoC container implementation for Owin.Dependencies
  • The framework adapter for Owin.Dependencies

The IoC container implementation is very straightforward. You just implement two interfaces for that: IOwinDependencyResolver and IOwinDependencyScope. I stole the dependency resolver pattern that ASP.NET Web API has been using but this may change over time as I get feedback. My first OWIN IoC container implementation is for Autofac and it has a seperate NuGet package, too:

PM> Install-Package DotNetDoodle.Owin.Dependencies.Autofac -Pre

The usage of the OWIN IoC container implementation is very simple. You just need to have an instance of the IOwinDependencyResolver implementation and you need to pass that along the UseDependencyResolver extension method on the IAppBuilder interface. Make sure to call the UseDependencyResolver before registering any other middlewares if you want to have the per-request dependency scope available on all middlewares. Here is a very simple Startup class after installing the Owin.Dependencies.Autofac package:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        IContainer container = RegisterServices();
        AutofacOwinDependencyResolver resolver = new AutofacOwinDependencyResolver(container);

        app.UseDependencyResolver(resolver)
            .Use<RandomTextMiddleware>();
    }

    public IContainer RegisterServices()
    {
        ContainerBuilder builder = new ContainerBuilder();

        builder.RegisterType<Repository>()
                .As<IRepository>()
                .InstancePerLifetimeScope();

        return builder.Build();
    }
}

After registering the dependency resolver into the OWIN pipeline, we registered our custom middleware called "RandomTextMiddleware". This middleware has been built using a handy abstract class called "OwinMiddleware" from Microsoft.Owin package. The Invoke method of the OwinMiddleware class will be invoked on each request and we can decide there whether to handle the request, pass the request to the next middleware or do the both. The Invoke method gets an IOwinContext instance and we can get to the per-request dependency scope through the IOwinContext instance. Here is the code:

public class RandomTextMiddleware : OwinMiddleware
{
    public RandomTextMiddleware(OwinMiddleware next)
        : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
        IOwinDependencyScope dependencyScope = 
            context.GetRequestDependencyScope();
            
        IRepository repository = 
            dependencyScope.GetService(typeof(IRepository)) 
                as IRepository;

        if (context.Request.Path == "/random")
        {
            await context.Response.WriteAsync(
                repository.GetRandomText()
            );
        }
        else
        {
            context.Response.Headers.Add(
                "X-Random-Sentence", 
                new[] { repository.GetRandomText() });
                
            await Next.Invoke(context);
        }
    }
}

I accept that we kind of have an anti-pattern here: Service Locator. It would be really nice to get the object instances injected as the method parameters but couldn't manage to figure out how to do that for now. However, this will be my next try. Here, we get an implementation of the IRepository and it is disposable. When we invoke this little pipeline now, we will see that the disposition will be handled by the infrastructure provided by the Owin.Dependencies implementation.

image

So far so good but what happens when we need to integrate with a specific framework which has its own dependency injection implementation such as ASP.NET Web API? This is where the framework specific adapters come. I provided the APS.NET Web API adapter and it has its own NuGet package which depends on the Microsoft.AspNet.WebApi.Owin package.

PM> Install-Package DotNetDoodle.Owin.Dependencies.Adapters.WebApi -Pre

Beside this package, I also installed the Autofac.WebApi5 pre-release package to register the API controllers inside the Autofac ContainerBuilder. Here is the modified Startup class to integrate with ASP.NET Web API:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        IContainer container = RegisterServices();
        AutofacOwinDependencyResolver resolver = 
            new AutofacOwinDependencyResolver(container);

        HttpConfiguration config = new HttpConfiguration();
        config.Routes.MapHttpRoute("DefaultHttpRoute", "api/{controller}");

        app.UseDependencyResolver(resolver)
           .Use<RandomTextMiddleware>()
           .UseWebApiWithOwinDependencyResolver(resolver, config);
    }

    public IContainer RegisterServices()
    {
        ContainerBuilder builder = new ContainerBuilder();

        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
        builder.RegisterType<Repository>()
               .As<IRepository>()
               .InstancePerLifetimeScope();

        return builder.Build();
    }
}

I also added an ASP.NET Web API controller class to serve all the texts I have. As ASP.NET Web API has a fist class DI support and our Web API adapter handles all the things for us, we can inject our dependencies through the controller constructor.

public class TextsController : ApiController
{
    private readonly IRepository _repo;

    public TextsController(IRepository repo)
    {
        _repo = repo;
    }

    public IEnumerable<string> Get()
    {
        return _repo.GetTexts();
    }
}

Now, when we send a request to /api/texts, the IRepository implementation is called twice: once from our custom middleware and once from the Web API's TextsController. At the end of the request, the instance is disposed.

image

The source code of this sample is available in the Owin.Dependencies repository on GitHub. I agree that there might be some hiccups with this implementation and I expect to have more stable solution in near future. Have fun with this little gem and give your feedback :)