Yesterday, a preview of the .NET Azure Mobile Services has been released. Despite the fact that I’d rather see a scripted C# support π - I am still very excited about this new .NET support, as ZUMO is one of my favorite Azure offerings.
The whole thing is in preview right now and runs on Web API (version 5.1 at the moment, so not the latest) but the team has made several very smart decisions, which I am sure the community will welcome with open arms. One of them is the ability to plug in your OWIN pipeline!
Access to OWIN pipeline in Azure Mobile Services π
While going with Web API gives you a ton of great integrated features, you can entirely opt out from Web API (!) and roll out your own OWIN pipeline.
Access to OWIN is tremendously powerful, as you could also still run Web API and take advantages of all its built in features (authentication, push notifications and whatnot) but also use some other framework side by side. I expressed the same thoughts to Henrik when this was first discussed with the community, and I am really happy to see this in ZUMO.
There are a couple of ways to go about it - this whole thing is brand new and these features are (at least to my knowledge) undocumented at the moment, so are a result of my hacking and slashing - and ultimately maybe there is an even better way to do it. For this samples I simply created a new .NET based ZUMO services, and downloaded the pre-generated project to my lcoal machine. It has sample things like a ToDoItemController wired up as a sample.
Option 1, brute force π
A static StartupOwinAppBuilder gives oyu access to IAppBuilder. So, in the Global.asax add:
Microsoft.WindowsAzure.Mobile.Service.
Config.StartupOwinAppBuilder.Initialize(app => app.UseNancy());
You also should get rid of all the code under WebApiConfig.Register.
This is equivalent to saying, get out of my way, this is my pipeline - I am going to use that. From now on your Azure Mobile Service is running this particular pipeline.
Option 2, finesse π
Lots of the configuration and setup classes in .NET Azure Mobile Services require Web API HttpConfiguration which makes it a bit difficult to pass things around. This is understandable, since it’s been built for and around Web API. However there are still some hooks that allow you to plug in things into the OWIN pipeline.
First of all, let’s create a custom IOwinAppBuilder, which is a ZUMO class resposible for building the pipeline.
public class CustomOwinAppBuilder : OwinAppBuilder
{
public CustomOwinAppBuilder(HttpConfiguration config) : base(config)
{
}
public override void Configuration(IAppBuilder appBuilder)
{
appBuilder.UseNancy(options =>
options.PerformPassThrough = context =>
context.Response.StatusCode == HttpStatusCode.NotFound);
base.Configuration(appBuilder);
}
}
We want to call base, because we want the fully fledged ZUMO experience, but I also want Nancy, so I add it. Now, the next steps are crucial - it’s a bit of a chicken and egg situation, and I’ll try to explain why.
ZUMO uses Autofac out of the box, so we’d like to register CustomOwinAppBuilder as the default IOwinAppBuilder. We can do it using the constructor of ConfigBuilder. However, the constructor of CustomOwinAppBuilder requires a properly setup HttpConfiguration which is created from ConfigBuilder!
So here’s how we can work around this vicious circle. We’ll create a default ConfigBuilder instance, use it to create a default HttpConfiguration for Web API. Then, we’ll create a new ConfigBuilder and in its constructor override the Autofac registration of IOwinAppBuilder - at that point we can do it, since we obtained the default HttpConfiguration already.
And that’s pretty much that. The code is shown below:
public static class WebApiConfig
{
public static void Register()
{
var options = new ConfigOptions();
var defaultBuilder = new ConfigBuilder(options);
var defaultConfig = ServiceConfig.Initialize(defaultBuilder);
defaultConfig.Routes.MapHttpRoute("Default", "api/{controller}/{id}", new { id = RouteParameter.Optional });
var configBuilder = new ConfigBuilder(options, autofac => autofac.RegisterInstance(new CustomOwinAppBuilder(defaultConfig)).As<IOwinAppBuilder>());
var config = ServiceConfig.Initialize(configBuilder);
configBuilder.ConfigureOwin(config);
Database.SetInitializer(new filipInitializer());
}
}
If I now throw in a NancyModule alongisde the default Web API controller that was generated for me I can access both frameworks, side by side, in Azure Mobile Services!
public class IndexModule : NancyModule
{
public IndexModule()
{
Get["/"] = x => "Hello from Nancy in Mobile Services";
}
}
And you can go and deploy this to ZUMO like that.