7

I'm currently building a library that contains several OWIN-middlewares. These middlewares should be executed in a certain order. In one of the first releases of OWIN, there was the IAppBuilder interface. However the IAppBuilder is not part of OWIN anymore, but part of Microsoft.Owin. I don't want to force my user(s) to have a dependency on Microsoft.Owin.

What is the preferred way of adding middlewares to the OWIN-pipeline without using Microsoft.Owin?

Jeroen
  • 1,212
  • 10
  • 24
  • 1
    maybe this helps you: https://visualstudiomagazine.com/articles/2015/05/01/inject-custom-middleware.aspx – Rumpelstinsk Mar 21 '17 at 06:59
  • Thanks, but unfortunately it doesn't. This example is using the IApplicationBuilder interface that is also not a part of OWIN. – Jeroen Mar 22 '17 at 12:12

1 Answers1

0

It took some time, but I think I figured it out.

First the definitions as specified by Owin:

public delegate Task AppFunc(IDictionary<string, object> environment);

public delegate AppFunc MidFunc(AppFunc next);

public delegate MidFunc MidFactory(IDictionary<string, object> startupProperties);

public delegate void BuildFunc(MidFactory midFactory);

I use delegate here to avoid the generics madness.

To go from IAppBuilder to BuildFunc:

public static BuildFunc UseOwin(this IAppBuilder builder)
{
    return middleware => builder.Use(middleware(builder.Properties));
}

In order to build a pipeline using BuildFunc, you can create an extension on BuildFunc:

public static BuildFunc UseMyFramework(this BuildFunc buildFunc)
{
    buildFunc(startupProperties => BuildPipeline(startupProperties));

    return buildFunc;
}

It is a good practice to return the BuildFunc for chaining.

Building the pipeline is nothing more than linking the MidFuncs together and optionally end with the actual AppFunc:

public static MidFunc BuildPipeline(IDictionary<string, object> startupProperties)
{
    return next => LogMiddleware(AuthenticateMiddleware(MyApplication));

    // Or this if you don't supply your own AppFunc
    return next => LogMiddleware(AuthenticateMiddleware(next));
}

public static AppFunc LogMiddleware(AppFunc next)
{
    AppFunc middleware = async environment =>
    {
        // Log request

        await next(environment);
    };

    return middleware;
}

public static AppFunc AuthenticateMiddleware(AppFunc next)
{
    AppFunc middleware = async environment =>
    {
        // authenticate request

        await next(environment);
    };

    return middleware;
}

public static async Task MyApplication(IDictionary<string, object> environment)
{
    await Task.CompletedTask;
}

You still need to connect the Owin implementation to your framework. I use Microsoft.Owin for this:

app.UseOwin().UseMyFramework()
Jeroen
  • 1,212
  • 10
  • 24