Why isn't OWIN middleware implemented as some kind of interface or abstraction class?
I can't figure out why the first parameter in an IAppBuilder Use(object middleware, params object[] args);
interface method IAppBuilder
doesn't require the implementation of any interface, but a simple object ?!
I was expecting something like this
public interface IMiddleWare
{
public void Invoke(IOwinContext context)
}
and
IAppBuilder Use(IMiddleware middleware, params object[] args);
After all, this middleware has to be executed at some point, so what and how can you name it if it's just an object ?!
Also, if the middleware was some kind of interface, the following code would not be available
public class SomeStupidMiddleWare
{
public void SomeMethod1()
{
Console.WriteLine("method1");
}
public void SomeMethod2()
{
Console.WriteLine("method2");
}
}
class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use(new SomeStupidMiddleWare());
}
}
But now this code compiled successfully but generates a runtime error The type 'OwinEducation.SomeStupidMiddleWare' does not match any known middleware pattern
I seem to have found the answer. As stated here Katana supports 4 different conditional templates for adding middlewares
- Delegation pattern
- Instance template
- Generator / Nested Delegate Template
- Constructor type or type pattern
Delegation Pattern The Delegation Pattern takes the following delegate as the first parameter to the IAppBuilder using method and any number of additional parameters of any type
Func<AppFunc, AppFunc>
Instance Instance To use this pattern to add middlewares, we need new types with the following two methods.
public void Initialize(AppFunc next, params object[] args);
public Task Invoke(IDictionary<string, object> environment);
Generator / Nested Delegate Template To use this template to create middlewares, we need a new type with the following method.
public AppFunc Invoke(AppFunc next, params object[] args);
Type / Type Pattern constructor A type with the following constructor and method can be added middleware using this pattern
public Ctor(AppFunc next, params object[] args);
public Task Invoke(IDictionary<string, object> env);
So IMHO, given that these cases have nothing to do, so the middleware is object
in the method Use
and we cannot create some kind of common interface for all of them
The OwinMiddleware class is provided by Microsoft to easily implement custom middleware with their OWIN server (Katana) implementation, but OWIN is not a Microsoft technology. By using middleware as an object, Katana can use non-Katana middleware that does not inherit from OwinMiddleware.
This blog post goes into more detail about signing and middleware embedding. The most important bit of information is that the only requirement is to sign a signature
Func<IDictionary<string, object>, Task
You can also check the OWIN site and specifically the Application Delegates section