Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Ingredients for Well-Designed OWIN Middleware Components (Part 2)

DZone's Guide to

Ingredients for Well-Designed OWIN Middleware Components (Part 2)

Learn more about separating the OWIN pipeline construction from the middleware definition.

· Integration Zone ·
Free Resource

The new Gartner Critical Capabilities report explains how APIs and microservices enable digital leaders to deliver better B2B, open banking and mobile projects.

In my last post, I talked about naming conventions and reducing the number of public dependencies, the first two ingredients of a recipe for well-designed OWIN middleware components. In this post, I'm going to talk about separating the OWIN pipeline construction from the middleware definition.

Ingredient 3: Keeping Your Pipeline Construction Clean

The first version of the UsePiercer extension method, before I added the settings argument, looked something like this:

 public static IAppBuilder UsePiercer(this IAppBuilder appBuilder)
{
  HttpConfiguration configuration = BuildHttpConfiguration();

  appBuilder.Map("/api", a => a.UseWebApi(configuration));

  return appBuilder;
}

IAppBuilder is defined by the Owin package, but that Map method is an extension method defined in Microsoft.Owin, part of Microsoft's Katana project. Since IAppBuilder is on that public method, you can't internalize it. Your package will need to retain a dependency on the Owin package. Microsoft.Owin however, is only used within that method. Merging it in your assembly sounds like a smart thing to do.

However, without discussing the intricacies of AppFuncs and MidFuncs, it suffices to know that when the OWIN host is finalizing the construction of the OWIN pipeline (by calling the Build method of AppBuilder), some magic conversion happens between a hidden AppBuilder (which is Microsoft's implementation of IAppBuilder) to an Owin MidFunc. If you merge Microsoft.Owin into your assembly, your host won't be able to find the conversion and some weird InvalidCastException will happen. You can solve that by separating the act of adding middleware to the IAppBuilder from the construction of the middleware itself. In Piercer I used this construction:

 public static IAppBuilder UsePiercer(this IAppBuilder appBuilder)
{
  appBuilder.Use(Middleware.Create(settings));
  return appBuilder;
}

Where the Middleware class returns a MidFunc:

 public static Func Create()
{
  return next =>
  {
    var appBuilder = new AppBuilder();
    
    HttpConfiguration configuration =
      BuildHttpConfiguration(settings);

    appBuilder.Map(settings.Route, a => a.UseWebApi(configuration));
    appBuilder.Run(ctx => next(ctx.Environment));

    return appBuilder.Build();
  };
}

I understand that it might be a bit difficult to read (although the functional guys love this stuff ). The point is that you force this magic conversion from a nested AppBuilder to the MidFunc even before you add the middleware to the pipeline. If you take this approach, you can safely merge Microsoft.Owin into your main assembly.

The new Gartner Critical Capabilities for Full Lifecycle API Management report shows how CA Technologies helps digital leaders with their B2B, open banking, and mobile initiatives. Get your copy from CA Technologies.

Topics:
OWIN ,middleware ,.net ,architecture ,integration

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}