I am trying to understand OWIN and Katana.. sure, it's cool that the application can be self-hosted or can be hosted on Nancy or on non-IIS. The reason for this question is we want to create a web application using MVC5 (VS 2013), which will be hosted on IIS in Windows Azure.
However, we received a recommendation to use OWIN middleware components/packages in mvc5 application to get the benefits of pluggable architecture, performance, etc.
I would like to understand how there will be a performance gain if we use OWIN middleware in MVC5 application, which will be hosted on IIS in Windows Azure. Will my application skip alot of unnecessary things in the IIS pipe by using owin middleware packages? Are there any other benefits that I can get by using OWIN in MVC5, when it is hosted on IIS?
Yes, you will potentially be able to skip a lot of unnecessary things in the pipeline, as you will define the components in the pipeline, along with using other components not necessarily made by you, that your application will use. These components are middleware, because they sit in the middle of the processing pipeline and the components can decide to pass control on to the next component in the pipeline via the async/await
C# syntax or end the processing at that component.
The AppFunc
object is where the "magic" happens in Katana, because it is the logic that a component uses when it is invoked, the signature is this:
Func<IDictionary<string, object>, Task>;
Note: The IDictionary<string, object>
represents the environment values (such as Request
and Response
; think HttpContext
in ASP.NET) and the OWIN standard defines certain values that must exist in this dictionary, such as "owin.RequestBody"
or "owin.ResponseBody"
. Katana is Microsoft's implementation of the OWIN standard and as such has these, and other, dictionary items available out-of-the-box.
An example of a component would be a method that matches the signature of AppFunc
(which is Func<IDictionary<string, object>, Task>
, like this:
public async Task Invoke(IDictionary<string, object> environment)
{
// Do processing...
// Wait for next component to complete
await _nextComponent(environment);
// Do more processing...
}
Note: OWIN expects the method to return a Task
or generate an exception, so return null;
would be invalid.
So how do you know what the next component will be?
The constructor of your component needs to accept a parameter of Func<IDictionary<string, object>, Task>
, like this:
public class HelloWorldCOmponent
{
Func<IDictionary<string, object>, Task> _next;
public HelloWorldComponent(Func<IDictionary<string, object>, Task> next)
{
_next = next;
}
public async Task Invoke(IDictionary<string, object> environment)
{
// Do something
// Wait for next component to return
await _next(environment);
}
}