During yesterday’s blog reading session I came across two interesting posts. First one was about building a web server using WCF. The other one was about testing ASP.NET MVC as a whole, not only controllers, by hosting ASP.NET in process.

I realized that  by combining these two not very common usages of these technologies I can build an even more uncommon one. I could use WCF to receive requests and send response and ASP.NET MVC to generate content. The goal would be to get it to the state, when I could reference an assembly (a class library) containing controllers and views and start a web server using these in my console application or Windows service.

Now, probably, you want to ask, why on earth would I need such a feature? Isn’t IIS the place to host your web applications? My scenario, which I think is quite interesting, it to add HTTP/HTML based diagnostics to a Windows service. Want to check in log paths are OK? Just connect to it using browser. Want to run some diagnostics against disk share paths or database table permissions? Just write some code to generate a report and make it accessible via a controller.

I encountered some interesting challenges I want to share with you. First of all, how ASP.NET MVC is quite dependent on ASP.NET infrastructure. Some request/context related classes are not a big problem thanks to System.Web.Abstractions dll. The case if far worse with default view engine (aspx/ascx) which uses directly System.Web. I wasn’t able to find out how could I use the compilation feature without starting ASP.NET runtime in AppDomain, so I decided to give up and start the ASP.NET.

(I am not very happy with this solution and I will try to use another view engine to check whether there are other hard ASP.NET dependencies. If not, I will happily get rid of it, since it complicates stuff, a lot — read on)

ASP.NET runtime could be started only in a brand new AppDomain to which you don’t have to access before it starts. It is a big problem because when you start the runtime, you pass it a custom type which is instantiated ‘on the other side’ and lets you configure and manipulate the domain. By default ASP.NET searches for dll in the bin subdirectory of main app directory, so if you want to run it in context of console application, you have to create bin directory where you have your dlls and put there one containing that aforementioned ‘integration’ type. At least it works and this is the trick this article uses.

Mine was to add assembly load directives to web config:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <probing privatePath="bin;"/>
  </assemblyBinding>
</runtime>

The ‘;’ character is critical. Because of it this private path means ’search in bin subdirectory of application base dir and in the application base dir‘. The latter is represented by an empty string, ‘;’ is just a separator.

Other elements of solution include custom virtual path provided (using aspx/ascx files embedded in an assembly) and some hackyish code I am not very proud of. But remember, that is only a very quick and very dirty proof-of-concept.

You can download the code here. It requires ASP.NET MVC 1.0 to run. If you have any ideas (besides that code is horrible ;-) ), please leave a comment.

VN:F [1.8.7_1070]
Rating: 5.0/5 (1 vote cast)
Building an embedded MVC server5.051