left-icon

ASP.NET Multitenant Applications Succinctly®
by Ricardo Peres

Previous
Chapter

of
A
A
A

CHAPTER 8

OWIN

OWIN


Introduction

The Open Web Interface for .NET (OWIN) is a Microsoft specification that defines a contract for .NET applications to interact with web servers. This includes the pipeline for execution of HTTP requests and contracts for services to sit in between (middleware). It also happens to be the basis for the upcoming ASP.NET 5.

OWIN allows you to decouple your service application from any particular web server, such as IIS. Although it can use IIS, it can also be self-hosted (like WCF) through OWIN’s web server implementation, OwinHttpListener.

You will need to add a reference to the Microsoft.Owin.Host.HttpListener NuGet package:

Installing the HttpListener NuGet package

  1. Installing the HttpListener NuGet package

Why should we care with OWIN? Well, for once, it gives you a consistent pipeline that is more aligned with the way ASP.NET will be in the near future: no more Web Forms—MVC will be configured through OWIN!

Note: For a good introduction to OWIN, check out the book OWIN Succinctly, by Ugo Lattanzi and Simone Chiaretta, also in the Succinctly collection.

Registering services

The OWIN pipeline starts with a call to a method called Configuration of a class called Startup. This is by convention; there is no base class or interface that dictates this, and both the class and method can even be static. If we want to change this bootstrap method, we can do so by adding an OwinStartupAttribute at the assembly level or a “owin:appStartup” entry to the Web.config’s appSettings section. Here we register a middleware component that in return, will register all our services (like tenant identification and registration):

Code Sample 82

public static class Startup

{

     public static void Configuration(IAppBuilder builder)

     {

          builder.UseStaticFiles();

          builder.UseDefaultFiles();

          //rest goes here

          builder.Use<MultitenancyMiddleware>();

          //rest goes here

     }

}

The middleware class inherits from OwinMiddleware—there are other options, but this is my favorite one. A middleware class receives in its constructor a pointer to the next middleware in the pipeline, and should return the result of its invocation in its Invoke method.

An example:

Code Sample 83

public class MultitenancyMiddleware : OwinMiddleware

{

     public MultitenancyMiddleware(OwinMiddleware next) : base(next) {     }

 

     public override Task Invoke(IOwinContext context)

     {

          //services registration

          context.Set<ITenantLocationStrategy>(

               typeof(ITenantLocationStrategy).FullName, 

               new MefTenantLocationStrategy(

                    typeof(Common.ContextRepository).Assembly));

          context.Set<ITenantIdentifierStrategy>(

               typeof(ITenantIdentifierStrategy).FullName, 

               new HostHeaderTenantIdentifierStrategy());

          context.Set<IConfiguration>(

               typeof(IConfiguration).FullName, 

               new AppSettingsConfiguration());   

          //rest goes here

          return this.Next.Invoke(context);

     }

}

Note: Right now, you cannot use OWIN with ASP.NET MVC or Web Forms, because these depend on the System.Web.DLL, the core of the ASP.NET framework, but ASP.NET MVC 6 will work on top of OWIN.

So, if you are to use OWIN, and you need to resolve one of our bootstrap services, you can either stick with your choice of IoC container and Common Service Locator, or you can use OWIN’s internal implementation:

Code Sample 84

public override Task Invoke(IOwinContext context)

{

     var tls = context.Get<ITenantLocationStrategy>(

          typeof(ITenantLocationStrategy).FullName);

     return this.Next.Invoke(context);

}

OWIN also supports ASP.NET Identity for authentication. Just add NuGet package Microsoft.AspNet.Identity.Owin and make any changes to the added classes:

ASP.NET Identity package for OWIN

  1. ASP.NET Identity package for OWIN

Web API

Unlike MVC, Web API can be used with OWIN. You will need to register an implementation, such as the one provided by the Microsoft NuGet package Microsoft.AspNet.WebApi.Owin:

Web API OWIN package

  1. Web API OWIN package

Then you will need to register the Web API service in the aforementioned Configuration method, using the UseWebApi extension method:

Code Sample 85

public static class Startup

{

     public static void Configuration(IAppBuilder builder)

     {

          builder.UseWebApi(new HttpConfiguration());

          //rest goes here

     }

}

Replacing System.Web

OWIN came into being because of the desire to replace the System.Web architecture. One key class in System.Web is HttpContext, which no longer exists in OWIN. This poses a problem: our interfaces that were introduced earlier, namely ITenantIdentifierStrategy, rely on classes that are part of System.Web, so we need to figure out how we can achieve the same results without it. The OWIN pipeline is significantly simpler than ASP.NET; it follows a pattern known as Chain of Responsibility, where each stage (called middleware) in the pipeline calls the next one, eventually doing something before and after that. So, if we want to make available  some services to the other, we need to do it in the first stage:

Code Sample 86

public class OwinHostHeaderTenantIdentifierStrategy : OwinMiddleware

{

     public OwinHostHeaderTenantIdentifierStrategy(OwinMiddleware next):

          base(next) { }

 

     public override Task Invoke(IOwinContext context)

     {

          context.Request.Environment["Tenant"] =         TenantsConfiguration.GetTenants().Single(x =>         x.Name == context.Request.Host.Value.Split(':')

                         .First().ToLower());

 

          return this.Next.Invoke(context);

     }

}

The equivalent of the HttpContext in OWIN is the implementation of the IOwinContext interface: it has Request and Response objects, plus a couple of other useful methods and properties. In this example, we are storing the current tenant, as identified by the host header, in an environment variable (the Environment collection). OWIN does not dictate how to do it, so please feel free to do it any way you prefer. The important thing is that this middleware needs to be inserted on the pipeline before anything else that might need it:

Code Sample 87

public static class Startup

{

     public static void Configuration(IAppBuilder builder)

     {

          builder.UseWebApi(new HttpConfiguration());

          builder.UseStaticFiles();

          builder.UseDefaultFiles();

          //rest goes here

          builder.Use<MultitenancyMiddleware>();

          builder.Use<OwinHostHeaderTenantIdentifierStrategy>();

          //rest goes here

     }

}

Unit testing

In order to unit test an OWIN setup, we may need to inject a couple of properties, such as the current host, so that it can be caught by our implementation of the Host header strategy:

Code Sample 88

public static void Setup(this IOwinContext context)

{

     context.Request.Host = new HostString("abc.com");

}

Other strategies don’t need any particular setup.

Scroll To Top
Disclaimer
DISCLAIMER: Web reader is currently in beta. Please report any issues through our support system. PDF and Kindle format files are also available for download.

Previous

Next



You are one step away from downloading ebooks from the Succinctly® series premier collection!
A confirmation has been sent to your email address. Please check and confirm your email subscription to complete the download.