OWIN and Katana part 2: the Application Function

Introduction

In the previous post of this series we started looking into OWIN and Katana. We also looked at a small, very basic Console based web server to see them in action.

We’ll continue digging into how these technologies work. We’ll build upon the demo application we started working on in the previous post so have it ready in Visual Studio.

The Application Function

The application function, or AppFunc is a tool that defines how elements process incoming HTTP requests to the server. It provides a delegate which returns a Task and accepts an IDictionary of string and object. We saw an example of such a Func in the first post of this series. The dictionary represents the request environment. Recall the Environment property of the IAppBuilder interface which is also of the same dictionary type. We also said that this structure is characteristic of OWIN as it lacks any higher level abstraction. It is not a dictionary of, say, RequestParameter and RequestKey with built-in properties which we could expect in a built-in object oriented .NET class. This particular dictionary includes all types of data about the request from and the response to the client: headers, cookies, server variables etc.

The application function delegate always returns a Task to adhere to the asynchronous programming model of modern .NET applications. At this point you should be familiar with the await-async keywords in C#. If not, then start here.

You’ll probably notice that this is quite low-level programming compared to writing a “normal” ASP.NET web application where you get all HTTP related tasks for free from the System.Web library and IIS as the default server. In OWIN you are free to build all components required to fulfil a request. The components will be independent from each other but still able to work together in a decoupled fashion. One component may check the request headers, another one the authentication cookies etc. Every component will have an application function that can be invoked externally. The components form a chain of actions where each component calls upon the next component’s application function in the pipeline using the data in the Environment dictionary mentioned above. As the dictionary object only contains strings and objects the chain remains very loosely coupled.

Demo

Open the console web server we started working on previously in Visual Studio. If you recall then we tested two methods of IAppBuilder: UseWelcomePage and Run. We’ll try something different this time. Add a new class to the solution called WelcomeComponent. Our goal is to write some greeting to every request at a lower level than we did previously. The class will need to come in contact with the IAppBuilder somehow. We’ll need to add a method that matches the Func delegate signature of AppFunc. Insert the following method stub into WelcomeComponent:

public Task Invoke(IDictionary<string, object> environment)
{
    throw new NotImplementedException();
}

Locate Startup.Configuration, comment out the call to appBuilder.UseWelcomePage and insert the following call instead:

appBuilder.Use<WelcomeComponent>();

The Use method will insert a component into the OWIN pipeline. Run the application and you should get an exception: MissingMethodException. The compiler is testing the OWIN components that you wired up using Reflection. If it finds any missing element it will tell you about it. In this case the error message says that “WelcomeComponent does not have a constructor taking 1 argument”. That argument is the AppFunc for the next component in the invocation chain. By now we know what an AppFunc delegate looks like so insert the following constructor stub:

public WelcomeComponent(Func<IDictionary<string, object>, Task> appFunc)
{
}

As an aside: there’s a little trick to make this constructor more concise. Add the following using statement underneath the others:

using ApplicationFunction = System.Func<System.Collections.Generic.IDictionary<string, object>, System.Threading.Tasks.Task>;

…the constructor becomes…:

public WelcomeComponent(ApplicationFunction appFunc)
{
}

The incoming appFunc variable represents the next component in the component chain. Add the following private field to the class:

private readonly ApplicationFunction _nextComponent;

…and so the constructor will look like the following:

public WelcomeComponent(ApplicationFunction appFunc)
{
	if (appFunc == null) throw new ArgumentNullException("AppFunc of next component");
	_nextComponent = appFunc;
}

We’ll also implement the Invoke method in a simplistic way:

public async Task Invoke(IDictionary<string, object> environment)
{
	await _nextComponent(environment);
}

So we await the next component and pass along the incoming environment variable to its constructor, just like the way how WelcomeComponent would be called in the pipeline.

A short aside: the Invoke method must be called Invoke, so I didn’t just pick this name. Change the method to something else, like MickeyMouse and then run the application. You should get a System.ArgumentException complaining about a conversion error.

Rename the method to ‘Invoke’. Add a breakpoint within the Invoke method and run the application. You should see a console window with the message that the web server has started. Navigate to localhost:7990 in a web browser and code execution should stop at the break point. Hover over the incoming ‘environment’ variable with the mouse to inspect its contents. In particular take a look at what’s available in the dictionary:

AppFunc dictionary contents

So there are 29 keys and 29 values – this number may change in future updates to the OWIN-related assemblies. Looking through the key names it will be clear immediately that it’s possible to extract just about any information related to the HTTP request: path, headers, request method, request body etc. This environment variable will make sure that the HTTP request properties will be available to every component in the chain. Some of them are actually specified as compulsory elements by the OWIN specification.

You can in fact stop the invocation chain right here and return a response to the caller already now. In that case you’ll need to access the “owin.ResponseBody” dictionary element. Stop the application and comment out the await statement in the Invoke method. The response body will be a Stream so we’ll extract it from the environment dictionary as follows:

Stream responseBody = environment["owin.ResponseBody"] as Stream;

We then construct a StreamWriter out of this and write to the response stream:

using (StreamWriter responseWriter = new StreamWriter(responseBody))
{
	return responseWriter.WriteAsync("Hello from the welcome component");
}

Remove the ‘async’ from the method declaration as the WriteAsync method already returns a Task. Run the application and navigate to localhost:7990 in a browser. You should see the plain message we provided above to the WriteAsync method. This was in fact a very low level Katana component, probably the lowest level possible.

The methods we tested with IAppBuilder, i.e. Run and UseWelcomePage, use the same technique behind the scenes. They are simply wrappers around a much more elaborate Invoke method.

We can make it so that our glorious implementation of the Invoke method becomes available to other programmers using an extension method. Add a new class to the project called AppBuilderExtensions:

public static class AppBuilderExtensions
{
	public static void UseWelcomeComponent(this IAppBuilder appBuilder)
	{
		appBuilder.Use<WelcomeComponent>();
	}
}

We can call this extension method in Startup.Configuration as follows:

appBuilder.UseWelcomeComponent();

This produces the same behaviour as before, just with a little nicer syntax. You’ll notice that the UseWelcomeComponent method call looks very much like UseWelcomePage – the implementation of the latter is probably slightly more involved however.

Components in OWIN are also called middleware as they sit in the middle of the processing pipeline. We’ll keep looking at OWIN middleware in the next post.

View the list of MVC and Web API related posts here.

Advertisements

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

4 Responses to OWIN and Katana part 2: the Application Function

  1. Pingback: Dev.Cast 71 – OWIN och Katana

  2. Pingback: نگاهی بر Katana (استاندارد OWIN) | A Geek Notes

  3. Taewan Kim says:

    Andras, thanks for the great Post!!

    If the execution doesn’t hit the break point in Invoke(), what could be the issue?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

Elliot Balynn's Blog

A directory of wonderful thoughts

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: