Saturday, April 18, 2015

How to create your own Katana middleware component - at the metal


//using a C like typedef alias for the Func() inside the class file
using AppFunc = Func<IDictionary<string,object>,Task>();

In the Configuration method of Statup, use my OWIN Katana component

public void Configuration(IAppBuilder app)
{
       app.Use<MyOwinComponent>();
}


// My lowest level OWIN component
public class MyOwinComponent
{
        //Required to pass processing on to the next OWIN component
       AppFunc _next;

       public MyOwinComponent(AppFunc next)
      {
             _next = next;
       }
        
       // If not using await, remove the async keyword   
       //This method should match the AppFunc signature
       public async Task Invoke(IDictionary<string,object> environment)
       {
                var response = environment["owin.ResponseBody"] as Stream;
                using( var writer = new StreamWriter(response))
                {
                      return await writer.WriteAsync("Hello from my Owin Component!");
                 }


                //Example await next component and pass along the dictionary 
                // await _next(environment);
       }
}

We can also add syntactic sugar to this so we can specify in configuration method as

              app.UseMyOwinComponent();

by creating an extension method like so

public static class AppBuilderExtensions
{
        public static void UseMyOwinComponent(this IAppBuilder app)
        {
               app.Use<MyOwinComponent>();
         }


******************************************************************

NOTE: Katana provides higher abstractions using app.Run or app.Use with its overloaded functions to write our middleware components, and we should actually use that.

For instance, using just a lambda expression

         app.Use( async (environment, next) =>
         {
                 Console.Write("Requesting: " + environment.Request.Path);

                  await next();

                Console.Write("Response: " + environment.Response.StatusCode);
          }

          app.UseMyOwinComponent();


No comments:

Post a Comment