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?
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 MidFunc
s 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()