Tinyweb Does Mono
For a long time, the Microsoft technology stack was pretty much glued to Windows. If you wanted to use Microsoft technology, you’d pretty much need to use compilers, runtimes and servers that existed only for Windows. Back then, the closest thing we had to cross-platform were things like WINE which simply tried to emulate the entire runtime environment.
Times have certainly changed, particularly when it comes to web development. Thanks to awesome projects like Mono, it’s no longer the case that working with C# / ASP.NET binds you to Microsoft development tools and forces you to use Windows for development and hosting.
Mono brings a C# compiler and CLI implementation (in addition to other things) to operating systems such as Linux and Mac OS X, making technologies like C# and ASP.NET much more feasible and available.
Let’s see how easy it is to get up and running on Mac OS X using things we’d normally only assume were doable using Visual Studio and Windows. We’ll create a C# ASP.NET application using Mono and MonoDevelop (the IDE). We could also use ASP.NET MVC, but to further demonstrate how easy cross-platform has become with Mono, we’ll use a lightweight web framework that I have been working on called Tinyweb. And while we’re at it, let’s add the Spark view engine and StructureMap to the mix too.
The first thing you’ll need to do is install Mono and MonoDevelop. Head over to http://www.go-mono.com/mono-downloads/download.html and http://monodevelop.com/download and install the packages for your version of OS X. If you’re following this using Linux instead, just install the Linux packages and everything else should work in the same way.
Here’s one I prepared earlier:
MonoDevelop provides much the same experience that Visual Studio provides, so you should be pretty familiar with how it works, even if you’ve never used it before. The next job is to create a new solution, which is done exactly how you might expect: File –> New –> Solution.
Here’s another one I prepared earlier:
After entering the name and location, you should have a new solution with an empty ASP.NET project. Since we’re using Tinyweb as our web framework, the next thing we need to do is add the Tinyweb assemblies to the project.
You can get Tinyweb from its github repository and compile it yourself, but to make life easier there’s also a continuous release build here. You don’t need an account to access the CI server, just click the Login as a Guest User link at the bottom:
Once you have logged in, you should see the latest build of Tinyweb and a link to the build artifacts. Download the Tinyweb.zip archive which contains the various assemblies you’ll need to work with Tinyweb.
As an interesting side-point, the TeamCity server is actually a Windows Server 2008 machine building the Tinyweb project directly from its github repository using MSBuild, and yet we’re able to download these same assemblies and use them on a completely different operating system.
Let’s add references to the assemblies we’ll need. You’ll notice that the archive is organised into two directories: Framework and View Engines. You need to add references to both assemblies from Framework, and both assemblies from View Engines/Spark:
To keep things simple, we’ll create an application which handles requests for the URL /home. In Tinyweb land, this is a simple matter of creating a HomeHandler class and adding the required method to reflect the type of request we want to handle:
Tinyweb uses a convention whereby the name of the handler (excluding the word handler) is used as the URL that the handler responds to. It’s possible to override this convention by declaring a Route field in the class, like this:
public class HomeHandler
{
Route route = new Route("UnconventionalUrl");
public IHandlerResult Get()
{
return Result.String("Hello World");
}
}
The handler would now respond to requests for the URL /UnconventionalUrl, not its original URL of /home.
Looking at our code so far, you’ll notice that we have a public method named Get. Methods in Tinyweb handlers must be named to match one of the HTTP verbs that they intend to process. Currently, we’ll be processing HTTP GET requests and returning a raw string as output.
So, we have a solution, we have a project, we have references to Tinyweb and we have a handler. Next up we need to initialise the Tinyweb framework at application start-up, cue Global.asax:
Nothing too ground-breaking here. We’ve just added a Global.asax file so we can hook into the ASP.NET application start-up event and call Tinyweb.Init. The Tinyweb.Init call simply provokes the framework to scan for handlers and set up the routes that have been found.
The last remaining thing to do is to make sure we’re targeting .NET 4 (because Tinyweb is compiled against version 4 of the CLR). Simply right-click the project and select properties. If any rocket scientists are reading, I apologise:
With any luck, you should now be able to build the solution and run it. When you run the project, MonoDevelop will start a local instance of the XSP web server on port 8080 in much the same way that Visual Studio uses its own local development server:
That was a pleasant experience, let’s continue with the demo and see how we can bring Spark to the party. In terms of code, we only need to make a slight change in order to return a Spark view instead of the raw string currently being returned:
The return statement has been changed to point to the Spark view file Hello.spark. Let’s see what happens when we run the project again:
Good, that’s what we should have expected since we’ve not created the view file yet. Easy fix – let’s create the view file Hello.spark in the root of the project:
It’s not a particularly ambitious view, we’re just keeping with the hello world theme while also using the Spark encoded output syntax ${} to output the current date and time from System.DateTime.Now. And, for my final trick:
If you were wondering what happened to StructureMap – it’s actually a dependency of Tinyweb and used internally when a handler needs instantiating to handle a request. If you were to add a constructor-injected dependency to a handler, you’d just need to supply a StructureMap registry to the Tinyweb.Init call in order to have that dependency supplied at runtime.
So there you have it – C#, ASP.NET, Tinyweb, Spark and StructureMap coming to you from sunny OS X, thanks to Mono.
EDIT
Due to the use of images in this post, the code samples have not been updated to reflect the latest public API changes in Tinyweb v2.0.0. The only significant difference is the renaming of IHandlerResult to IResult, so please be aware of this when following along.


that seems simple enough.
will give it a try.
Cheers,
Kalyan