<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Zack Owens</title><subtitle type="html">Showing how COOL .NET is!</subtitle><id>http://weblogs.asp.net/zowens/atom.aspx</id><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/default.aspx" /><link rel="self" type="application/atom+xml" href="http://weblogs.asp.net/zowens/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20510.895">Community Server</generator><updated>2008-08-04T17:08:04Z</updated><entry><title>“Try to avoid foreach/for loops”–Over my Dead Body!</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2011/01/24/try-to-avoid-foreach-for-loops-over-my-dead-body.aspx" /><id>http://weblogs.asp.net/zowens/archive/2011/01/24/try-to-avoid-foreach-for-loops-over-my-dead-body.aspx</id><published>2011-01-24T20:01:00Z</published><updated>2011-01-24T20:01:00Z</updated><content type="html">&lt;p&gt;Before I get into this a little bit, know that my comments are a direct response to this post: &lt;a href="http://www.codekicks.com/2011/01/try-to-avoid-foreachfor-loops.html" title="http://www.codekicks.com/2011/01/try-to-avoid-foreachfor-loops.html" mce_href="http://www.codekicks.com/2011/01/try-to-avoid-foreachfor-loops.html"&gt;http://www.codekicks.com/2011/01/try-to-avoid-foreachfor-loops.html&lt;/a&gt;. The reason I’m writing this post is because the author is making invalid comparisons through his use of each of the looping mechanisms in C# to &lt;i&gt;QUICKLY&lt;/i&gt; come to the conclusion that do-while and while are faster than for/foreach. I’ve done my own tests modeled after the author’s tests, but with significantly different results. As a computer &lt;b&gt;scientist&lt;/b&gt;, I want to make sure I actually analyze the data before coming to a conclusion about the runtime behavior. &lt;/p&gt;  &lt;h1&gt;&amp;nbsp;&lt;/h1&gt;  &lt;h2&gt;What He Got Wrong&lt;/h2&gt;  &lt;p&gt;The first test he’s running is a foreach loop. This all fine and good… this is something we probably do on a daily basis. &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_2.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_2.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb.png" style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb.png" border="0" height="219" width="330"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;What is the foreach loop &lt;i&gt;actually&lt;/i&gt; doing? The compiler translates this into a local variable for the enumerator and a boolean. In IL, one of my runs produced a binary with the IEnumerator being named CS$5$0000. Then the compiler translates the body and the behavior of the foreach into a bunch of labels in IL. First MoveNext is called and the body of the forloop (now a label) is jumped to and executed. Then the MoveNext is called again and the loop starts over. &lt;/p&gt;  &lt;p&gt;The next thing the author moves to is the for loop. Here’s his code:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_4.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_4.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_1.png" style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_1.png" border="0" height="80" width="390"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;What this is actually doing is COMPLETELY different from the semantics of the forloop. What he’s doing is just running a for loop on a separate integer. He’s not running through the iterator. This is the thing that invalidates his tests. He has WAY too many experimental variables, leading to invalid comparisons. The same fallacy occurs in his while test and the do-while tests:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_6.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_6.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_2.png" style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_2.png" border="0" height="96" width="279"&gt;&lt;/a&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_8.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_8.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_3.png" style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_3.png" border="0" height="105" width="301"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;He’s not actually iterating through the list of numbers. This is a huge issue. You can’t possibly make valid comparisons when you completely change your test scheme. This is just bad test design. &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;h2&gt;The Right Idea&lt;/h2&gt;  &lt;p&gt;The idea of testing the different looping mechanisms isn’t a bad one. However, his test design doesn’t really take a few things into account that is really significant to the outcome of the time. &lt;/p&gt;  &lt;p&gt;First of all, GC is a huge issue. He’s running all 4 tests in succession on the same thread. The GC in .NET, unlike the looping, can kick in whenever it damn well pleases to cleanup garbage. When you’re dealing with 10 million items, there’s bound to be at least 1 GC run in there somewhere, which can significantly mess with the times of the stopwatch. The stopwatch is a really dumb object… it just keeps track of CPU clicks. It has NO idea what the GC is up to. &lt;/p&gt;  &lt;p&gt;A better design would be to simply run 1 trial at a time. That way, the order of the tests doesn’t influence the GC. &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;h2&gt;Wrong Data Structure&lt;/h2&gt;  &lt;p&gt;The author probably doesn’t know how lists are implemented (as I suspect most .NET devs don’t). If you’ve ever taken a class in C++ or C, you know that you have to manually resize arrays yourself if you’re going to have expandable array (“list”) behavior. The author chose to use a list to add 10 million items in it. The list, when setup, doesn’t know how many items you’ll be adding to the data structure. It choses an arbitrary size, allocates an array of that size, and expands if you add more items than the size it picked. But when it expands, it has to do a complete copy of the array EVERY SINGLE TIME an item is added (see the iternals of Insert on list). Since you already know the size of the data, just use an array to begin with!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_10.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_10.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_4.png" style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_4.png" border="0" height="178" width="367"&gt;&lt;/a&gt;&lt;/p&gt;    &lt;h2&gt;Let’s Test This For Real&lt;/h2&gt;  &lt;p&gt;I’m done ranting about a poorly design perf test. It’s time to run my own. The proof is in the pudding. &lt;/p&gt;  &lt;p&gt;First I’m going to run identical tests in succession and let GC do whatever it wants. As you can see from my code, I’m using iterators EVERY TIME for consistency. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_12.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_12.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_5.png" style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_5.png" border="0" height="829" width="734"&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;Surprising results: they’re all about the same.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_16.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_16.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_7.png" style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_7.png" border="0" height="342" width="680"&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;All except for that do-while… anyone wanna tell me why? My guess is that GC took over at some point inside the stopwatch execution. Let’s run it again. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_18.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_18.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_8.png" style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_8.png" border="0" height="352" width="693"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Hmmmmmmmmmm interesting! While and do-while are actually SIGNIFICANTLY SLOWER than for and foreach…. what an interesting turn of events. Let’s run them individually now. &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_20.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_20.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_9.png" style="background-image: none; border: 0px none; margin: 5px 5px 5px 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_9.png" border="0" height="348" width="680"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_22.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_22.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_10.png" style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_10.png" border="0" height="345" width="677"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_24.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_24.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_11.png" style="background-image: none; border: 0px none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_11.png" border="0" height="345" width="680"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_26.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_26.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_12.png" style="background-image: none; border: 0px none; margin: 5px 5px 5px 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/Try-to-avoid-foreachfor-loopsOver-my-Dea_C83B/image_thumb_12.png" border="0" height="339" width="677"&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;All are around the same time, interestingly. Honestly, I think this is a testament to the great work the C# compiler guys do. Here’s the deal. At the end of the day, the body of any looping construct is a label generated by the compiler and then interpreted by the CLR. These guys shouldn’t have completely different running times. &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;h2&gt;Conclusion&lt;/h2&gt;  &lt;p&gt;This post started off as a complete rant about an incorrect test and ended with a proof that there’s a lot more going on in the test design than the original author was fooled into thinking. Let me just say that this post isn’t personal. I don’t even know the original author. I just happened on his post and about flew out of my chair. Just think about how this sounds: different looping constructs have different runtime behavior. This seems completely rediculous to me. If this were true, the C# compiler writers would certainly have converted all loops to the one that performed better… it wouldn’t be hard to do at all. However, this isn’t the case since all loops are turned into labels in IL. &lt;/p&gt;  &lt;p&gt;So the moral of the story is that you can keep writing your for loops and foreach loops, there’s no performance gain either way. &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;UPDATE:&lt;/b&gt; The author changed the title from "Try to Avoid Foreach/For loops" to "An observation on .NET loops". I copied and pasted the original title for my blog post... so that's where the title comes from :) &lt;br&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7689154" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/zowens/archive/tags/.NET/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/zowens/archive/tags/C_2300_/default.aspx" /><category term="IL" scheme="http://weblogs.asp.net/zowens/archive/tags/IL/default.aspx" /></entry><entry><title>ASP.NET JavaScript Routing for ASP.NET MVC–Constraints</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2011/01/04/asp-net-javascript-routing-for-asp-net-mvc-constraints.aspx" /><id>http://weblogs.asp.net/zowens/archive/2011/01/04/asp-net-javascript-routing-for-asp-net-mvc-constraints.aspx</id><published>2011-01-04T22:12:24Z</published><updated>2011-01-04T22:12:24Z</updated><content type="html">&lt;p&gt;If you haven’t had a look at my previous post about ASP.NET routing, go ahead and check it out before you read this post: &lt;a title="http://weblogs.asp.net/zowens/archive/2010/12/20/asp-net-mvc-javascript-routing.aspx" href="http://weblogs.asp.net/zowens/archive/2010/12/20/asp-net-mvc-javascript-routing.aspx"&gt;http://weblogs.asp.net/zowens/archive/2010/12/20/asp-net-mvc-javascript-routing.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;And the code is here: &lt;a title="https://github.com/zowens/ASP.NET-MVC-JavaScript-Routing" href="https://github.com/zowens/ASP.NET-MVC-JavaScript-Routing"&gt;https://github.com/zowens/ASP.NET-MVC-JavaScript-Routing&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Anyways, this post is about routing constraints. A routing constraint is essentially a way for the routing engine to filter out route patterns based on the day from the URL. For example, if I have a route where all the parameters are required, I could use a constraint on the required parameters to say that the parameter is non-empty. Here’s what the constraint would look like:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/ASP.NET-MVC-JavaScript-RoutingConstraint_E924/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/ASP.NET-MVC-JavaScript-RoutingConstraint_E924/image_thumb.png" width="595" height="196" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Notice that this is a class that inherits from IRouteConstraint, which is an interface provided by System.Web.Routing. The match method returns true if the value is a match (and can be further processed by the routing rules) or false if it does not match (and the route will be matched further along the route collection). &lt;/p&gt;  &lt;p&gt;Because routing constraints are so essential to the route matching process, it was important that they be part of my JavaScript routing engine. But the problem is that we need to somehow represent the constraint in JavaScript. I made a design decision early on that you MUST put this constraint into JavaScript to match a route. I didn’t want to have server interaction for the URL generation, like I’ve seen in so many applications. While this is easy to maintain, it causes maintenance issues in my opinion. &lt;/p&gt;  &lt;p&gt;So the way constraints work in JavaScript is that the constraint as an object type definition is set on the route manager. When a route is created, a new instance of the constraint is created with the specific parameter. In its current form the constraint function MUST return a function that takes the route data and will return true or false. You will see the NotEmpty constraint in a bit. &lt;/p&gt;  &lt;p&gt;Another piece to the puzzle is that you can have the JavaScript exist as a string in your application that is pulled in when the routing JavaScript code is generated. There is a simple interface, IJavaScriptAddition, that I have added that will be used to output custom JavaScript. &lt;/p&gt;  &lt;p&gt;Let’s put it all together. Here is the NotEmpty constraint. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/ASP.NET-MVC-JavaScript-RoutingConstraint_E924/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/ASP.NET-MVC-JavaScript-RoutingConstraint_E924/image_thumb_1.png" width="639" height="388" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;There’s a few things at work here. The constraint is called “notEmpty” in JavaScript. When you add the constraint to a parameter in your C# code, the route manager generator will look for the JsConstraint attribute to look for the name of the constraint type name and fallback to the class name. For example, if I didn’t apply the “JsConstraint” attribute, the constraint would be called “NotEmpty”. &lt;/p&gt;  &lt;p&gt;The JavaScript code essentially adds a function to the “constraintTypeDefs” object on the “notEmpty” property (this is how constraints are added to routes). The function returns another function that will be invoked with routing data. &lt;/p&gt;  &lt;p&gt;Here’s how you would use the NotEmpty constraint in C# and it will work with the JavaScript routing generator. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/ASP.NET-MVC-JavaScript-RoutingConstraint_E924/image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/ASP.NET-MVC-JavaScript-RoutingConstraint_E924/image_thumb_2.png" width="556" height="136" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The only catch to using route constraints currently is that the following is not supported:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/ASP.NET-MVC-JavaScript-RoutingConstraint_E924/image_8.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/ASP.NET-MVC-JavaScript-RoutingConstraint_E924/image_thumb_3.png" width="542" height="125" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The constraint will work in C# but is not supported by my JavaScript routing engine. (I take pull requests so if you’d like this… go ahead and implement it). &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I just wanted to take this post to explain a little bit about the background on constraints. I am looking at expanding the current functionality, but for now this is a good start. &lt;/p&gt;  &lt;p&gt;Thanks for all the support with the JavaScript router. Keep the feedback coming! &lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7674422" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/zowens/archive/tags/.NET/default.aspx" /><category term="ASP.NET" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET/default.aspx" /><category term="ASP.NET MVC" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET+MVC/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/zowens/archive/tags/C_2300_/default.aspx" /><category term="JavaScript" scheme="http://weblogs.asp.net/zowens/archive/tags/JavaScript/default.aspx" /><category term="jQuery" scheme="http://weblogs.asp.net/zowens/archive/tags/jQuery/default.aspx" /><category term="Open Source" scheme="http://weblogs.asp.net/zowens/archive/tags/Open+Source/default.aspx" /></entry><entry><title>ASP.NET MVC JavaScript Routing</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2010/12/20/asp-net-mvc-javascript-routing.aspx" /><id>http://weblogs.asp.net/zowens/archive/2010/12/20/asp-net-mvc-javascript-routing.aspx</id><published>2010-12-20T16:15:00Z</published><updated>2010-12-20T16:15:00Z</updated><content type="html">
&lt;p&gt;Have you ever done this sort of thing in your ASP.NET MVC view?&lt;/p&gt;
  
&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_4.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_4.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_1.png" style="background-image: none; border-width: 0px; margin: 5px 5px 5px 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_1.png" border="0" height="187" width="676"&gt;&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;The weird thing about this isn’t the alert function, it’s the code block containing the Url formation using the ASP.NET MVC UrlHelper. The terrible thing about this experience is the obvious lack of IntelliSense and this ugly inline JavaScript code. Inline JavaScript isn’t portable to other pages beyond the current page of execution. It is generally considered bad practice to use inline JavaScript in your public-facing pages. How ludicrous would it be to copy and paste the entire jQuery code base into your pages…? Not something you’d ever consider doing. &lt;/p&gt;
  
&lt;p&gt;The problem is that your URLs have to be generated by ASP.NET at runtime and really can’t be copied to your JavaScript code without some trickery. &lt;/p&gt;
  
&lt;p&gt;How about this?&lt;/p&gt;
  
&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_6.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_6.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_2.png" style="background-image: none; border-width: 0px; margin: 5px 5px 5px 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_2.png" border="0" height="181" width="661"&gt;&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;Does the hard-coded URL bother you? It really bothers me. The typical solution to this whole routing in JavaScript issue is to just hard-code your URLs into your JavaScript files and call it done. But what if your URLs change? You have to now go an track down the places in JavaScript and manually replace them. What if you get the pattern wrong? Do you have tests around it? This isn’t something you should have to worry about.&lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h3&gt;The Solution To Our Problems&lt;/h3&gt;  
&lt;p&gt;The solution is to port routing over to JavaScript. Does that sound daunting to you? It’s actually not very hard, but I decided to create my own generator that will do all the work for you. &lt;/p&gt;
  
&lt;p&gt;What I have created is a very basic port of the route formation feature of ASP.NET routing. It will generate the formatted URLs based on your routing patterns. Here’s how you’d do this:&lt;/p&gt;
  
&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_8.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_8.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_3.png" style="background-image: none; border-width: 0px; margin: 5px 5px 5px 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_3.png" border="0" height="112" width="585"&gt;&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;Does that feel familiar? It looks a lot like something you’d do inside of your ASP.NET MVC views… but this is inside of a JavaScript file… just a plain ol’ .js file.&amp;nbsp; Your first question might be why do you have to have that “.toUrl()” thing. The reason is that I wanted to make POST and GET requests dead simple. Here’s how you’d do a POST request (and the same would work with a GET request):&lt;/p&gt;
  
&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_10.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_10.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_4.png" style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_4.png" border="0" height="147" width="591"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
  
&lt;p&gt;The first parameter is extra data passed to the post request and the second parameter is a function that handles the success of the POST request. If you’re familiar with jQuery’s Ajax goodness, you’ll know how to use it. (if not, check out &lt;a href="http://api.jquery.com/jQuery.Post/" title="http://api.jquery.com/jQuery.Post/" mce_href="http://api.jquery.com/jQuery.Post/"&gt;http://api.jquery.com/jQuery.Post/&lt;/a&gt; and the parameters are essentially the same). &lt;/p&gt;
  
&lt;p&gt;But we still haven’t gotten rid of the magic strings. We still have controller names and action names represented as strings. This is going to blow your mind… &lt;/p&gt;
  
&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_12.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_12.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_5.png" style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_5.png" border="0" height="144" width="431"&gt;&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;If you’ve seen T4MVC, this will look familiar. We’re essentially doing the same sort of thing with my JavaScript router, but we’re porting the concept to JavaScript. The good news is that parameters to the controllers are directly reflected in the action function, just like T4MVC. &lt;/p&gt;
  
&lt;p&gt;And the even better news… IntlliSense is easily transferred to the JavaScript version if you’re using Visual Studio as your JavaScript editor. &lt;/p&gt;
  
&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_14.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_14.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_6.png" style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_6.png" border="0" height="387" width="430"&gt;&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_16.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_16.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_7.png" style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_7.png" border="0" height="162" width="410"&gt;&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;The additional data parameter gives you the ability to pass extra routing data to the URL formatter. &lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h3&gt;About the Magic&lt;/h3&gt;  
&lt;p&gt;You may be wondering how this all work. &lt;/p&gt;
  
&lt;p&gt;It’s actually quite simple. I’ve built a simple jQuery pluggin (called routeManager) that hangs off the main jQuery namespace and routes all the URLs. Every time your solution builds, a routing file will be generated with this pluggin, all your route and controller definitions along with your documentation. Then by the power of Visual Studio, you get some really slick IntelliSense that is hard to live without. &lt;/p&gt;
  
&lt;p&gt;But there are a few steps you have to take before this whole thing is going to work. &lt;/p&gt;
  
&lt;p&gt;First and foremost, you need a reference to the JsRouting.Core.dll to your projects containing controllers or routes. &lt;/p&gt;
  
&lt;p&gt;Second, you have to specify your routes in a bit of a non-standard way. See, we can’t just pull routes out of your App_Start in your Global.asax. We force you to build a route source like this:&lt;/p&gt;
  
&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_18.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_18.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_8.png" style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_8.png" border="0" height="185" width="653"&gt;&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;The way we determine the routes is by pulling in all RouteSources and generating routes based upon the mapped routes. &lt;/p&gt;
  
&lt;p&gt;There are various reasons why we can’t use RouteCollection (different post for another day)… but in this case, you get the same route mapping experience. Converting the RouteSource to a RouteCollection is trivial (there’s an extension method for that).&lt;/p&gt;
  
&lt;p&gt;Next thing you have to do is generate a documentation XML file. This is done by going to the project settings, going to the build tab and clicking the checkbox. (this isn’t required, but nice to have).&lt;/p&gt;
  
&lt;p&gt;The final thing you need to do is hook up the generation mechanism. Pop open your project file and look for the AfterBuild step. Now change the build step task to look like this:&lt;/p&gt;
  
&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_20.png" mce_href="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_20.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_9.png" style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/zowens/Windows-Live-Writer/66dc68f24846_13B90/image_thumb_9.png" border="0" height="177" width="877"&gt;&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;The “PathToOutputExe” is the path to the JsRouting.Output.exe file. This will change based on where you put the EXE. The “PathToOutputJs” is a path to the output JavaScript file. The “DicrectoryOfAssemblies” is a path to the directory containing controller and routing DLLs. The JsRouting.Output.exe executable pulls in all these assemblies and scans them for controllers and route sources. &lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  
&lt;p&gt;Now that wasn’t too bad, was it :) &lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h3&gt;The State of the Project&lt;/h3&gt;  
&lt;p&gt;This is definitely not complete… I have a lot of plans for this little project of mine. For starters, I need to look at the generation mechanism. Either I will be creating a utility that will do the project file manipulation or I will go a different direction. I’d like some feedback on this if you feel partial either way. &lt;/p&gt;
  
&lt;p&gt;Another thing I don’t support currently is areas. While this wouldn’t be too hard to support, I just don’t use areas and I wanted something up quickly (this is, after all, for a current project of mine). I’ll be adding support shortly. &lt;/p&gt;
  
&lt;p&gt;There are a few things that I haven’t covered in this post that I will most certainly be covering in another post, such as routing constraints and how these will be translated to JavaScript. &lt;/p&gt;
  
&lt;p&gt;I decided to open source this whole thing, since it’s a nice little utility I think others should really be using. &lt;/p&gt;
  
&lt;p&gt;Currently we’re using ASP.NET MVC 2, but it should work with MVC 3 as well. I’ll upgrade it as soon as MVC 3 is released. Along those same lines, I’m investigating how this could be put on the NuGet feed. &lt;/p&gt;
  &lt;h3&gt;Show me the Bits!&lt;/h3&gt;  
&lt;p&gt;OK, OK! The code is posted on my GitHub account. Go nuts. Tell me what you think. Tell me what you want. Tell me that you hate it. All feedback is welcome! &lt;/p&gt;
  
&lt;p&gt;&lt;a href="https://github.com/zowens/ASP.NET-MVC-JavaScript-Routing" title="https://github.com/zowens/ASP.NET-MVC-JavaScript-Routing" mce_href="https://github.com/zowens/ASP.NET-MVC-JavaScript-Routing"&gt;https://github.com/zowens/ASP.NET-MVC-JavaScript-Routing&lt;/a&gt;&lt;/p&gt;
&lt;br&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2010%2f12%2f20%2fasp-net-mvc-javascript-routing.aspx"&gt;&lt;img src="http://weblogs.asp.net/controlpanel/blogs/http%3A%2F%2Fwww.dotnetkicks.com%2FServices%2FImages%2FKickItImageGenerator.ashx%3Furl%3Dhttp%253a%252f%252fweblogs.asp.net%252fzowens%252farchive%252f2010%252f12%252f20%252fasp-net-mvc-javascript-routing.aspx" alt="kick it on DotNetKicks.com" border="0"&gt;&lt;/a&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7664917" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/zowens/archive/tags/.NET/default.aspx" /><category term="AJAX" scheme="http://weblogs.asp.net/zowens/archive/tags/AJAX/default.aspx" /><category term="ASP.NET" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET/default.aspx" /><category term="ASP.NET MVC" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET+MVC/default.aspx" /><category term="JavaScript" scheme="http://weblogs.asp.net/zowens/archive/tags/JavaScript/default.aspx" /><category term="jQuery" scheme="http://weblogs.asp.net/zowens/archive/tags/jQuery/default.aspx" /></entry><entry><title>Multi-tenant ASP.NET MVC – Inversion of Control</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2010/06/23/multi-tenant-asp-net-mvc-inversion-of-control.aspx" /><id>http://weblogs.asp.net/zowens/archive/2010/06/23/multi-tenant-asp-net-mvc-inversion-of-control.aspx</id><published>2010-06-23T14:30:14Z</published><updated>2010-06-23T14:30:14Z</updated><content type="html">&lt;p&gt;&lt;a href="http://weblogs.asp.net/zowens/archive/2010/05/26/multi-tenant-asp-net-mvc-introduction.aspx" target="_blank"&gt;Part I – Introduction&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/zowens/archive/2010/05/29/multi-tenant-asp-net-foundation.aspx" target="_blank"&gt;Part II – Foundation&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/zowens/archive/2010/06/07/mulit-tenant-asp-net-mvc-controllers.aspx" target="_blank"&gt;Part III – Controllers&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/zowens/archive/2010/06/16/multi-tenant-asp-net-mvc-views.aspx" target="_blank"&gt;Part IV – Views&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://github.com/zowens/Multi-tenancy-Sample" target="_blank"&gt;Source Code&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;One of the most important aspects of my Multi-tenant ASP.NET MVC implementation is Inversion of Control containers. These containers are essential to wiring up and finding the proper controllers. In my last iteration of code that followed the Views post, my setup for the container was a simple association of types added to the PluginGraph. I really do not want to have to do this manually. Therefore, I want to utilize StructureMap the best I can. This post will show you how I wire up controllers by convention rather than by configuration.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;The Convention&lt;/h3&gt;  &lt;p&gt;The main convention I will be targeting is this: the controller that will be wired must have the same name as the root (or a unique name) and must inherit from a controller of the same name or “Controller”. For example, this first class would be in the “Host” project (for this example, the controller is “AccountController”). If a tenant project DID NOT override the AccountController, the host’s AccountController would be added to the container. If a tenant DID override AccountController, the AccountController in the tenant would be used as the AccountController. Here’s the example in code:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// AccountController in the Host project&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; MyApp.HostWeb
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; AccountController : Controller
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        ....
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// AccountController in the Tenant project&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; MyApp.FirstTenant
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; AccountController : MyApp.HostWeb.AccountController
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        ....
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The obvious downside to this implementation is that the fully qualified controller name must be used after the “:” to denote inheritance. You could implement this a bit differently, but I’ve chosen this way for simplicity.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Wiring Up Controllers&lt;/h3&gt;

&lt;p&gt;The question that arises is how to inject this convention into container configuration using StructureMap. The way I’ve chosen to go is by using assembly scanner conventions. An assembly scanner will blindly go through all the types in a specified assembly and run the types against a convention. There are some conventions already in place, but we can also write our own conventions. &lt;/p&gt;

&lt;p&gt;In my implementation, the host and tenant project assemblies will both be scanned for controllers. Here’s how the assembly scanning works inside the configuration of a container:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;var container = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Container();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;container.Configure(config =&amp;gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    config.Scan(scanner =&amp;gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #008000"&gt;// add the conventions&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        scanner.Convention&amp;lt;ControllerConvention&amp;gt;();
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #008000"&gt;// specify assemblies to scan (just examples here, simpler in practice)&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        scanner.TheCallingAssembly();
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        scanner.Assembly(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(Something).Assembly);
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        scanner.Assembly(&amp;quot;&lt;span style="color: #8b0000"&gt;MyAssembly&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        scanner.AssemblyContainingType&amp;lt;Foo&amp;gt;();
&lt;/pre&gt;&lt;pre style="background-color: #ffff00; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    });
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;});&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Writing the Convention&lt;/h3&gt;

&lt;p&gt;The next step is to write ControllerConvention so that the controllers will be added correctly to the container. I’m using a little black magic to intercept types and initialize them properly using an interceptor. However, this is frankly the only way I’ve found that works. But anyways, here’s the code.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ControllerConvention : IRegistrationConvention
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Process(Type type, Registry registry)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (registry == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; || !IsValidController(type))
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        var baseClass = type.BaseType;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!IsValidController(baseClass) || !baseClass.Name.Equals(type.Name))
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            registry.AddType(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IController), type);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            registry.AddType(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IController), baseClass);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            registry.RegisterInterceptor(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TypeReplacementInterceptor(baseClass, type));
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsValidController(Type type)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; type != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; !type.IsAbstract &amp;amp;&amp;amp; &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IController).IsAssignableFrom(type) &amp;amp;&amp;amp;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;               type.Name.EndsWith(&amp;quot;&lt;span style="color: #8b0000"&gt;Controller&lt;/span&gt;&amp;quot;) &amp;amp;&amp;amp; type.IsPublic;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; TypeReplacementInterceptor : TypeInterceptor
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; Type typeToReplace;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; Type replacementType;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; TypeReplacementInterceptor(Type typeToReplace, Type replacementType)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.typeToReplace = typeToReplace;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.replacementType = replacementType;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; MatchesType(Type type)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; type != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; type.Equals(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.typeToReplace);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Process(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; target, IContext context)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #008000"&gt;// Sanity check: If the context is null, we can't do anything about it!&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (context == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; target;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; context.GetInstance(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.replacementType);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Going back to the AccountController example, suppose that the controller is overridden by the tenant. The way the convention will look at it is that the names match and the base type is a controller. Therefore, the BASE TYPE is added to the PluginGraph and will be INTERCEPTED once requested by the TypeInterceptor. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Another Way to Implement&lt;/h3&gt;

&lt;p&gt;Another way to implement this behavior is through a type scanner (ITypeScanner). The process is the same as the convention, but you are given a PluginGraph directly rather than using a registry. There is a subtle difference in the types, but the idea is the same. In fact, you can copy and paste the body of the “Process” code right into a type scanner and only have to change “registry.RegisterInterceptor(…)” to “graph.InterceptorLibrary.AddInterceptor(…);”.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Caveat &lt;/h3&gt;

&lt;p&gt;There’s a bit of a wonkiness in the type interceptor. If you look at the “Process” method of the interceptor, you’ll notice you’re given a target. If you’re overriding a controller, target will be the base controller. For example, going back to the AccountController example, target will be an &lt;em&gt;instance&lt;/em&gt; of the AccountController from the Host. While this is not so problematic, there is still no need for this instance since it will be intercepted and not used. This is the price you pay for having such a structure in StructureMap. If someone has a better way than I’ve described, I’m all ears :)&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Up Next&lt;/h3&gt;

&lt;p&gt;I have 3 things on my list that I need to talk about. The first is routing with multi-tenancy, second is content resolution and the third is wiring this all up in IIS7. This might be the order of the post or it might not be. We will see. But until next time, keep the questions and discussions going. &lt;a href="mailto:zowens@eagleenvision.net" target="_blank"&gt;Email&lt;/a&gt; me, &lt;a href="http://twitter.com/zowens" target="_blank"&gt;@-reply or DM me on Twitter&lt;/a&gt;.&amp;#160; &lt;a href="http://github.com/zowens/Multi-tenancy-Sample" target="_blank"&gt;(Source code link)&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7540672" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/zowens/archive/tags/.NET/default.aspx" /><category term="ASP.NET" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET/default.aspx" /><category term="ASP.NET MVC" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET+MVC/default.aspx" /><category term="Multi-tenancy" scheme="http://weblogs.asp.net/zowens/archive/tags/Multi-tenancy/default.aspx" /></entry><entry><title>Multi-tenant ASP.NET MVC - Views</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2010/06/16/multi-tenant-asp-net-mvc-views.aspx" /><id>http://weblogs.asp.net/zowens/archive/2010/06/16/multi-tenant-asp-net-mvc-views.aspx</id><published>2010-06-16T16:56:45Z</published><updated>2010-06-16T16:56:45Z</updated><content type="html">&lt;p&gt;&lt;a href="http://weblogs.asp.net/zowens/archive/2010/05/26/multi-tenant-asp-net-mvc-introduction.aspx" target="_blank"&gt;Part I – Introduction&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/zowens/archive/2010/05/29/multi-tenant-asp-net-foundation.aspx" target="_blank"&gt;Part II – Foundation&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/zowens/archive/2010/06/07/mulit-tenant-asp-net-mvc-controllers.aspx" target="_blank"&gt;Part III – Controllers&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;So far we have covered the basic premise of tenants and how they will be delegated. Now comes a big issue with multi-tenancy, the views. In some applications, you will not have to override views for each tenant. However, one of my requirements is to add extra views (and controller actions) along with overriding views from the core structure. This presents a bit of a problem in locating views for each tenant request. I have chosen quite an opinionated approach at the present but will coming back to the “views” issue in a later post. &lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;What’s the deal?&lt;/h3&gt;  &lt;p&gt;The path I’ve chosen is to use &lt;a href="http://sparkviewengine.com/documentation/precompiling" target="_blank"&gt;precompiled Spark views&lt;/a&gt;. I really love Spark View Engine and was planning on using it in my project anyways. However, I ran across a really neat aspect of the source when I was having a look under the hood. There’s an easy way to hook in embedded views from your project. There are solutions that provide this, but they implement a special &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.hosting.virtualpathprovider.aspx" target="_blank"&gt;Virtual Path Provider&lt;/a&gt;. While I think this is a great solution, I would rather just have Spark take care of the view resolution. The magic actually happens during the compilation of the views into a bin-deployable DLL. After the views are compiled, the are simply pulled out of the views DLL. Each tenant has its own views DLL that just has “.Views” appended after the assembly name as a convention. &lt;/p&gt;  &lt;p&gt;The list of reasons for this approach are quite long. The primary motivation is performance. I’ve had quite a few performance issues in the past and I would like to increase my application’s performance in any way that I can. My customized build of Spark removes insignificant whitespace from the HTML output so I can some some bandwidth and load time without having to deal with whitespace removal at runtime. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;How to setup Tenants for the Host&lt;/h3&gt;  &lt;p&gt;In the source, I’ve provided a single tenant as a sample (Sample1). This will serve as a template for subsequent tenants in your application. The first step is to add a “PostBuildStep” installer into the project. I’ve defined one in the source that will eventually change as we focus more on the construction of dependency containers. The next step is to tell the project to run the installer and copy the DLL output to a folder in the host that will pick up as a tenant. Here’s the code that will achieve it (this belongs in Post-build event command line field in the Build Events tab of settings)&lt;/p&gt;  &lt;p&gt;&lt;em&gt;%systemroot%\Microsoft.NET\Framework\v4.0.30319\installutil &amp;quot;$(TargetPath)&amp;quot;      &lt;br /&gt;copy /Y &amp;quot;$(TargetDir)$(TargetName)*.dll&amp;quot; &amp;quot;$(SolutionDir)Web\Tenants\&amp;quot;       &lt;br /&gt;copy /Y &amp;quot;$(TargetDir)$(TargetName)*.pdb&amp;quot; &amp;quot;$(SolutionDir)Web\Tenants\&amp;quot;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;The DLLs with a name starting with the target assembly name will be copied to the “Tenants” folder in the web project. This means something like MultiTenancy.Tenants.Sample1.dll and MultiTenancy.Tenants.Sample1.Views.dll will both be copied along with the debug symbols. This is probably the simplest way to go about this, but it is a tad inflexible. For example, what if you have dependencies? The preferred method would probably be to use IL Merge to merge your dependencies with your target DLL. This would have to be added in the build events. Another way to achieve that would be to simply bypass Visual Studio events and use MSBuild. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I also got a question about how I was setting up the controller factory. Here’s the basics on how I’m setting up tenants inside the host (Global.asax)&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Application_Start()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    RegisterRoutes(RouteTable.Routes);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// create a container just to pull in tenants&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    var topContainer = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Container();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    topContainer.Configure(config =&amp;gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        config.Scan(scanner =&amp;gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            scanner.AssembliesFromPath(Path.Combine(Server.MapPath(&amp;quot;&lt;span style="color: #8b0000"&gt;~/&lt;/span&gt;&amp;quot;), &amp;quot;&lt;span style="color: #8b0000"&gt;Tenants&lt;/span&gt;&amp;quot;));
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            scanner.AddAllTypesOf&amp;lt;IApplicationTenant&amp;gt;();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        });
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    });
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// create selectors&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    var tenantSelector = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DefaultTenantSelector(topContainer.GetAllInstances&amp;lt;IApplicationTenant&amp;gt;());
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    var containerSelector = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TenantContainerResolver(tenantSelector);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// clear view engines, we don't want anything other than spark&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    ViewEngines.Engines.Clear();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// set view engine&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    ViewEngines.Engines.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TenantViewEngine(tenantSelector));
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;// set controller factory&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    ControllerBuilder.Current.SetControllerFactory(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ContainerControllerFactory(containerSelector));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The code to setup the tenants isn’t actually that hard. I’m utilizing assembly scanners in StructureMap as a simple way to pull in DLLs that are not in the AppDomain. Remember that there is a dependency on the host in the tenants and a tenant cannot simply be referenced by a host because of circular dependencies. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Tenant View Engine&lt;/h3&gt;

&lt;p&gt;TenantViewEngine is a simple delegator to the tenant’s specified view engine. You might have noticed that a tenant has to define a view engine.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IApplicationTenant
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    ....
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    IViewEngine ViewEngine { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The trick comes in specifying the view engine on the tenant side. Here’s some of the code that will pull views from the DLL. &lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; IViewEngine DetermineViewEngine()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    var factory = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SparkViewFactory();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    var file = GetType().Assembly.CodeBase.Without(&amp;quot;&lt;span style="color: #8b0000"&gt;file:///&lt;/span&gt;&amp;quot;).Replace(&amp;quot;&lt;span style="color: #8b0000"&gt;.dll&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;.Views.dll&lt;/span&gt;&amp;quot;).Replace('/', '\\');
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    var assembly = Assembly.LoadFile(file);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    factory.Engine.LoadBatchCompilation(assembly);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; factory;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;This code resides in an abstract Tenant where the fields are setup in the constructor. This method (inside the abstract class) will load the Views assembly and load the compilation into Spark’s “Descriptors” that will be used to determine views. There is some trickery on determining the file location… but it works just fine.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Up Next&lt;/h3&gt;

&lt;p&gt;There’s just a few big things left such as StructureMap configuring controllers with a convention instead of specifying types directly with container construction and content resolution. I will also try to find a way to use the Web Forms View Engine in a multi-tenant way we achieved with the Spark View Engine without using a virtual path provider. I will probably not use the Web Forms View Engine personally, but I’m sure some people would prefer using WebForms because of the maturity of the engine. As always, I love to take questions by &lt;a href="mailto:zowens@eagleenvision.net" target="_blank"&gt;email&lt;/a&gt; or on &lt;a href="http://twitter.com/zowens" target="_blank"&gt;twitter&lt;/a&gt;. Suggestions are always welcome as well! &lt;a href="http://github.com/zowens/Multi-tenancy-Sample" target="_blank"&gt;(Oh, and here’s another link to the source code).&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7533601" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET/default.aspx" /><category term="ASP.NET MVC" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET+MVC/default.aspx" /><category term="Multi-tenancy" scheme="http://weblogs.asp.net/zowens/archive/tags/Multi-tenancy/default.aspx" /></entry><entry><title>Mulit-tenant ASP.NET MVC – Controllers</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2010/06/07/mulit-tenant-asp-net-mvc-controllers.aspx" /><id>http://weblogs.asp.net/zowens/archive/2010/06/07/mulit-tenant-asp-net-mvc-controllers.aspx</id><published>2010-06-07T16:40:00Z</published><updated>2010-06-07T16:40:00Z</updated><content type="html">
&lt;p&gt;&lt;a href="http://weblogs.asp.net/zowens/archive/2010/05/26/multi-tenant-asp-net-mvc-introduction.aspx" mce_href="http://weblogs.asp.net/zowens/archive/2010/05/26/multi-tenant-asp-net-mvc-introduction.aspx" target="_blank"&gt;Part I – Introduction&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;&lt;a href="http://weblogs.asp.net/zowens/archive/2010/05/29/multi-tenant-asp-net-foundation.aspx" mce_href="http://weblogs.asp.net/zowens/archive/2010/05/29/multi-tenant-asp-net-foundation.aspx" target="_blank"&gt;Part II – Foundation&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  
&lt;p&gt;The time has come to talk about controllers in a multi-tenant ASP.NET MVC architecture. This is actually the most critical design decision you will make when dealing with multi-tenancy with MVC. In my design, I took into account the design goals I mentioned in the introduction about inversion of control and what a tenant is to my design. Be aware that this is only one way to achieve multi-tenant controllers. &lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h3&gt;The Premise &lt;/h3&gt;  
&lt;p&gt;&lt;a href="http://mvcex.codeplex.com/" mce_href="http://mvcex.codeplex.com/" target="_blank"&gt;MvcEx (which is a sample written by Rob Ashton)&lt;/a&gt; utilizes dynamic controllers. Essentially a controller is “dynamic” in that multiple action results can be placed in different “controllers” with the same name. This approach is a bit too complicated for my design. I wanted to stick with plain old inheritance when dealing with controllers. The basic premise of my controller design is that my main host defines a set of universal controllers. It is the responsibility of the tenant to decide if the tenant would like to utilize these core controllers. This can be done either by straight usage of the controller or inheritance for extension of the functionality defined by the controller. The controller is resolved by a StructureMap container that is attached to the tenant, as discussed in &lt;a href="http://weblogs.asp.net/zowens/archive/2010/05/29/multi-tenant-asp-net-foundation.aspx" mce_href="http://weblogs.asp.net/zowens/archive/2010/05/29/multi-tenant-asp-net-foundation.aspx" target="_blank"&gt;Part II&lt;/a&gt;. &lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h3&gt;Controller Resolution&lt;/h3&gt;  
&lt;p&gt;I have been thinking about two different ways to resolve controllers with StructureMap. One way is to use named instances. This is a really easy way to simply pull the controller right out of the container without a lot of fuss. I ultimately chose not to use this approach. The reason for this decision is to ensure that the controllers are named properly. If a controller has a different named instance that the controller type, then the resolution has a significant disconnect and there are no guarantees. The final approach, the one utilized by the sample, is to simply pull all controller types and correlate the type with a controller name. This has a bit of a application start performance disadvantage, but is significantly more approachable for maintainability. For example, if I wanted to go back and add a “ControllerName” attribute, I would just have to change the ControllerFactory to suit my needs. &lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h3&gt;The Code&lt;/h3&gt;  
&lt;p&gt;The container factory that I have built is actually pretty simple. That’s really all we need. The most significant method is the GetControllersFor method. This method makes the model from the Container and determines all the concrete types for IController.&amp;nbsp; &lt;/p&gt;
  
&lt;p&gt;The thing you might notice is that this doesn’t depend on tenants, but rather containers. You could easily use this controller factory for an application that doesn’t utilize multi-tenancy. &lt;/p&gt;
  
&lt;pre style="border: 1px solid rgb(206, 206, 206); padding: 5px; background-color: rgb(251, 251, 251); min-height: 40px; width: 650px; overflow: auto;"&gt;&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; ContainerControllerFactory : IControllerFactory&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;{&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;readonly&lt;/span&gt; ThreadSafeDictionary&amp;lt;IContainer, IDictionary&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;, Type&amp;gt;&amp;gt; typeCache;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; ContainerControllerFactory(IContainerResolver resolver)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        Ensure.Argument.NotNull(resolver, "&lt;span style="color: rgb(139, 0, 0);"&gt;resolver&lt;/span&gt;");&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;.ContainerResolver = resolver;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;.typeCache = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; ThreadSafeDictionary&amp;lt;IContainer, IDictionary&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;, Type&amp;gt;&amp;gt;();&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; IContainerResolver ContainerResolver { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;; }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;virtual&lt;/span&gt; IController CreateController(RequestContext requestContext, &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; controllerName)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        var controllerType = &lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;.GetControllerType(requestContext, controllerName);&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (controllerType == &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        var controller = &lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;.ContainerResolver.Resolve(requestContext).GetInstance(controllerType) &lt;span style="color: rgb(0, 0, 255);"&gt;as&lt;/span&gt; IController;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 128, 0);"&gt;// ensure the action invoker is a ContainerControllerActionInvoker&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (controller != &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; controller &lt;span style="color: rgb(0, 0, 255);"&gt;is&lt;/span&gt; Controller &amp;amp;&amp;amp; !((controller &lt;span style="color: rgb(0, 0, 255);"&gt;as&lt;/span&gt; Controller).ActionInvoker &lt;span style="color: rgb(0, 0, 255);"&gt;is&lt;/span&gt; ContainerControllerActionInvoker))&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;            (controller &lt;span style="color: rgb(0, 0, 255);"&gt;as&lt;/span&gt; Controller).ActionInvoker = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; ContainerControllerActionInvoker(&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;.ContainerResolver);&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; controller;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; ReleaseController(IController controller)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (controller != &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; controller &lt;span style="color: rgb(0, 0, 255);"&gt;is&lt;/span&gt; IDisposable)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;            ((IDisposable)controller).Dispose();&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;internal&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; IEnumerable&amp;lt;Type&amp;gt; GetControllersFor(IContainer container)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        Ensure.Argument.NotNull(container);&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; container.Model.InstancesOf&amp;lt;IController&amp;gt;().Select(x =&amp;gt; x.ConcreteType).Distinct();&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;virtual&lt;/span&gt; Type GetControllerType(RequestContext requestContext, &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; controllerName)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        Ensure.Argument.NotNull(requestContext, "&lt;span style="color: rgb(139, 0, 0);"&gt;requestContext&lt;/span&gt;");&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        Ensure.Argument.NotNullOrEmpty(controllerName, "&lt;span style="color: rgb(139, 0, 0);"&gt;controllerName&lt;/span&gt;");&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        var container = &lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;.ContainerResolver.Resolve(requestContext);&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        var typeDictionary = &lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;.typeCache.GetOrAdd(container, () =&amp;gt; GetControllersFor(container).ToDictionary(x =&amp;gt; ControllerFriendlyName(x.Name)));&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        Type found = &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (typeDictionary.TryGetValue(ControllerFriendlyName(controllerName), &lt;span style="color: rgb(0, 0, 255);"&gt;out&lt;/span&gt; found))&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; found;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; ControllerFriendlyName(&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;value&lt;/span&gt;)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; (&lt;span style="color: rgb(0, 0, 255);"&gt;value&lt;/span&gt; ?? &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;.Empty).ToLowerInvariant().Without("&lt;span style="color: rgb(139, 0, 0);"&gt;controller&lt;/span&gt;");&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;One thing to note about my implementation is that we do not use namespaces that can be utilized in the default ASP.NET MVC controller factory. This is something that I don’t use and have no desire to implement and test. The reason I am not using namespaces in this situation is because each tenant has its own namespaces and the routing would not make sense in this case. &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Because we are using IoC, dependencies are automatically injected into the constructor. For example, a tenant container could implement it’s own IRepository and a controller could be defined in the “main” project. The IRepository from the tenant would be injected into the main project’s controller. This is quite a useful feature. &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Again, the source code is on &lt;a href="http://github.com/zowens/Multi-tenancy-Sample" mce_href="http://github.com/zowens/Multi-tenancy-Sample" target="_blank"&gt;GitHub here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;Up Next&lt;/h3&gt;

&lt;p&gt;Up next is the view resolution. This is a complicated issue, so be prepared. I hope that you have found this series useful. If you have any questions about my implementation so far, &lt;a href="mailto:zowens@eagleenvision.net" mce_href="mailto:zowens@eagleenvision.net" target="_blank"&gt;send me an email&lt;/a&gt; or &lt;a href="http://www.twitter.com/zowens" mce_href="http://www.twitter.com/zowens" target="_blank"&gt;DM me on Twitter&lt;/a&gt;. I have had a lot of great conversations about multi-tenancy so far and I greatly appreciate the feedback! &lt;/p&gt;
&lt;br&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2010%2f06%2f07%2fmulit-tenant-asp-net-mvc-controllers.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2010%2f06%2f07%2fmulit-tenant-asp-net-mvc-controllers.aspx" alt="kick it on DotNetKicks.com" border="0"&gt;&lt;/a&gt;
&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7520512" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/zowens/archive/tags/.NET/default.aspx" /><category term="ASP.NET" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET/default.aspx" /><category term="ASP.NET MVC" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET+MVC/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/zowens/archive/tags/C_2300_/default.aspx" /><category term="Multi-tenancy" scheme="http://weblogs.asp.net/zowens/archive/tags/Multi-tenancy/default.aspx" /></entry><entry><title>Multi-tenant ASP.NET – Foundation</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2010/05/29/multi-tenant-asp-net-foundation.aspx" /><id>http://weblogs.asp.net/zowens/archive/2010/05/29/multi-tenant-asp-net-foundation.aspx</id><published>2010-05-29T19:09:00Z</published><updated>2010-05-29T19:09:00Z</updated><content type="html">
&lt;p&gt;&lt;a href="http://weblogs.asp.net/zowens/archive/2010/05/26/multi-tenant-asp-net-mvc-introduction.aspx" target="_blank" mce_href="http://weblogs.asp.net/zowens/archive/2010/05/26/multi-tenant-asp-net-mvc-introduction.aspx"&gt;Part I – Introduction&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  
&lt;p&gt;In my &lt;a href="http://weblogs.asp.net/zowens/archive/2010/05/26/multi-tenant-asp-net-mvc-introduction.aspx" target="_blank" mce_href="http://weblogs.asp.net/zowens/archive/2010/05/26/multi-tenant-asp-net-mvc-introduction.aspx"&gt;last post&lt;/a&gt;, I talked about some of the goals of multi-tenancy in general and some hints about my implementation. Now it is time to put a little meat on the bones. I’m ready to share my ideas about how to implement a multi-tenant system on ASP.NET MVC and IIS7. I’m excited about some of the improvements in both areas in recent years… without some of the advancements in those technologies, I’m sure my code would have been much more complicated. &lt;a href="http://github.com/zowens/Multi-tenancy-Sample" target="_blank" mce_href="http://github.com/zowens/Multi-tenancy-Sample"&gt;(Here' is the link to the source code if you’d like to follow along :) )&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h3&gt;Modeling the tenant&lt;/h3&gt;  
&lt;p&gt;As I described in my first post on multi-tenancy, I’m working with a multi-tenancy architecture because of my job. At &lt;a href="http://www.eagleenvision.net/" target="_blank" mce_href="http://www.eagleenvision.net/"&gt;eagleenvision.net&lt;/a&gt;, we are contracted by clients to create websites, all with similar structure. Because of the similarity in implementation, I felt that it was necessary to eliminate our issue of maintaining different codebases for the same application. This is problematic in that some enhancements applied to some clients and not to others. &lt;/p&gt;
  
&lt;p&gt;Going back to multi-tenancy, a “tenant” to me is simply a client. This client has a few different attributes that are reflected in the model. Here’s the interface I use to describe a tenant.&lt;/p&gt;
  
&lt;pre style="border: 1px solid rgb(206, 206, 206); padding: 5px; background-color: rgb(251, 251, 251); min-height: 40px; width: 650px; overflow: auto;"&gt;&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;interface&lt;/span&gt; IApplicationTenant&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;{&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; ApplicationName { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    IFeatureRegistry EnabledFeatures { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    IEnumerable&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&amp;gt; UrlPaths { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    IContainer DependencyContainer { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    IViewEngine ViewEngine { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;The first thing you might notice is the UrlPaths property. Url paths are root URL paths that are mapped to a tenant. One of my requirements is that multiple bindings can exist for the same tenant. In some applications, this might not be a requirement, in which case you might want to make this a single string. &lt;/p&gt;

&lt;p&gt;The next thing you’ll notice is that a tenant has a dependency container. Like I alluded to in my previous post, my implementation uses 1:1 tenant to container. That is, every tenant has it’s own isolated container from the other tenants. This is an important aspect of the tenant and it really sets my implementation apart from the others I have seen. IoC is my friend… I intend to use StructureMap to do a lot of my bidding. This allows for a lot of flexibility and isolation that a multi-tenancy application should have. &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;Features&lt;/h3&gt;

&lt;p&gt;As you can see from the IApplicationTenant interface, a tenant has a list of features that are enabled by the tenant, called a feature registry. The feature registry is responsible for describing which features are enabled and which features the tenant is allowed to utilize. Here’s some relevant code for features.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;pre style="border: 1px solid rgb(206, 206, 206); padding: 5px; background-color: rgb(251, 251, 251); min-height: 40px; width: 650px; overflow: auto;"&gt;&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;interface&lt;/span&gt; IFeature&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;{&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; FeatureName { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;}&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;interface&lt;/span&gt; IComplexFeature : IFeature&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;{&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    IEnumerable&amp;lt;IFeature&amp;gt; SubFeatures { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;}&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;interface&lt;/span&gt; IFeatureRegistry&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;{&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    IEnumerable&amp;lt;IFeature&amp;gt; Features { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; IsEnabled(IEnumerable&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&amp;gt; featurePath);&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;A feature is a simple string. A complex feature is a feature that has sub features. The feature registry is responsible for the features enabled by the application tenant. Feature path describes the path to the lowest enabled sub feature. For example, if there’s a feature path such as A – B – C, A and B are complex features where B is a sub feature of A and C is a sub feature of B. This enables a lot of power in describing features and sub features. In MvcEx, I believe the concept of Module is similar. The distinction here is that a controller doesn’t have to be a feature, but it can be a feature. Here’s an example of some of the uses of the “Feature” attribute that will check the tenant’s feature registry once a controller has been called for execution. &lt;/p&gt;

&lt;pre style="border: 1px solid rgb(206, 206, 206); padding: 5px; background-color: rgb(251, 251, 251); min-height: 40px; width: 650px; overflow: auto;"&gt;&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// explicit feature paths&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; AccountController : Controller&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;{&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    [Feature("&lt;span style="color: rgb(139, 0, 0);"&gt;Account&lt;/span&gt;", "&lt;span style="color: rgb(139, 0, 0);"&gt;Login&lt;/span&gt;")]&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; ActionResult Login()&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; View("&lt;span style="color: rgb(139, 0, 0);"&gt;Login&lt;/span&gt;");&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    [Feature("&lt;span style="color: rgb(139, 0, 0);"&gt;Account&lt;/span&gt;", "&lt;span style="color: rgb(139, 0, 0);"&gt;Logout&lt;/span&gt;")]&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; ActionResult Logout()&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; View("&lt;span style="color: rgb(139, 0, 0);"&gt;Logout&lt;/span&gt;");&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    [Feature("&lt;span style="color: rgb(139, 0, 0);"&gt;Account&lt;/span&gt;", "&lt;span style="color: rgb(139, 0, 0);"&gt;Register&lt;/span&gt;")]&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; ActionResult Register()&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; View("&lt;span style="color: rgb(139, 0, 0);"&gt;Register&lt;/span&gt;");&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;}&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// implicit feature path from controller name&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;[Feature]&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; AccountController : Controller&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;{&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;// Account -&amp;gt; Login&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; ActionResult Login()&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; View("&lt;span style="color: rgb(139, 0, 0);"&gt;Login&lt;/span&gt;");&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;// Account -&amp;gt; Logout&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; ActionResult Logout()&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; View("&lt;span style="color: rgb(139, 0, 0);"&gt;Logout&lt;/span&gt;");&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;// Account -&amp;gt; Register&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; ActionResult Register()&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; View("&lt;span style="color: rgb(139, 0, 0);"&gt;Register&lt;/span&gt;");&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;The implementation of this attribute are a bit complicated. Just look at the &lt;a href="http://github.com/zowens/Multi-tenancy-Sample" target="_blank" mce_href="http://github.com/zowens/Multi-tenancy-Sample"&gt;source for a complete implementation&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I have also included a default implementation for IsEnabled in the Features class of the &lt;a href="http://github.com/zowens/Multi-tenancy-Sample" target="_blank" mce_href="http://github.com/zowens/Multi-tenancy-Sample"&gt;source code&lt;/a&gt;. It’s a pretty simple implementation this is hardcoded for IFeature and IComplexFeature. (This probably isn’t the best design for the API, but it suits my needs. Any suggestions on an API would be wonderful.)&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;Tenant Selection&lt;/h3&gt;

&lt;p&gt;One of the concepts that is essential to the delegation of requests to the various tenants is tenant selection. As you can see from the code below, there’s an interface that handles tenant selection and querying of the tenants (ITenantSelector). The tenant selector is responsible for getting the tenant for the request or an exception can be thrown if a tenant cannot be found. The default tenant selector queries the tenants based upon the root URL (“BaseUrl” in my implementation) and selects the first tenant with that URL. Obviously you can implement your own tenant selector that works off something else, such as a route value, etc. However, this sort of selection process makes sense for my implementation. &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;pre style="border: 1px solid rgb(206, 206, 206); padding: 5px; background-color: rgb(251, 251, 251); min-height: 40px; width: 650px; overflow: auto;"&gt;&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;interface&lt;/span&gt; ITenantSelector&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;{&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    IEnumerable&amp;lt;IApplicationTenant&amp;gt; Tenants { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    IApplicationTenant Select(RequestContext context);&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;}&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; DefaultTenantSelector : ITenantSelector&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;{&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; DefaultTenantSelector(IEnumerable&amp;lt;IApplicationTenant&amp;gt; tenants)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        Ensure.Argument.NotNull(tenants, "&lt;span style="color: rgb(139, 0, 0);"&gt;tenants&lt;/span&gt;");&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;.Tenants = tenants;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; IEnumerable&amp;lt;IApplicationTenant&amp;gt; Tenants { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;; }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; IApplicationTenant Select(RequestContext context)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        Ensure.Argument.NotNull(context, "&lt;span style="color: rgb(139, 0, 0);"&gt;context&lt;/span&gt;");&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; baseurl = context.HttpContext.BaseUrl().TrimEnd('/');&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        var valid = from tenant &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;.Tenants&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                    from path &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; tenant.UrlPaths&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                    where path.Trim().TrimEnd('/').Equals(baseurl, StringComparison.OrdinalIgnoreCase)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                    select tenant;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (!valid.Any())&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; TenantNotFoundException();&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; valid.First();&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;A related concept is container resolution. Because I have a lot of different containers floating around and I don’t want certain things knowing about tenants, there is an abstraction on container resolution. The default resolver selects a tenant. This code will be available with the &lt;a href="http://github.com/zowens/Multi-tenancy-Sample" target="_blank" mce_href="http://github.com/zowens/Multi-tenancy-Sample"&gt;source code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;Where’s the code?! &lt;/h3&gt;

&lt;p&gt;I have the source code on my &lt;a href="http://github.com/zowens/Multi-tenancy-Sample" target="_blank" mce_href="http://github.com/zowens/Multi-tenancy-Sample"&gt;GitHub account&lt;/a&gt;. Feel free to fork it or use to your whim. Make sure you keep up with my blog series to get the inside scoop. This post goes along with the f8cf7e5408eff7b659f3 commit. Be aware that the code introduced in this post are subject to change with subsequent commits. &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;Up Next&lt;/h3&gt;

&lt;p&gt;Next up is controller resolution. You’ll see how controllers are resolved and how my implementation uses controllers. You will be surprised at how simple the implementation is. In contrast, MvcEx uses a lot of Reflection.Emit to achieve “Dynamic Controllers”. While this may work for some applications, I think it’s a bit overkill. You will see what I mean in my next post.&lt;/p&gt;

&lt;p&gt;Until next time, leave questions in the comments, &lt;a href="http://twitter.com/zowens" target="_blank" mce_href="http://twitter.com/zowens"&gt;DM me on Twitter&lt;/a&gt;, or &lt;a href="mailto:zowens@eagleenvision.net" target="_blank" mce_href="mailto:zowens@eagleenvision.net"&gt;send me an email&lt;/a&gt;. &lt;/p&gt;
&lt;br&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2010%2f05%2f29%2fmulti-tenant-asp-net-foundation.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2010%2f05%2f29%2fmulti-tenant-asp-net-foundation.aspx" alt="kick it on DotNetKicks.com" border="0"&gt;&lt;/a&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7509716" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author></entry><entry><title>Multi-tenant ASP.NET MVC – Introduction</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2010/05/26/multi-tenant-asp-net-mvc-introduction.aspx" /><id>http://weblogs.asp.net/zowens/archive/2010/05/26/multi-tenant-asp-net-mvc-introduction.aspx</id><published>2010-05-27T00:56:00Z</published><updated>2010-05-27T00:56:00Z</updated><content type="html">
&lt;p&gt;I’ve read a few different blogs that talk about multi-tenancy and how to resolve some of the issues surrounding multi-tenancy. What I’ve come to realize is that these implementations &lt;b&gt;overcomplicate the issues and give only a muddy implementation!&lt;/b&gt; I’ve seen some &lt;i&gt;really&lt;/i&gt; illogical code out there. I have recently been building a multi-tenancy framework for internal use at &lt;a href="http://www.eagleenvision.net/" mce_href="http://www.eagleenvision.net/" target="_blank"&gt;eagleenvision.net&lt;/a&gt;. Through this process, I’ve realized a few different techniques to make building multi-tenant applications actually quite easy. I will be posting a few different entries over the issue and my personal implementation. In this first post, I will discuss what multi-tenancy means and how my implementation will be structured. &lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h3&gt;So what’s the problem?&lt;/h3&gt;  
&lt;p&gt;Here’s the deal. Multi-tenancy is basically a technique of code-reuse of web application code. A &lt;a href="http://en.wikipedia.org/wiki/Multitenancy" mce_href="http://en.wikipedia.org/wiki/Multitenancy" target="_blank"&gt;multi-tenant application&lt;/a&gt; is an application that runs a single instance for multiple clients. Here the “client” is different URL bindings on IIS using ASP.NET MVC. The problem with different instances of the, essentially, same application is that you have to spin up different instances of ASP.NET. As the number of running instances of ASP.NET grows, so does the memory footprint of IIS. &lt;a href="http://blog.stackexchange.com/post/459188139/speeding-up-stackexchange" mce_href="http://blog.stackexchange.com/post/459188139/speeding-up-stackexchange" target="_blank"&gt;Stack Exchange shifted its architecture to multi-tenancy March.&lt;/a&gt; As the blog post explains, multi-tenancy saves cost in terms of memory utilization and physical disc storage. If you use the same code base for many applications, multi-tenancy just makes sense. You’ll reduce the amount of work it takes to synchronize the site implementations and you’ll thank your lucky stars &lt;i&gt;later&lt;/i&gt; for choosing to use one application for multiple sites. Multi-tenancy allows the freedom of extensibility while relying on some pre-built code. &lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h3&gt;You’d think this would be simple.&lt;/h3&gt;  
&lt;p&gt;I have actually seen a real lack of reference material on the subject in terms of ASP.NET MVC. This is somewhat surprising given the number of users of ASP.NET MVC. However, I will certainly fill the void ;). Implementing a multi-tenant application takes a little thinking. It’s not straight-forward because the possibilities of implementation are endless. &lt;b&gt;I have yet to see a great implementation of a multi-tenant MVC application&lt;/b&gt;. The only one that comes close to what I have in mind is Rob Ashton’s implementation &lt;a href="http://www.codeofrob.com/category/10.aspx" mce_href="http://www.codeofrob.com/category/10.aspx" target="_blank"&gt;(all the entries are listed on this page).&lt;/a&gt; There’s some &lt;i&gt;really&lt;/i&gt; nasty code in there… something I’d really like to avoid. He has also &lt;a href="http://mvcex.codeplex.com/" mce_href="http://mvcex.codeplex.com/" target="_blank"&gt;written a library&lt;/a&gt; (MvcEx) that attempts to aid multi-tenant development. This code is even worse, in my honest opinion. Once I start seeing Reflection.Emit, I have to assume the worst :)&lt;/p&gt;
  
&lt;p&gt;In all seriousness, if his implementation makes sense to you, &lt;i&gt;use it!&lt;/i&gt; It’s a fine implementation that should be given a look. At least look at the code. &lt;/p&gt;
  
&lt;p&gt;I will reference MvcEx going forward as a comparison to my implementation. I will explain why my approach differs from MvcEx and how it is better or worse (hopefully better). &lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h3&gt;Core Goals of my Multi-Tenant Implementation&lt;/h3&gt;  
&lt;p&gt;The first, and foremost, goal is to use Inversion of Control containers to my advantage. As you will see throughout this series, I pass around containers quite frequently and rely on their use heavily. I will be using StructureMap in my implementation. However, you could probably use your favorite IoC tool instead. &amp;lt;RANT&amp;gt; However, please don’t be stupid and abstract your IoC tool. Each IoC is powerful and by abstracting the capabilities, you’re doing yourself a real disservice. Who in the world swaps out IoC tools…? No one!&amp;lt;/RANT&amp;gt; (It had to be said.) I will outline some of the goodness of StructureMap as we go along. This is really an invaluable tool in my tool belt and simple to use in my multi-tenant implementation. &lt;/p&gt;
  
&lt;p&gt;The second core goal is to represent a tenant as easily as possible. Just as a dependency container will be a first-class citizen, so will a tenant. This allows us to easily extend and use tenants. This will also allow different ways of “plugging in” tenants into your application. In my implementation, there will be a single dependency container for a single tenant. This will enable isolation of the dependencies of the tenant. &lt;/p&gt;
  
&lt;p&gt;The third goal is to use composition as a means to delegate “core” functions out to the tenant. More on this later.&lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h3&gt;Features&lt;/h3&gt;  
&lt;p&gt;In MvcExt, “Modules” are a code element of the infrastructure. I have simplified this concept and have named this “Features”. A feature is a simple element of an application. Controllers can be specified to have a feature and actions can have “sub features”. Each tenant can select features it needs and the other features will be hidden to the tenant’s users. My implementation doesn’t require something to be a feature. A controller can be common to all tenants. For example, (as you will see) I have a “Content” controller that will return the CSS, Javascript and Images for a tenant. This is common logic to all tenants and shouldn’t be hidden or considered a “feature”; Content is a core component. &lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h3&gt;Up next&lt;/h3&gt;  
&lt;p&gt;My next post will be all about the code. I will reveal some of the foundation to the way I do multi-tenancy. I will have posts dedicated to Foundation, Controllers, Views, Caching, Content and how to setup the tenants. Each post will be in-depth about the issues and implementation details, while adhering to my core goals outlined in this post. As always, comment with questions of &lt;a href="http://www.twitter.com/zowens" mce_href="http://www.twitter.com/zowens" target="_blank"&gt;DM me on twitter&lt;/a&gt; or &lt;a href="mailto:zowens@eagleenvision.net" mce_href="mailto:zowens@eagleenvision.net" target="_blank"&gt;send me an email&lt;/a&gt;. &lt;/p&gt;
&lt;br&gt;&lt;br&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2010%2f05%2f26%2fmulti-tenant-asp-net-mvc-introduction.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2010%2f05%2f26%2fmulti-tenant-asp-net-mvc-introduction.aspx" alt="kick it on DotNetKicks.com" border="0"&gt;&lt;/a&gt;
&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7507129" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/zowens/archive/tags/.NET/default.aspx" /><category term="ASP.NET" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET/default.aspx" /><category term="ASP.NET MVC" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET+MVC/default.aspx" /><category term="ASP.NET Performance" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET+Performance/default.aspx" /><category term="Multi-tenancy" scheme="http://weblogs.asp.net/zowens/archive/tags/Multi-tenancy/default.aspx" /></entry><entry><title>Filter IQueryable by String for ASP.NET MVC</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2010/01/22/filter-iqueryable-by-string-for-asp-net-mvc.aspx" /><id>http://weblogs.asp.net/zowens/archive/2010/01/22/filter-iqueryable-by-string-for-asp-net-mvc.aspx</id><published>2010-01-22T18:44:00Z</published><updated>2010-01-22T18:44:00Z</updated><content type="html">
&lt;p&gt;In ASP.NET web applications, mostly seen in MVC, it is really nice to have a standard way to filter a query based on a pre-defined set of combinators. It is often annoying to have to test for different Request parameters in a controller action for MVC or on a page for WebForms. In this post I will describe what I’m calling StringToIQueryable, an open source parser library I built in a few days that I’m using on a few projects. Basically you feed a string to the parser and it manipulates an IQueryable according to a set of pre-defined combinators. The syntax is URL-friendly… that was the goal. Hopefully I will show you in this post how useful this tool can be for both consumption and extension. &lt;/p&gt;
  
&lt;p&gt;I figure I might as well tell you where the source is first. I decided to use GitHub for this project… so it is &lt;a href="http://github.com/zowens/StringToIQueryable" mce_href="http://github.com/zowens/StringToIQueryable" target="_blank"&gt;hosted on GitHub here&lt;/a&gt;. Download it and have at it!&lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h2&gt;MONADS MONADS MONADS!&lt;/h2&gt;  
&lt;p&gt;If Steve Ballmer were a functional programmer, he’d FOR SURE be screaming MONADS MONADS MONADS! I’ve discussed monads &lt;a href="http://weblogs.asp.net/zowens/archive/2009/09/04/maybe-monad-my-c-version.aspx" mce_href="http://weblogs.asp.net/zowens/archive/2009/09/04/maybe-monad-my-c-version.aspx" target="_blank"&gt;in the past&lt;/a&gt; (with a little less understanding than I have now :) ). Basically a parser (like what I’ve implemented) is like the IEnumerable monad in C#. There is a whole list of combinators you can use to define exactly what a parser does to arrive at a result. Intermediate results are stored as pairs of the parsed value and the string left to parse. I have defined a few simple combinators (I will talk about Or, When, and OrWhen specifically) that are useful. I’ve also defined some of the standard LINQ query operators… so you can easily use a parser as a LINQ query. As Erik Meijer says, “everything is a query!”. &lt;/p&gt;
  &lt;h2&gt;&amp;nbsp;&lt;/h2&gt;  &lt;h2&gt;Parser Internals&lt;/h2&gt;  
&lt;p&gt;The parser has really 2 important internals, a delegate and a storage container for the result and “rest” string. Here’s the code for each.    &lt;br&gt;&lt;/p&gt;
  
&lt;pre style="border: 1px solid rgb(206, 206, 206); padding: 5px; background-color: rgb(251, 251, 251); min-height: 40px; width: 650px; overflow: auto;"&gt;&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// generic delegate for getting result/rest&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;delegate&lt;/span&gt; ParserResult&amp;lt;T&amp;gt; Parse&amp;lt;T&amp;gt;(&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; input);&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// class for holding the result and rest&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;sealed&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; ParserResult&amp;lt;T&amp;gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;{&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; ParserResult(T parsed, &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; remaining)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        Parsed = parsed;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        Remaining = remaining;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; T Parsed { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;; }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; Remaining { &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;; }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;You’ll notice I’m using a generic… so you can pretty much parse anything here. The Parse delegate takes an input and returns a parser result. The parser’s job is to make sure everything is parsed correctly. This is in the ParserLib project of my source code. &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;The Combinators&lt;/h2&gt;

&lt;p&gt;Combinators in functional programming are kind of an awesome thing. The main operators are bind and return. Bind is implemented with Select, SelectMany and Then. These are really the important operators, but Or, When, and OrWhen are what I find particularly useful when dealing with constraints and possibilities in my URL to IQueryable configuration. &lt;/p&gt;

&lt;p&gt;Or is a combinator that takes 2 Parse delegates. If the first should return null (indication of failure) then the result of the Parse will be the result of the second delegate. &lt;/p&gt;

&lt;p&gt;When is a unary parser (takes only 1 parser) and takes a string predicate. If the predicate is satisfied by the input, then the result will be delegated to the Parse instance. Otherwise the parser fails and null is returned. This is especially useful in my implementation of String to IQueryable because I associate a beginning keyword to a parser.&lt;/p&gt;

&lt;p&gt;OrWhen is a hybrid of Or and When that I built to mainly chain my parsers together. OrWhen takes a string predicate (like When) and 2 parsers (like Or). If the result isn’t null for the first parser, then that is the result. Otherwise the string is tested against the predicate and fails if the predicate fails or returns the result of the parse if the string predicate passes. &lt;/p&gt;

&lt;p&gt;If you download the code, you will see these defined in the ParserLib project. I’m not going to show you the implementation for the sake of brevity. But I would recommend having a look. &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;The Query Parser&lt;/h2&gt;

&lt;p&gt;Ah now to the good stuff. QuerParser is it’s own separate project in my solution. I have defined what I call “ParserExpressions”, which mostly conform to the LINQ standard query operators. The expressions are take, skip, where, sort, and page (which isn’t a standard query operator). I will discuss why some of the other operators were not implemented in a minute. But you do have the option of extending the parser by creating your own operators. Here is the interface that all the expressions use. &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;pre style="border: 1px solid rgb(206, 206, 206); padding: 5px; background-color: rgb(251, 251, 251); min-height: 40px; width: 650px; overflow: auto;"&gt;&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;interface&lt;/span&gt; IParserExpression&amp;lt;T&amp;gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;{&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    IQueryable&amp;lt;T&amp;gt; Map(IQueryable&amp;lt;T&amp;gt; queriable);&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;That’s it. Just one method (plus a ToString… more on that in a bit). The expression has to be able to transform an IQueryable using the Map method. How this method works is up to the expression. For example, the take expression transforms the IQueryable by calling the Take method and passing an integer (which is passed in the constructor) to generate a new IQueryable. You will see how this is useful in a minute.&lt;/p&gt;

&lt;p&gt;It is important to note that the ParserExpression does not &lt;i&gt;parse&lt;/i&gt; the string. They simply act as containers for state until the IQueryable is mapped upon. The parse delegate, as I said before, is the logic behind the parser.&lt;/p&gt;

&lt;p&gt;Let’s now have a look at the parse code. &lt;/p&gt;

&lt;pre style="border: 1px solid rgb(206, 206, 206); padding: 5px; background-color: rgb(251, 251, 251); min-height: 40px; width: 650px; overflow: auto;"&gt;&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; StringQueryParser&amp;lt;T&amp;gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;{&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; expressions;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; StringQueryParser(&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; exprs)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        expressions = exprs.ToLower();&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;protected&lt;/span&gt; Predicate&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&amp;gt; StartsWith(&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; test)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; str =&amp;gt; str.StartsWith(test);&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;virtual&lt;/span&gt; Parse&amp;lt;IParserExpression&amp;lt;T&amp;gt;&amp;gt; Parsers&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; Parser.When(StartsWith(ParserConstants.ExpressionSeparator.ToString()), IgnoreSeparatorParser)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                     .OrWhen(StartsWith(ParserConstants.PageIndicator), PageParser)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                     .OrWhen(StartsWith(ParserConstants.SkipIndicator), SkipParser)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                     .OrWhen(StartsWith(ParserConstants.TakeIndicator), TakeParser)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                     .OrWhen(StartsWith(ParserConstants.SortIndicator), SortParser)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                     .Or(WhereParser); &lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; IEnumerable&amp;lt;IParserExpression&amp;lt;T&amp;gt;&amp;gt; Parse()&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;.IsNullOrEmpty(expressions))&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; List&amp;lt;IParserExpression&amp;lt;T&amp;gt;&amp;gt;();&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; Parsers.Repeat()&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                      .Invoke(expressions)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                      .Parsed&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                      .Where(x =&amp;gt; x != &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;);&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; IQueryable&amp;lt;T&amp;gt; Map(IQueryable&amp;lt;T&amp;gt; queriable)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (var parseExpr &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; Parse())&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;            queriable = parseExpr.Map(queriable);&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; queriable;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;// the parsers have been removed for brevity. once&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;// again, download the code for have a look at the&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;// entire parser code&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    ......&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;As you’ll see I’ve removed the parsers. Just go download the code to look at the parser code. Those are generally unimportant for this post. I can go in-depth if there is a demand for it. &lt;/p&gt;

&lt;p&gt;I’ve implemented a Parsers property that returns a composite parser that encapsulates the logic to parse the string. If you were to override this class, you’d want to override the Parsers property to append your own parsers or just completely start anew. Each indicator (page, take, sort and skip) will be covered in the next section, but basically we filter an expression down to it’s parts and create the expression from there. You’ll have a better idea of how to form these expressions by the end. Don’t worry :) So really there’s no surprises here (other than repeat… that’s in ParserLib. Kind of intuitive… you parse until the input is empty). When all is said and done, the IQueryable is mapped through all the expressions generated by the string. Here’s how accomplish a parse in an ASP.NET MVC controller. &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;pre style="border: 1px solid rgb(206, 206, 206); padding: 5px; background-color: rgb(251, 251, 251); min-height: 40px; width: 650px; overflow: auto;"&gt;&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; MyController : Controller&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;{&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    ....&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;// option #1, instantiate a StringQueryParser&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; ActionResult List(&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; query)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 128, 0);"&gt;// replace with your data access&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        IQueryable&amp;lt;User&amp;gt; usersQueryable = Session.Linq&amp;lt;User&amp;gt;();&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 128, 0);"&gt;// do the parsing&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        var parser = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; StringQueryParser&amp;lt;User&amp;gt;(query);&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        usersQueryable = parser.Map(usersQueryable);&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 128, 0);"&gt;// manipulate and parse as needed&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; Json(usersQueryable.ToList());&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;// option #2, use the extension method&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; ActionResult List2(&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; query)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    {&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 128, 0);"&gt;// replace with your data access&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        var usersQueryable = Session.Linq&amp;lt;User&amp;gt;().Parse(query);        &lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 128, 0);"&gt;// manipulate and parse as needed&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; Json(usersQueryable.ToList());&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    }&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;    ......&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;I personally prefer option 2. That’s a little neater, but both do the same thing. You will want to setup a “catch all” route in MVC that maps to this. &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;How to form expressions&lt;/h2&gt;

&lt;p&gt;At this point, I’ve been blabbering about the internals of the parser. Some of you probably don’t care… which is actually fine with me. The important part of this whole project is the real world application. Basically you will be passing a well-formed expression to your controllers that will manipulate the IQueryable accordingly. Here’s the low down on how to do this by string.&lt;/p&gt;

&lt;h3&gt;Singular Expressions&lt;/h3&gt;

&lt;p&gt;/skip-5/&lt;/p&gt;

&lt;p&gt;&lt;i&gt;skips the first 5 elements&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;/take-4/&lt;/p&gt;

&lt;p&gt;&lt;i&gt;returns only 4 elements&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;/take-all/&lt;/p&gt;

&lt;p&gt;&lt;i&gt;returns all elements&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;/page-5-11/&lt;/p&gt;

&lt;p&gt;&lt;i&gt;returns a paged result on page 5 (1-based) with page size 11&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;/page-5/&lt;/p&gt;

&lt;p&gt;&lt;i&gt;returns a paged result on page 5, default page size is 10 in my library&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;/sort-name/&lt;/p&gt;

&lt;p&gt;&lt;i&gt;applies an ascending sort on the name property&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;/sort-desc-name/&lt;/p&gt;

&lt;p&gt;&lt;i&gt;applies a descending sort on the name property&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;/sort-name,age,birthmonth/&lt;/p&gt;

&lt;p&gt;&lt;i&gt;applies an ascending sort on name property, then ascending sort on age property, then on birthmonth property&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;/sort-desc-name,age,birthmonth/&lt;/p&gt;

&lt;p&gt;&lt;i&gt;applies a descending sort on the name property, then ascending sort on age property, then on birthmonth property&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;/name-equals-jon/&lt;/p&gt;

&lt;p&gt;&lt;i&gt;applies a where name equals jon&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;/age-greaterthan-4/&lt;/p&gt;

&lt;p&gt;&lt;i&gt;applies a greater than 4 where&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;/name-not-null/&lt;/p&gt;

&lt;p&gt;applies a name must not be null constraint&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;For the where expression, there are a lot of combinators that we support (equals, like, not, greater than, less than, greater than or equal, and less than or equal). We also support null as a “keyword”. So don’t expect your name properties to be null or something… that would be interpreted as null by the parser and not “null” as in the string.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;&lt;/h3&gt;
&lt;h3&gt;Multiple Expressions&lt;/h3&gt;

&lt;p&gt;It is particularly useful to chain these expressions together. Here’s some examples. Feel free to combine these however you’d like.&lt;/p&gt;

&lt;p&gt;/page-5/name-equals-jim/age-lessthan-90/age-greaterthanequal-4/&lt;/p&gt;

&lt;p&gt;/skip-4/take-3/name-equals-kim/haschainsaw-equals-true/&lt;/p&gt;

&lt;p&gt;/gender-equals-female/page-5-10/&lt;/p&gt;

&lt;p&gt;The order is typically of no importance except for using skip and take together. It is a good idea to use a skip before a take. That’s just been my experience. You’ll notice in these examples (which are fictitious, by the way :)) that we support a lot of different types. Strings, int, double, float, enum, and more. In the future I’ll add an interceptor that you can parse where’s differently.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;How properties work&lt;/h3&gt;

&lt;p&gt;When designing this solution, I had this idea that you might want to name a property differently or ignore a property. I have added two attributes (ParserIgnore and ParserPropertyName). The parser takes these into effect. If you pass the parser an ignored property then the constraint isn’t parsed. You can define a parser property name to a property and that name will be used in determining which property to apply a constraint. This avoids the issue of property name conflicts… you have to resolve those yourself using the property name attribute for the expected behavior to work when you have the same property name in different case.&lt;/p&gt;

&lt;p&gt;Also, it’s worth mentioning that everything is parsed in lower-case. So the case in your expressions are of no importance… it’ll just be changed to lower-case upon parsing. &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;Using the generator&lt;/h3&gt;

&lt;p&gt;Sometimes you don’t want to form these by hand… concatenation isn’t exactly useful when you’re using paged data, for example. Because of this, I’ve built a generator. Basically you’d pass a few IParserExpression’s to this generator and it’ll generate the string for the query for you. The generator uses the ToString method on each IParserExpression. It is important to note that you &lt;i&gt;must&lt;/i&gt; override ToString for the generator to work on your custom expressions. You can take a look at the code yourself, but I thought I might show you an example of how to use this.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;pre style="border: 1px solid rgb(206, 206, 206); padding: 5px; background-color: rgb(251, 251, 251); min-height: 40px; width: 650px; overflow: auto;"&gt;&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;....&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;h2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;My MVC Page&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;h2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;....&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;a&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;href&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"#&amp;lt;% new StringQueryGenerator&amp;lt;User&amp;gt;(new IParserExpression&amp;lt;User&amp;gt;[] &lt;br&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                                            { &lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                                                 new WhereExpression&amp;lt;User&amp;gt;(u =&amp;gt; u.Name, WhereCombinator.equals, "&lt;span style="color: rgb(255, 0, 0);"&gt;foo&lt;/span&gt;"),&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                                                 &lt;span style="color: rgb(255, 0, 0);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;PageExpression&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(255, 0, 0);"&gt;User&lt;/span&gt;&amp;gt;(&lt;span style="color: rgb(255, 0, 0);"&gt;4&lt;/span&gt;, &lt;span style="color: rgb(255, 0, 0);"&gt;10&lt;/span&gt;)&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(255, 255, 255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;                                            }).&lt;span style="color: rgb(255, 0, 0);"&gt;Generate&lt;/span&gt;() %&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
&lt;pre style="background-color: rgb(251, 251, 251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px;"&gt;......&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;This will generate a string like /name-equals-foo/page-4/ . Both where and sort have a constructor overload that you can pass in a property expression… so you don’t have to use the property name as a string.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Wow that was a long blog post :) I hope that you’ve seen that this is useful for ASP.NET MVC in particular and in an instance where a user can define their own query. There are many examples of this sort of thing on the web where people are using this approach to filter results based on a clean-looking query. I hope you check out the source code and let me know if you have any suggestions or comments on my implementation. And with that I say &lt;b&gt;DEATH TO QUERY STRING FILTERING! &lt;/b&gt;&lt;/p&gt;

&lt;br&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2010%2f01%2f22%2ffilter-iqueryable-by-string-for-asp-net-mvc.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2010%2f01%2f22%2ffilter-iqueryable-by-string-for-asp-net-mvc.aspx" alt="kick it on DotNetKicks.com" border="0"&gt;&lt;/a&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7319974" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/zowens/archive/tags/.NET/default.aspx" /><category term="ASP.NET" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET/default.aspx" /><category term="ASP.NET MVC" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET+MVC/default.aspx" /><category term="Conversion" scheme="http://weblogs.asp.net/zowens/archive/tags/Conversion/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/zowens/archive/tags/C_2300_/default.aspx" /><category term="Functional Programming" scheme="http://weblogs.asp.net/zowens/archive/tags/Functional+Programming/default.aspx" /><category term="Monads" scheme="http://weblogs.asp.net/zowens/archive/tags/Monads/default.aspx" /><category term="Open Source" scheme="http://weblogs.asp.net/zowens/archive/tags/Open+Source/default.aspx" /></entry><entry><title>jQuery DataTables Plugin Meets C#</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2010/01/19/jquery-datatables-plugin-meets-c.aspx" /><id>http://weblogs.asp.net/zowens/archive/2010/01/19/jquery-datatables-plugin-meets-c.aspx</id><published>2010-01-19T20:32:54Z</published><updated>2010-01-19T20:32:54Z</updated><content type="html">&lt;p&gt;Over the weekend, I was doing some work on the internal CMS we use over at &lt;a href="http://www.eagleenvision.net/" target="_blank"&gt;eagleenvision.net&lt;/a&gt; and I wanted to scrap my custom table implementation for a table system that would use JSON to return data rather than have the data be statically allocated on the page. Basically I wanted to have the ability to refresh, etc for editing purposes. My little table marker was too much code for something so simple.&lt;/p&gt;  &lt;p&gt;I’m a HUGE fan of jQuery, especially of the recent changes in jQuery 1.4. We have already made a significant investment in jQuery code for our CMS and I didn’t want to simply add another library or framework into the mix… by that I mean I didn’t want to throw in the Ext framework, which specialized in UI controls rather than general purpose JavaScript. &lt;/p&gt;  &lt;p&gt;I stumbled upon the &lt;a href="http://www.datatables.net/" target="_blank"&gt;jQuery DataTables plugin&lt;/a&gt;. It has a lot of great features… one of which is the ability to have server-side processing of your data. The examples on the site are written with PHP, as are the downloadable demos. I don’t use PHP, I use ASP.NET :). So I had to write my own library to process the incoming request. DataTables has a set of pre-defined request variables that are passed to the server for processing. A successful implementation will take all these variables into account and send the correct data back per these variables. (To see a complete list, check out &lt;a href="http://datatables.net/usage/server-side" target="_blank"&gt;the server-side usage page&lt;/a&gt;). &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Our friend, IQueriable&lt;/h2&gt;  &lt;p&gt;If you’re a C# developer, there’s no way you &lt;em&gt;don’t&lt;/em&gt; already know about LINQ… (double negatives… oops…. every C# knows about LINQ, or they’re not really current with technology… that’s better :) ). This includes VB people as well. IQueriable is the fundamental type of LINQ that drives the functionality of the various sequence operators. In my implementation of DataTables processing, I wanted to leverage LINQ so that you could throw this thing an IQueriable from Linq2Sql, Linq to NHibernate, Entity Framework, LightSpeed, in-memory list, or ANYTHING that has IQueriable functionality and it would just work. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;How to output&lt;/h2&gt;  &lt;p&gt;The DataTables plugin accepts either JSON or XML… whichever jQuery will parse. My opinion is &lt;em&gt;never use XML with JavaScript&lt;/em&gt;. It’s slower and there’s no point to using XML over JSON… especially in .NET where there are built-in JSON serializers. Having said that, you could certainly use XML… although I haven’t tested my code for this, I think (&lt;em&gt;in theory) &lt;/em&gt;it will work the same. He’s the output type, which should be serialized into JSON or XML, which I will cover in a minute.&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; FormatedList
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; FormatedList()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; sEcho { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; iTotalRecords { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; iTotalDisplayRecords { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; List&amp;lt;List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;&amp;gt; aaData { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; sColumns { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Import(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] properties)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        sColumns = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; properties.Length; i++)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            sColumns += properties[i];
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (i &amp;lt; properties.Length - 1)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                sColumns += &amp;quot;&lt;span style="color: #8b0000"&gt;,&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Basically the only interesting thing here is the output of the columns. I made a custom Import method that just takes a list of properties and forms the column string that DataTables will parse. Other than that the code here is just basic property holding.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;ASP.NET MVC&lt;/h3&gt;

&lt;p&gt;Readers of my blog and twitter will know I am also a HUGE fan of ASP.NET MVC. I don’t think I’ll ever return to ASP.NET WebForms. But who knows. Anyways, here’s how you will output the thing in MVC&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ActionResult List()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    IQueriable&amp;lt;User&amp;gt; users = Session.Linq&amp;lt;User&amp;gt;();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Request[&amp;quot;&lt;span style="color: #8b0000"&gt;sEcho&lt;/span&gt;&amp;quot;] != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        var parser = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DataTableParser&amp;lt;User&amp;gt;(Request, users);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Json(parser.Parse());
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Json(users);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;You’ll notice that I referenced DataTableParser, which I will get to in a minute. This takes an HttpRequestBase (or an HttpRequest) and an IQueriable of whatever type. It will output a new FormattedList in the parse method, which you will return via JSON (which is serialized in the Json method for MVC).&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;ASP.NET Webservices&lt;/h3&gt;

&lt;p&gt;While I don’t claim to be an expert at ASP.NET Webservice, this I can handle :). He’s how would would do the same thing in ASP.NET Webservices.&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Web.Script.Serialization;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Linq;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;...
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyWebservice : System.Web.Services.WebService
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; MyMethod()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #008000"&gt;// change the following line per your data configuration&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        IQueriable&amp;lt;User&amp;gt; users = Session.Linq&amp;lt;User&amp;gt;();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        response.ContentType = &amp;quot;&lt;span style="color: #8b0000"&gt;application/json&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(Request[&amp;quot;&lt;span style="color: #8b0000"&gt;sEcho&lt;/span&gt;&amp;quot;] != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            var parser = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DataTableParser&amp;lt;User&amp;gt;(Request, users);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; JavaScriptSerializer().Serialize(parser.Parse());
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; JavaScriptSerializer().Serialize(users); 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;This is the same code… it just uses webservices and the JavaScriptSerializer (which MVC uses under the covers) to serialize the FormatedList object.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;It should be noted that you should ALWAYS check if the request is a DataTables request (which is what that sEcho business is all about). &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;The Parser&lt;/h2&gt;

&lt;p&gt;Now is the time to show you my parser. I have taken out my code comments to keep this short on my blog… but you can &lt;a href="http://weblogs.asp.net/blogs/zowens/DataTables.zip" target="_blank"&gt;download my code from here&lt;/a&gt; and the comments should explain what is going on. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; DataTableParser&amp;lt;T&amp;gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; INDIVIDUAL_SEARCH_KEY_PREFIX = &amp;quot;&lt;span style="color: #8b0000"&gt;sSearch_&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; INDIVIDUAL_SORT_KEY_PREFIX = &amp;quot;&lt;span style="color: #8b0000"&gt;iSortCol_&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; INDIVIDUAL_SORT_DIRECTION_KEY_PREFIX = &amp;quot;&lt;span style="color: #8b0000"&gt;sSortDir_&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; DISPLAY_START = &amp;quot;&lt;span style="color: #8b0000"&gt;iDisplayStart&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; DISPLAY_LENGTH = &amp;quot;&lt;span style="color: #8b0000"&gt;iDisplayLength&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ECHO = &amp;quot;&lt;span style="color: #8b0000"&gt;sEcho&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ASCENDING_SORT = &amp;quot;&lt;span style="color: #8b0000"&gt;asc&lt;/span&gt;&amp;quot;;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IQueryable&amp;lt;T&amp;gt; _queriable;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; HttpRequestBase _httpRequest;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; Type _type;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; PropertyInfo[] _properties;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; DataTableParser(HttpRequestBase httpRequest, IQueryable&amp;lt;T&amp;gt; queriable)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        _queriable = queriable;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        _httpRequest = httpRequest;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        _type = &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(T);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        _properties = _type.GetProperties();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; DataTableParser(HttpRequest httpRequest, IQueryable&amp;lt;T&amp;gt; queriable)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        : &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; HttpRequestWrapper(httpRequest), queriable)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    { }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; FormatedList Parse()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        var list = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FormatedList();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        list.Import(_properties.Select(x =&amp;gt; x.Name).ToArray());
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        list.sEcho = &lt;span style="color: #0000ff"&gt;int&lt;/span&gt;.Parse(_httpRequest[ECHO]);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        list.iTotalRecords = _queriable.Count();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        ApplySort();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; skip = 0, take = 10;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;int&lt;/span&gt;.TryParse(_httpRequest[DISPLAY_START], &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; skip);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;int&lt;/span&gt;.TryParse(_httpRequest[DISPLAY_LENGTH], &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; take);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        list.aaData = _queriable.Where(ApplyGenericSearch)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                .Where(IndividualPropertySearch)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                .Skip(skip)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                .Take(take)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                .Select(SelectProperties)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                .ToList();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        list.iTotalDisplayRecords = list.aaData.Count;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; list;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ApplySort()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; key &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; _httpRequest.Params.AllKeys.Where(x =&amp;gt; x.StartsWith(INDIVIDUAL_SORT_KEY_PREFIX)))
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; sortcolumn = &lt;span style="color: #0000ff"&gt;int&lt;/span&gt;.Parse(_httpRequest[key]);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (sortcolumn &amp;lt; 0 || sortcolumn &amp;gt;= _properties.Length)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; sortdir = _httpRequest[INDIVIDUAL_SORT_DIRECTION_KEY_PREFIX + key.Replace(INDIVIDUAL_SORT_KEY_PREFIX, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty)];
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            var paramExpr = Expression.Parameter(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(T), &amp;quot;&lt;span style="color: #8b0000"&gt;val&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            var propertyExpr = Expression.Lambda&amp;lt;Func&amp;lt;T, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;(Expression.Property(paramExpr, _properties[sortcolumn]), paramExpr);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(sortdir) || sortdir.Equals(ASCENDING_SORT, StringComparison.OrdinalIgnoreCase))
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                _queriable = _queriable.OrderBy(propertyExpr);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                _queriable = _queriable.OrderByDescending(propertyExpr);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Expression&amp;lt;Func&amp;lt;T, List&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; SelectProperties
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #008000"&gt;// &lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;value&lt;/span&gt; =&amp;gt; _properties.Select
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                        (
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                            prop =&amp;gt; (prop.GetValue(&lt;span style="color: #0000ff"&gt;value&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;[0]) ?? &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty).ToString()
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                        )
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                       .ToList();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Expression&amp;lt;Func&amp;lt;T, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; IndividualPropertySearch
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            var paramExpr = Expression.Parameter(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(T), &amp;quot;&lt;span style="color: #8b0000"&gt;val&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            Expression whereExpr = Expression.Constant(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;); &lt;span style="color: #008000"&gt;// default is val =&amp;gt; True&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; key &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; _httpRequest.Params.AllKeys.Where(x =&amp;gt; x.StartsWith(INDIVIDUAL_SEARCH_KEY_PREFIX)))
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            {
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; property = -1;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;.TryParse(_httpRequest[key].Replace(INDIVIDUAL_SEARCH_KEY_PREFIX, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty), &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; property) 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                    || property &amp;gt;= _properties.Length || &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(_httpRequest[key]))
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                    &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;; &lt;span style="color: #008000"&gt;// ignore if the option is invalid&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; query = _httpRequest[key].ToLower();
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                var toStringCall = Expression.Call(
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                    Expression.Call(
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                        Expression.Property(paramExpr, _properties[property]), &amp;quot;&lt;span style="color: #8b0000"&gt;ToString&lt;/span&gt;&amp;quot;, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Type[0]),
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                    &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;).GetMethod(&amp;quot;&lt;span style="color: #8b0000"&gt;ToLower&lt;/span&gt;&amp;quot;, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Type[0]));
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                whereExpr = Expression.And(whereExpr, 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                           Expression.Call(toStringCall, 
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                                           &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;).GetMethod(&amp;quot;&lt;span style="color: #8b0000"&gt;Contains&lt;/span&gt;&amp;quot;), 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                                           Expression.Constant(query)));
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Expression.Lambda&amp;lt;Func&amp;lt;T, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt;(whereExpr, paramExpr);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Expression&amp;lt;Func&amp;lt;T, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; ApplyGenericSearch
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; search = _httpRequest[&amp;quot;&lt;span style="color: #8b0000"&gt;sSearch&lt;/span&gt;&amp;quot;];
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(search) || _properties.Length == 0)
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; x =&amp;gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            var searchExpression = Expression.Constant(search.ToLower());
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            var paramExpression = Expression.Parameter(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(T), &amp;quot;&lt;span style="color: #8b0000"&gt;val&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            var propertyQuery = (from property &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; _properties
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                let tostringcall = Expression.Call(
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                                    Expression.Call(
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                                        Expression.Property(paramExpression, property), &amp;quot;&lt;span style="color: #8b0000"&gt;ToString&lt;/span&gt;&amp;quot;, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Type[0]),
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                                        &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;).GetMethod(&amp;quot;&lt;span style="color: #8b0000"&gt;ToLower&lt;/span&gt;&amp;quot;, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Type[0]))
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                select Expression.Call(tostringcall, &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;).GetMethod(&amp;quot;&lt;span style="color: #8b0000"&gt;Contains&lt;/span&gt;&amp;quot;), searchExpression)).ToArray();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                                
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            Expression compoundExpression = propertyQuery[0];
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 1; i &amp;lt; propertyQuery.Length; i++)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                compoundExpression = Expression.Or(compoundExpression, propertyQuery[i]);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Expression.Lambda&amp;lt;Func&amp;lt;T, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt;(compoundExpression, paramExpression);
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }
&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Caveat&lt;/h2&gt;

&lt;p&gt;Currently there’s a bug here, that I need to research :). If you have a boolean property and apply a sort on it, you’ll get an exception because I am trying to cast it as an object with the Expression.Lambda&amp;lt;Func&amp;lt;T, object&amp;gt;&amp;gt; call. I’ll look into this and update this blog post accordingly. If you can provide any help, that would be great :)&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This is just a simple example of parsing a request and mutating IQueriable acordingly. I hope this helps &lt;em&gt;someone&lt;/em&gt; out there who would like to use C# with the DataTables plugin. Again, you can &lt;a href="http://weblogs.asp.net/blogs/zowens/DataTables.zip" target="_blank"&gt;download my code from here with full comments&lt;/a&gt;. &lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7316292" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author></entry><entry><title>ClubStarterKit – Caching for performance</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2009/12/11/clubstarterkit-caching-for-performance.aspx" /><id>http://weblogs.asp.net/zowens/archive/2009/12/11/clubstarterkit-caching-for-performance.aspx</id><published>2009-12-11T15:43:56Z</published><updated>2009-12-11T15:43:56Z</updated><content type="html">&lt;p&gt;First of all, if you haven’t heard, I recently released ClubStarterKit v3 Preview. If you haven’t had a chance to look at it, I highly encourage you to &lt;a href="http://clubstarterkit.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=36375#ReleaseFiles" target="_blank"&gt;take a look at the whole new codebase&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;My whole goal when building any application whether it’s an application for a client or the open source ClubStarterKit project is to make the app as fast as possible. There are quite a few layers to the caching mechanisms in CSK that I think could be applied to many other projects. In fact, some of the caching ideas came from an internal web framework we use at &lt;a href="http://www.eagleenvision.net" target="_blank"&gt;eagleenvision.net&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;There are two “caches” that CSK uses. One is the HTTP Cache that IIS and other web servers use in the background. The other is the client’s web cache. I will give a brief overview of each in this post.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Web Cache&lt;/h2&gt;  &lt;p&gt;The web cache is the simplest to understand of the two types of caches. When a request comes down from the web application, a response key is set on the server side that informs the browser to not look up the same file until a certain date. The trick we can do is to set the date as far as possible so the cache NEVER expires. (In CSK I think the cache is something like 5 years…). But what happens when you change your website? That’s where the application ID comes into play.&lt;/p&gt;  &lt;p&gt;At every application startup, an identifier is pushed in storage (we use HTTP Application) of a string-based token. In CSK the token is the DateTime of the insertion into the cache so that there are no other collisions. This token is appended onto every CSS file request, image request, and Javascript file request so that the client doesn’t have to wait every time a page is loaded for the same CSS, image and Javascript files to load into the browser when running a particular “application instance”. If, for some reason, the application ID is not passed to the request, then the response isn’t cached. &lt;/p&gt;  &lt;p&gt;When a part of your application changes, you have the ability to reset the application ID yourself. In CSK you just navigate to /sitecontent/reset and the application ID should be reset. &lt;/p&gt;  &lt;p&gt;The obvious advantage to this strategy is the reduction in unnecessary bandwidth. And users don’t have to wait for something to download that they already have on their computer. So there are some real benefits to using client-side caching of static files.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;HTTP Cache&lt;/h2&gt;  &lt;p&gt;Just like the web cache, the HTTP cache reduces unnecessary bandwidth. The center of the HTTP cache, however, is around the database. It can sometimes be costly to hit a database for the same query. To counteract this we use HTTP caches. These things store data onto the application server and store them for a certain amount of time until it has expired or is expired. A value can be expired by the application server, when the specified TimeSpan is reached or when the item is removed from the cache by the web application. In the CSK, an item is expired from the cache when something is added, such as a new article or a forum post. Once the item is pulled from the cache, the next request forces the cache to go to the database for the query result and store it in the cache. &lt;/p&gt;  &lt;p&gt;In the CSK we are also refreshing caches for every application id. This just ensures that there isn’t a leak in the caching mechanism and the data can be easily refreshed by a website owner. &lt;/p&gt;  &lt;p&gt;The rationale for this feature is that hitting the database is a lot more costly when you’re dealing with load. Memory cache is really cheap comparatively. So it just makes sense to “hold” the query results until they are expired by either the application’s usage or the refresh of the application ID. In the worst case, ASP.NET removes the item from the cache because of lack of storage. In that case the query is regenerated anyways. &lt;/p&gt;  &lt;p&gt;In the CSK there are a few abstractions that I will detail in later posts that are particularly useful when dealing with data. These are the &lt;em&gt;CollectionDataCache&lt;/em&gt;, used for storing a collection from the DB, &lt;em&gt;PagedDataCache&lt;/em&gt;, used for storing a paged list from the DB, and the &lt;em&gt;SingleItemDataCache&lt;/em&gt;, used for storing single items from the DB. All these abstractions are sortable, constrainable, and easy to use. They all use the HTTP cache as the backing store. The abstractions also take care of the data access using the UnitOfWork and Repository patterns we employ in CSK. &lt;/p&gt;  &lt;p&gt;There is also an HttpSession cache, which is particularly useful when storing user data. It operates off the same cache interface as the HttpCacheBase.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;The Changes Ahead&lt;/h2&gt;  &lt;p&gt;Like I said, I took a lot of code from the internal framework I built a few years ago. The code I put into the CSK was really useful in that framework. But in the application of CSK, there is a sense of “code smell”. I would really like to do a few things differently, namely abstracting caches even further for CollectionDataCache, PagedDataCache and SingleItemDataCache. So maybe you might want to store a paged list into the session state. Currently you can’t do that without writing your own cache, which isn’t bad… it’s just not particularly fun to do. I would like to add, what I am calling, “cache strategies” to the infrastructure. So expect changes down the line for further abstraction.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;So you’ve seen that caches are particularly useful when dealing with data, whether it’s file data or database data. As always, questions, comments, and other feedback are GREATLY appreciated. Just send me an email, comment on this blog, or post on the &lt;a href="http://clubstarterkit.codeplex.com/Thread/List.aspx" target="_blank"&gt;ClubStarterKit forums&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7276613" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/zowens/archive/tags/.NET/default.aspx" /><category term="ASP.NET" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET/default.aspx" /><category term="ASP.NET MVC" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET+MVC/default.aspx" /><category term="ASP.NET Performance" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET+Performance/default.aspx" /><category term="ClubStarterKit" scheme="http://weblogs.asp.net/zowens/archive/tags/ClubStarterKit/default.aspx" /><category term="CSS" scheme="http://weblogs.asp.net/zowens/archive/tags/CSS/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/zowens/archive/tags/C_2300_/default.aspx" /></entry><entry><title>ClubStartKit is Reborn… With a new release</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2009/12/09/clubstartkit-is-reborn-with-a-new-release.aspx" /><id>http://weblogs.asp.net/zowens/archive/2009/12/09/clubstartkit-is-reborn-with-a-new-release.aspx</id><published>2009-12-09T06:07:00Z</published><updated>2009-12-09T06:07:00Z</updated><content type="html">
&lt;p&gt;The title says it all. That’s right, I’m back on ClubStarterKit. I’ve tried to assure the CSK community in past blog posts that it isn’t dead. In the last year, I’ve done a lot of thinking and outside programming. I’m FINALLY in a position where I have really progressed in terms of project management skill and web design. Many of the opinions I held when I started the project have simply changed. I’ll detail some of those in a minute. &lt;/p&gt;
  
&lt;p&gt;&lt;a href="http://clubstarterkit.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=36375" mce_href="http://clubstarterkit.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=36375" target="_blank"&gt;Here’s a link to the new release.&lt;/a&gt;&lt;/p&gt;
  
&lt;p&gt;Open source software is really tricky, especially for someone who has to go to school and keep up with the day job. It’s simply TOO MUCH for someone else to demand so much on a person. However, demanding open source work onto yourself is highly rewarding. That’s why I’m back. &lt;/p&gt;
  &lt;h2&gt;Why the time off?&lt;/h2&gt;  
&lt;p&gt;Well, I simply had to build my &lt;a href="http://www.eagleenvision.net" mce_href="http://www.eagleenvision.net" target="_blank"&gt;business&lt;/a&gt;. Ultimately, that takes a lot more priority over any other open source work. As harsh as that is, I simply had too much going on. Also, I was in a bit of a rut with CSK. &lt;/p&gt;
  
&lt;p&gt;The project started from a need by the community to extend the club starter kit originally started by Microsoft that shipped in the box as a starter kit with Visual Studio 2005. I found plenty of ways to extend the kit for myself and decided to share my extended version. It was a tool for beginners. My role was to share my knowledge of ASP.NET with everyone else.&lt;/p&gt;
  
&lt;p&gt;But there was a point where I was just copy and pasting and hacking the crap out of something that wasn’t mine and was written by a bunch of other people. I ripped a lot of things out, especially the data access. What I put in it’s place was a disaster as well, though. I simply didn’t have the forethought to imagine a site that was fully extensible. I simply put out something that was hacked and hacked and hacked. I didn’t put something out that EVERYONE could use, I put something out that EVERYONE had to figure out every little piece and extend. That’s simply irresponsible on my part. &lt;/p&gt;
  
&lt;p&gt;So I decided I needed to completely rewrite the thing. There was a point were I was sick and tired of writing VB. To me, it looks WAY too verbose. I couldn’t stand looking at it… and C# was my primary language at a point anyways, and still is.&lt;/p&gt;
  &lt;h2&gt;The big news&lt;/h2&gt;  
&lt;p&gt;Now I’m ready to come back. I finally have something that I put my stamp on. It’s MINE. I wrote it. There’s not a feeling in this world more satisfying for me than to say a piece of code is completely my creation. No hacks, no copy paste (ok, there’s a little… but at least I know what it does!) and certainly something I think everyone can use, whether it’s bits and pieces or the whole thing. &lt;/p&gt;
  &lt;h3&gt;What’s new!&lt;/h3&gt;  
&lt;p&gt;Well… for starters, it’s written entirely in C#! While I know some VB people are shivering in their boots, I plan on upgrading the web project to VB &lt;i&gt;if there is an apparent need from the community&lt;/i&gt;. I’m not here to waste my time converting something to VB if there’s not a need. C# is such an expressive language and it’s something every VB dev should at least TRY to look at. More on that down the line. &lt;/p&gt;
  
&lt;p&gt;Another big new thing is that it runs ASP.NET MVC, not classic web forms. I know that there is some serious turmoil out there over this subject, but it really is a much better way to create web applications in ASP.NET in my opinion. There’s not very much of a difference, as it turns out. It’s a very comfortable shift… more than I thought it would be. It makes applications much easier to understand, write, and test.&amp;nbsp; I can entertain comments, questions, and concerns by email over this. I’m willing to fight for this :) But really, MVC rocks. It’s simply amazing. &lt;/p&gt;
  
&lt;p&gt;I know it hasn’t been released yet, but this release will be targeting Visual Studio 2010 and the .NET Framework 4.0. There’s a lot of really cool new ASP.NET features that I think CSK would really benefit from. &lt;/p&gt;
  
&lt;p&gt;Now to the big thing that might just turn some people off… we’re primarily going to use NHibernate for data access. I plan on adding a few more providers (Subsonic would be the first to the list). I really started off with NHibernate as a learning experience. It’s a very complex, but WELL written data access solution. I’ve VERY pleased with the results. There’s a learning curve with NHibernate, to an extent. But NHibernate isn’t as hard for simple operations, like what CSK provides. I think I can go back to the fundamental part of CSK and provide some really good samples for people to learn from. NHibernate isn’t really all that hard as long as you have something to look at. Trust me, reading the documentation isn’t as glamorous as it sounds :). Hopefully I can abstract that away from the average CSK user. &lt;/p&gt;
  
&lt;p&gt;A huge reason for adding NHibernate as the primary data access point is because we can use it to generate our DB for us, often called “Domain Driven Design” (although we aren’t completely “DDD”). I can’t tell you how much trouble I’ve had with the SQL stuff in the past. If you start with your data model first, a tool like NHibernate or Subsonic will just generate all the DB code for you! For me, that’s HUGE! I hate having people say the new version broke their DB. That' hurts. Now we can just have the damn thing upgraded!&lt;/p&gt;
  
&lt;p&gt;Speaking of the DB… we will be starting from scratch on that too… sorry to say. I know plenty of people will be really disappointed by this. Just how it is. Hopefully from now on, we will have a better upgrade path. I hate breaking people’s compatibility simply because we release a new version. I’ll be assessing a possible upgrade path for those running v3 beta 1 and v2. But we shall see. This would be a GREAT contribution if someone in the community could code this out. &lt;/p&gt;
  
&lt;p&gt;The fact that we didn’t have a lot of tests in the last few versions proved we really didn’t have a great product. We just didn’t. That simple. I knew that this time, I needed to test EVERYTHING. While I don’t claim to be a TDD expert, I really tried to test first. I’ll detail contributions in a bit, but I can tell you, everything needs to have tests. While we’re a little light on tests right now, hopefully that will change as we get closer to v3. &lt;/p&gt;
  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;What’s taken out&lt;/h2&gt;  
&lt;p&gt;There was a serious outcry after v2 for a league management component. What happened in v3 Beta 1 was… interesting. I haven’t really seen anyone use it, and the feedback was mixed. So for this iteration, it’s not going to be a core part of the product. If there is a serious need, I think we (as in the community) should plan and implement an extension to CSK for league management stuff. &lt;/p&gt;
  
&lt;p&gt;League management was a really good idea, but I think the ideas some people had were just out of my scope. It’s something someone needs to write a spec for. I can’t just create what I think will fly. Just not something I’m willing to waste more of my time on. &lt;/p&gt;
  
&lt;p&gt;Also on my list of things taken out, I’ve finally decided to separate the logic of the application into separate projects. While the Visual Studio Express people might be upset, it really comes down to manageability of the project. If you create a large web application, it really defeats the purpose of expansibility. There are 6 main projects: Core, Infrastructure, Web, Data.NHibernate, Domain, and Tests. The core and infrastructure projects are meant to be distributed with ANY web project. It’s not CSK specific. So you can really use those as toolkits. It has some really good logic in it. I’d love to provide something that isn’t just for our little open source project. I will, however, be shipping a template with compiled versions of Domain, infrastructure, core, and Data.NHibernate. Hopefully that will help those who use express. We’ll see. I’d love to hear your feedback on this. &lt;/p&gt;
  
&lt;p&gt;   &lt;br&gt;&lt;/p&gt;
  &lt;h2&gt;Contributions&lt;/h2&gt;  
&lt;p&gt;In the past, I’ve said everyone can just contribute. That’s going to change. We’re starting with a whole new codebase that I wrote. Because of this, I think it’s time we started accepting patches rather than add contributors. We’ve had only a tiny bit of contribution in the past anyways. So here’s my decision. &lt;/p&gt;
  
&lt;p&gt;I’m going to take every contributor off the list. It’s a tough choice, but it has to be done. I will start to accept patches. These patches HAVE to contain tests. Once you’ve contributed in that way, I will then consider making you a contributor to the source repository. &lt;/p&gt;
  &lt;h2&gt;The release&lt;/h2&gt;  
&lt;p&gt;So I’ve told you wants new, and what not, but I didn’t say anything about a release. Today I am releasing the new codebase. I’m going to name this ClubStarterKit v3 preview. While I would love to call this v4, I think that not having a final v3 would be kind of strange. So this codebase will eventually become version 3. My plans from this point is to get feedback on what I have an release Version 3 &lt;b&gt;&lt;i&gt;&lt;u&gt;when it’s ready&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;. No promises, no false hopes. It’ll be done when I say it’s done. In the mean time, you can &lt;a href="http://clubstarterkit.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=36375" mce_href="http://clubstarterkit.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=36375" target="_blank"&gt;download the preview here.&lt;/a&gt;&lt;/p&gt;
  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;A call to action&lt;/h2&gt;  
&lt;p&gt;I’ve done my thing. I’ve built what I thought you’d want. Now it’s YOUR turn to help me out. Tell me what you like, tell me what you don’t like, tell me what should be in there, tell me what the future of CSK looks like. I need your feedback. It’s the essential ingredient in any open source project. We need to pick up anew and make this a sustainable and polished project that we can call a community-driven project! &lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  
&lt;p&gt;As always, thank you for your support and contribution. We all can give each other a helping hand in learning to develop software. &lt;/p&gt;

&lt;br&gt;&lt;br&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2009%2f12%2f09%2fclubstartkit-is-reborn-with-a-new-release.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2009%2f12%2f09%2fclubstartkit-is-reborn-with-a-new-release.aspx" alt="kick it on DotNetKicks.com" border="0"&gt;&lt;/a&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7274352" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/zowens/archive/tags/.NET/default.aspx" /><category term="ASP.NET" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET/default.aspx" /><category term="ASP.NET MVC" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET+MVC/default.aspx" /><category term="ClubStarterKit" scheme="http://weblogs.asp.net/zowens/archive/tags/ClubStarterKit/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/zowens/archive/tags/C_2300_/default.aspx" /><category term="Open Source" scheme="http://weblogs.asp.net/zowens/archive/tags/Open+Source/default.aspx" /><category term="SubSonic" scheme="http://weblogs.asp.net/zowens/archive/tags/SubSonic/default.aspx" /></entry><entry><title>Fluent NHibernate with System.ComponentModel.DataAnnotations</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2009/10/23/fluent-nhibernate-with-system-componentmodel-dataannotations.aspx" /><id>http://weblogs.asp.net/zowens/archive/2009/10/23/fluent-nhibernate-with-system-componentmodel-dataannotations.aspx</id><published>2009-10-23T20:34:00Z</published><updated>2009-10-23T20:34:00Z</updated><content type="html">
&lt;p&gt;So I’m building a product with &lt;a href="http://nhforge.org/" mce_href="http://nhforge.org/" target="_blank"&gt;NHibernate&lt;/a&gt; and possibly another ORM. The main focus of the app is a &lt;a href="http://www.asp.net/mvc/" mce_href="http://www.asp.net/mvc/" target="_blank"&gt;ASP.NET MVC 2.0 web application&lt;/a&gt;. So I, obviously, want the built in validation client-side in JavaScript &lt;b&gt;&lt;i&gt;and&lt;/i&gt;&lt;/b&gt; server side. By default, the MVC stuff uses the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx" target="_blank"&gt;System.ComponentModel.DataAnnotations&lt;/a&gt; attributes to validate properties on your domain. &lt;/p&gt;
  
&lt;p&gt;What I REALLY wanted was to use the Data Annotations with &lt;a href="http://fluentnhibernate.org/" mce_href="http://fluentnhibernate.org/" target="_blank"&gt;Fluent NHibernate&lt;/a&gt; for my DB mapping files. This presents a problem, right? WRONG! Because Fluent NHibernate is so extensible, I can easily create a convention to use the Attributes. Then all I have to do is add the convention to my Fluent NHibernate AutoMapper instance and the properties with the attributes are just taken care of. Isn’t that neat!! &lt;/p&gt;
  
&lt;p&gt;Required is a common notion with domains. Something HAS to be defined for an entity to be considered a reputable entry. Here’s the convention to use the Required attribute in Fluent NHibernate.&lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:00ea964d-6adf-4c63-8c26-118429c146e1" class="wlWriterEditableSmartContent"&gt; &lt;div class="le-pavsc-container"&gt; &lt;div class="le-pavsc-titleblock"&gt;Code Snippet&lt;/div&gt; &lt;div style="padding: 2px 5px; overflow: auto; background-color: rgb(0, 0, 0); max-height: 300px; white-space: nowrap;"&gt;&lt;span style="color: rgb(120, 175, 237);"&gt;using&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;System&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;ComponentModel&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;DataAnnotations&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;;&lt;/span&gt;&lt;br&gt; &lt;span style="color: rgb(120, 175, 237);"&gt;using&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;FluentNHibernate&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;Conventions&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;;&lt;/span&gt;&lt;br&gt; &lt;span style="color: rgb(120, 175, 237);"&gt;using&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;FluentNHibernate&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;Conventions&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;Instances&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;;&lt;/span&gt;&lt;br&gt; &lt;br&gt; &lt;span style="color: rgb(120, 175, 237);"&gt;namespace&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;Data&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;NHibernate&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;Conventions&lt;/span&gt;&lt;br&gt; &lt;span style="color: rgb(220, 220, 204);"&gt;{&lt;/span&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: rgb(220, 220, 204);"&gt;&lt;/span&gt;&lt;span style="color: rgb(120, 175, 237);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(120, 175, 237);"&gt;class&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(236, 216, 155);"&gt;RequiredConvention&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt; : &lt;/span&gt;&lt;span style="color: rgb(236, 216, 155);"&gt;AttributePropertyConvention&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(236, 216, 155);"&gt;RequiredAttribute&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: rgb(220, 220, 204);"&gt;{&lt;/span&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: rgb(220, 220, 204);"&gt;&lt;/span&gt;&lt;span style="color: rgb(120, 175, 237);"&gt;protected&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(120, 175, 237);"&gt;override&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(120, 175, 237);"&gt;void&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;Apply&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(236, 216, 155);"&gt;RequiredAttribute&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;attribute&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(12, 130, 186);"&gt;IPropertyInstance&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt; &lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;instance&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;)&lt;/span&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: rgb(220, 220, 204);"&gt;{&lt;/span&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: rgb(220, 220, 204);"&gt;&lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;instance&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;Not&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(223, 223, 191);"&gt;Nullable&lt;/span&gt;&lt;span style="color: rgb(220, 220, 204);"&gt;();&lt;/span&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: rgb(220, 220, 204);"&gt;}&lt;/span&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: rgb(220, 220, 204);"&gt;}&lt;/span&gt;&lt;br&gt; &lt;span style="color: rgb(220, 220, 204);"&gt;}&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  
&lt;p&gt;As you can see… there’s really only 1 line of code!&lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  
&lt;p&gt;I just showed you one out of the handful of attributes in the DataAnnotations library. To use the other attributes, you just basically follow the same basic outline of the example above. Not bad, eh :)&lt;/p&gt;

&lt;br&gt;
&lt;br&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2009%2f10%2f23%2ffluent-nhibernate-with-system-componentmodel-dataannotations.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2009%2f10%2f23%2ffluent-nhibernate-with-system-componentmodel-dataannotations.aspx" alt="kick it on DotNetKicks.com" border="0"&gt;&lt;/a&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7237394" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/zowens/archive/tags/.NET/default.aspx" /><category term="ASP.NET" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET/default.aspx" /><category term="ASP.NET MVC" scheme="http://weblogs.asp.net/zowens/archive/tags/ASP.NET+MVC/default.aspx" /><category term="Fluent NHibernate" scheme="http://weblogs.asp.net/zowens/archive/tags/Fluent+NHibernate/default.aspx" /><category term="NHibernate" scheme="http://weblogs.asp.net/zowens/archive/tags/NHibernate/default.aspx" /></entry><entry><title>Maybe Monad… my C# version</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2009/09/04/maybe-monad-my-c-version.aspx" /><id>http://weblogs.asp.net/zowens/archive/2009/09/04/maybe-monad-my-c-version.aspx</id><published>2009-09-04T05:09:00Z</published><updated>2009-09-04T05:09:00Z</updated><content type="html">
&lt;p&gt;Functional programming isn’t a new concept. There is Scheme, Haskell and a bunch of other really cool languages. But new on the block is F#. F# is Microsoft’s stab at creating a functional programming in the .NET world as a first-class language. &lt;/p&gt;
  
&lt;p&gt;Functional programming paradigms are increasingly important to &lt;b&gt;all&lt;/b&gt; .NET developers. This post will detail the functional elements (in my mind) of the Maybe Monad, something I’m sure &lt;b&gt;everyone&lt;/b&gt; has written in some way or another (ok maybe not &lt;b&gt;everyone, &lt;/b&gt;but there are certainly a lot of implementations out there in C#). But let’s discuss the application, functionally, of the maybe monad.&lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h4&gt;The Basics&lt;/h4&gt;  
&lt;p&gt;There are three areas of the maybe monad that are really important. The first is the concept of “Nothing” and “Just”. Nothing, in this context, would be either a failed operation (say division by 0, for example) or something that just returns null. The “Just” is the opposite of “Nothing”, it’s &lt;i&gt;something&lt;/i&gt;. It’s a successful operation that returns a value. Although this concept seems simple, it’s actually quite powerful. We’ll return to this in a bit.&lt;/p&gt;
  
&lt;p&gt;The second of the important concepts with the maybe monad is the “bind” and “return” verbs. “Bind” is the assigning of a value to a Maybe. “Return” the extraction of the value from the maybe. See the Maybe Monad is a container of a value (or lack thereof). The verbs attached to the container relay a façade of the actual value. While my implementation doesn’t deal with bind/return verbs directly, it is used indirectly with the composition and decomposition of the value container.&lt;/p&gt;
  
&lt;p&gt;The third is something we’re ALL familiar with, a type constraint. The formal declaration of the maybe monad declares that there must be a type parameter of type &lt;i&gt;M&lt;/i&gt;. This letter is arbitrary, of course, but the concept is important. Without the constraint, the possible values of the true value bound to the maybe container would be limitless. One more reason where generics in C# are invaluable!&lt;/p&gt;
  
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;h4&gt;&lt;/h4&gt;  &lt;h4&gt;Let’s get coding!&lt;/h4&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h5&gt;Start with Nothing&lt;/h5&gt;  
&lt;p&gt;Let’s start out with some initial xUnit.net tests. &lt;/p&gt;
  
&lt;pre class="csharpcode"&gt;[Fact]&lt;br&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Maybe_NothingContructor_SetsNothingFlag()&lt;br&gt;{&lt;br&gt;    var maybe = &lt;span class="kwrd"&gt;new&lt;/span&gt; Maybe&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt;();&lt;br&gt;    &lt;span class="kwrd"&gt;bool&lt;/span&gt; isNothing = maybe.Nothing;&lt;br&gt;    Assert.True(isNothing);&lt;br&gt;}&lt;br&gt;&lt;br&gt;[Fact]&lt;br&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; Maybe_JustContructor_DoesntSetNothingFlag()&lt;br&gt;{&lt;br&gt;    var maybe = &lt;span class="kwrd"&gt;new&lt;/span&gt; Maybe&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt;(5);&lt;br&gt;    &lt;span class="kwrd"&gt;bool&lt;/span&gt; isNothing = maybe.Nothing;&lt;br&gt;    Assert.False(isNothing);&lt;br&gt;}&lt;br&gt;&lt;br&gt;[Fact]&lt;br&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Maybe_JustContructor_SetsNothingFlag_WhenTheValuePassedIsNull()&lt;br&gt;{&lt;br&gt;    var maybe = &lt;span class="kwrd"&gt;new&lt;/span&gt; Maybe&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt;();&lt;br&gt;    &lt;span class="kwrd"&gt;bool&lt;/span&gt; isNothing = maybe.Nothing;&lt;br&gt;    Assert.True(isNothing);&lt;br&gt;}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;As you can see there are 2 constructors. The default is the “nothing” constructor. The constructor with a value is the “nothing” if the value is null and the “just” if there is an actual value. This is an immutable container, so I don’t feel so bad setting these values only in the constructor. Here’s what my “Maybe” looks like now.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class="rem"&gt;/// Value container for storing &lt;/span&gt;&lt;br&gt;&lt;span class="rem"&gt;/// a) a value ("Just")&lt;/span&gt;&lt;br&gt;&lt;span class="rem"&gt;/// b) lack of a value ("Nothing")&lt;/span&gt;&lt;br&gt;&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class="rem"&gt;/// &amp;lt;typeparam name="M"&amp;gt;Type M of the Maybe Monad&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;sealed&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Maybe&amp;lt;M&amp;gt;&lt;br&gt;{&lt;br&gt;&lt;br&gt;    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span class="rem"&gt;/// Non-value maybe ("Nothing")&lt;/span&gt;&lt;br&gt;    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Maybe()&lt;br&gt;    {&lt;br&gt;        &lt;span class="rem"&gt;// assign the nothing flag&lt;/span&gt;&lt;br&gt;        Nothing = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span class="rem"&gt;/// Maybe with a value ("Just")&lt;/span&gt;&lt;br&gt;    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span class="rem"&gt;/// &amp;lt;param name="value"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Maybe(M &lt;span class="kwrd"&gt;value&lt;/span&gt;)&lt;br&gt;    {&lt;br&gt;        &lt;span class="rem"&gt;// assign the nothing flag&lt;/span&gt;&lt;br&gt;        &lt;span class="rem"&gt;// when not null&lt;/span&gt;&lt;br&gt;        Nothing = &lt;span class="kwrd"&gt;value&lt;/span&gt; == &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span class="rem"&gt;/// Determines the state of the &lt;/span&gt;&lt;br&gt;    &lt;span class="rem"&gt;/// value in the container&lt;/span&gt;&lt;br&gt;    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Nothing { get; &lt;span class="kwrd"&gt;private&lt;/span&gt; set; }&lt;br&gt;}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;You might be wondering why I made this class sealed. My rationale for this is that, since &lt;i&gt;Maybe &lt;/i&gt;is immutable, we don’t want to get rid of some of the guarantees we have with the default implementation. Having a central “maybe” is a nice, simple way to define the maybe behavior. &lt;/p&gt;

&lt;h5&gt;Now for the return&lt;/h5&gt;

&lt;p&gt;The notion of a return for the maybe monad essentially means extracting the value from the container. I could define a “Return” function or even a “Value” property. But this is an unnecessary step. We don’t really need added complexity. My theory is that casting would be the best option. It is, after all, just a façade. Plus casting is a bit more expressive anyways. In your implementation, you can do this if you wish :)&lt;/p&gt;

&lt;pre class="csharpcode"&gt;[Fact]&lt;br&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Maybe_MCast_ReturnsAValue_WhenThereIsAValue()&lt;br&gt;{&lt;br&gt;    var maybe = &lt;span class="kwrd"&gt;new&lt;/span&gt; Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;""&lt;/span&gt;);&lt;br&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt; = maybe;&lt;br&gt;    Assert.NotNull(&lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;br&gt;}&lt;br&gt;&lt;br&gt;[Fact]&lt;br&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Maybe_MCast_ReturnsSameValue_WhenThereIsAValue()&lt;br&gt;{&lt;br&gt;    var initialValue = &lt;span class="str"&gt;""&lt;/span&gt;;&lt;br&gt;    var maybe = &lt;span class="kwrd"&gt;new&lt;/span&gt; Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(initialValue);&lt;br&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt; = maybe;&lt;br&gt;    Assert.Same(initialValue, &lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;br&gt;}&lt;br&gt;&lt;br&gt;[Fact]&lt;br&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Maybe_MCast_ReturnsNull_WhenThereIsNotAValue()&lt;br&gt;{&lt;br&gt;    var maybe = &lt;span class="kwrd"&gt;new&lt;/span&gt; Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();&lt;br&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt; = maybe;&lt;br&gt;    Assert.Null(&lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;br&gt;}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;And here is the code that makes the tests pass. &lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;sealed&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Maybe&amp;lt;M&amp;gt;&lt;br&gt;{&lt;br&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; M _value;&lt;br&gt;    &lt;br&gt;    ...&lt;br&gt;    &lt;span class="rem"&gt;// previous code hidden for brevity&lt;/span&gt;&lt;br&gt;    &lt;br&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;implicit&lt;/span&gt; &lt;span class="kwrd"&gt;operator&lt;/span&gt; M(Maybe&amp;lt;M&amp;gt; maybe)&lt;br&gt;    {&lt;br&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (maybe == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br&gt;            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="str"&gt;"maybe"&lt;/span&gt;);&lt;br&gt;&lt;br&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; maybe._value;&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;I added the value field and the implicit cast operator. &lt;/p&gt;

&lt;h5&gt;Another way to bind&lt;/h5&gt;

&lt;p&gt;The constructor to define the “Just” and “Nothing” is useful, but what if we wanted save a little code when we are &lt;i&gt;returning a maybe from a method?&lt;/i&gt; To do that, we’ll define &lt;i&gt;another&lt;/i&gt; implicit operator. This time the operator will take an &lt;i&gt;M &lt;/i&gt;and return a &lt;i&gt;Maybe&amp;lt;M&amp;gt;&lt;/i&gt;. Here’s our test:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;[Fact]&lt;br&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Maybe_MaybeCast_ReturnsNothingMaybe_WhenTheValueIsNull()&lt;br&gt;{&lt;br&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; val = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br&gt;    Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; maybe = val;&lt;br&gt;    Assert.True(maybe.Nothing);&lt;br&gt;}&lt;br&gt;&lt;br&gt;[Fact]&lt;br&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Maybe_MaybeCast_ReturnsJustMaybe_WhenTheValueIsNotNull()&lt;br&gt;{&lt;br&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; val = &lt;span class="str"&gt;""&lt;/span&gt;;&lt;br&gt;    Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; maybe = val;&lt;br&gt;    Assert.False(maybe.Nothing);&lt;br&gt;}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;And here’s the code.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;sealed&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Maybe&amp;lt;M&amp;gt;&lt;br&gt;{    &lt;br&gt;    ...&lt;br&gt;    &lt;span class="rem"&gt;// previous code hidden for brevity&lt;/span&gt;&lt;br&gt;    &lt;br&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;implicit&lt;/span&gt; &lt;span class="kwrd"&gt;operator&lt;/span&gt; Maybe&amp;lt;M&amp;gt;(M &lt;span class="kwrd"&gt;value&lt;/span&gt;)&lt;br&gt;    {&lt;br&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Maybe&amp;lt;M&amp;gt;(&lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h4&gt;Apply for Chainability&lt;/h4&gt;

&lt;p&gt;Being able to chain different functions is really a key part of the maybe monad. The verb I will use is “Apply”. In functional languages, this action just happens due to function composition. We have two options here. We can return the Maybe monad as a &lt;i&gt;Func&amp;lt;Maybe&amp;lt;M&amp;gt;, Maybe&amp;lt;M&amp;gt;&amp;gt;&lt;/i&gt; or we can define an Apply method to take a &lt;i&gt;Func&amp;lt;Maybe&amp;lt;M&amp;gt;, Maybe&amp;lt;M2&amp;gt;&amp;gt;&lt;/i&gt; where M2 is essentially a new value. The Apply method &lt;i&gt;could &lt;/i&gt;serve as a converter. If the initial value of M is Nothing, then the converted value should return a Nothing maybe monad. The great thing about the maybe monad is that there is no need to throw exceptions.Although the throwing of exceptions can provide useful information, most simple operations don’t require such complexity. Just test for Nothing on the maybe. Now you don't have to add a try/catch throughout your code.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;I am going to  use the Apply method. Although returning a &lt;i&gt;Func&amp;lt;Maybe&amp;lt;M&amp;gt;, Maybe&amp;lt;M&amp;gt;&amp;gt; &lt;/i&gt;might add expressive syntax, the Apply method will be a little more flexible for most scenarios. Here’s some tests.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;[Fact]&lt;br&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Maybe_Apply_ReturnsNothingMonad_WhenTheInitialNothingMaybe()&lt;br&gt;{&lt;br&gt;    Func&amp;lt;Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;, Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;&amp;gt; fun= (m) =&amp;gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;""&lt;/span&gt;);&lt;br&gt;    Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; initialMaybe = &lt;span class="kwrd"&gt;new&lt;/span&gt; Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();&lt;br&gt;    Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; appliedMaybe = initialMaybe.Apply(fun);&lt;br&gt;    Assert.True(appliedMaybe.Nothing);&lt;br&gt;}&lt;br&gt;&lt;br&gt;[Fact]&lt;br&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Maybe_Apply_ReturnsNewMaybeWithNewValue()&lt;br&gt;{&lt;br&gt;    Func&amp;lt;Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;, Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;&amp;gt; addBchar = (maybe) =&amp;gt; &lt;br&gt;                        &lt;span class="kwrd"&gt;new&lt;/span&gt; Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(((&lt;span class="kwrd"&gt;string&lt;/span&gt;)maybe) + &lt;span class="str"&gt;"b"&lt;/span&gt;);&lt;br&gt;&lt;br&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; initial = &lt;span class="str"&gt;""&lt;/span&gt;, final = &lt;span class="str"&gt;"b"&lt;/span&gt;;&lt;br&gt;&lt;br&gt;    Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; initialMaybe = &lt;span class="kwrd"&gt;new&lt;/span&gt; Maybe&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(initial);&lt;br&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; afterApply = initialMaybe.Apply(addBchar);&lt;br&gt;    Assert.Equal(final, afterApply);&lt;br&gt;}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;As you can see, my implementation will automatically return a nothing maybe monad when a nothing maybe monad is the initial value. OK here’s the code.&lt;/p&gt;

&lt;pre class="csharpcode"&gt; &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class="rem"&gt;/// Applies the specified function to this object&lt;/span&gt;&lt;br&gt;&lt;span class="rem"&gt;/// if this maybe is not nothing&lt;/span&gt;&lt;br&gt;&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class="rem"&gt;/// &amp;lt;typeparam name="M2"&amp;gt;Return Type&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class="rem"&gt;/// &amp;lt;param name="applyFunction"&amp;gt;Conversion function&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;A Nothing maybe if the initial maybe is nothing&lt;/span&gt;&lt;br&gt;&lt;span class="rem"&gt;/// or the value returned by &amp;lt;see cref="applyFunction"/&amp;gt; if&lt;/span&gt;&lt;br&gt;&lt;span class="rem"&gt;/// this maybe has a value.&lt;/span&gt;&lt;br&gt;&lt;span class="rem"&gt;/// &amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; Maybe&amp;lt;M2&amp;gt; Apply&amp;lt;M2&amp;gt;(Func&amp;lt;Maybe&amp;lt;M&amp;gt;, Maybe&amp;lt;M2&amp;gt;&amp;gt; applyFunction)&lt;br&gt;{&lt;br&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (Nothing)&lt;br&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Maybe&amp;lt;M2&amp;gt;();&lt;br&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; applyFunction(&lt;span class="kwrd"&gt;this&lt;/span&gt;);&lt;br&gt;}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h4&gt;Conclusion &lt;/h4&gt;

&lt;p&gt;The maybe monad is pretty cool for writing structure C# code. Your methods can now return a &lt;i&gt;Maybe&amp;lt;M&amp;gt;&lt;/i&gt; to be perfectly clear if your methods returned actual values or null. This also gives you another definition of null. Perhaps your idea of “null” could be returning a 0. We have added flexibility with this new construct. &lt;/p&gt;

&lt;p&gt;I’ve just hit the high marks in this post of my implementation of the maybe monad. Here’s an extended version with tests. Enjoy :)&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h4&gt;&lt;a href="http://weblogs.asp.net/blogs/zowens/MaybeMonad.zip" mce_href="http://weblogs.asp.net/blogs/zowens/MaybeMonad.zip"&gt;DOWNLOAD&lt;/a&gt;&lt;/h4&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2009%2f09%2f04%2fmaybe-monad-my-c-version.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fweblogs.asp.net%2fzowens%2farchive%2f2009%2f09%2f04%2fmaybe-monad-my-c-version.aspx" alt="kick it on DotNetKicks.com" border="0"&gt;&lt;/a&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7191328" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author><category term=".NET" scheme="http://weblogs.asp.net/zowens/archive/tags/.NET/default.aspx" /><category term="C#" scheme="http://weblogs.asp.net/zowens/archive/tags/C_2300_/default.aspx" /><category term="Functional Programming" scheme="http://weblogs.asp.net/zowens/archive/tags/Functional+Programming/default.aspx" /><category term="Monads" scheme="http://weblogs.asp.net/zowens/archive/tags/Monads/default.aspx" /></entry><entry><title>Cache Abstraction</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/zowens/archive/2008/08/04/cache-abstraction.aspx" /><id>http://weblogs.asp.net/zowens/archive/2008/08/04/cache-abstraction.aspx</id><published>2008-08-04T21:08:04Z</published><updated>2008-08-04T21:08:04Z</updated><content type="html">&lt;p&gt;I'm in the middle of a project and I wrote my own Cache logic that melds nicely to my project's needs. But how do I test it? I can't mock the System.Web.Caching.Cache class. So I looked in the Abstractions that ship with ASP.NET MVC. What do you know, they're not there!&lt;/p&gt; &lt;p&gt;So I created my own base class and wrapper. Here's the code. Enjoy.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Caching;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; WebCommon.Abstractions
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CacheBase : IEnumerable
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Count { get; }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; EffectivePercentagePhysicalMemoryLimit { get; }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; EffectivePrivateBytesLimit { get; }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;[&lt;span class="kwrd"&gt;string&lt;/span&gt; key] { get; set; }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Add(&lt;span class="kwrd"&gt;string&lt;/span&gt; key, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback);
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Get(&lt;span class="kwrd"&gt;string&lt;/span&gt; key);
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; IDictionaryEnumerator GetEnumerator();
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Insert(&lt;span class="kwrd"&gt;string&lt;/span&gt; key, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;);
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Insert(&lt;span class="kwrd"&gt;string&lt;/span&gt; key, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;, CacheDependency dependencies);
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Insert(&lt;span class="kwrd"&gt;string&lt;/span&gt; key, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration);
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Insert(&lt;span class="kwrd"&gt;string&lt;/span&gt; key, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback);
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Remove(&lt;span class="kwrd"&gt;string&lt;/span&gt; key);

        IEnumerator IEnumerable.GetEnumerator()
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetEnumerator();
        }
    }
}&lt;/pre&gt;
&lt;p&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Caching;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; WebCommon.Abstractions
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CacheWrapper : CacheBase
    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; Cache _cache;

        &lt;span class="kwrd"&gt;public&lt;/span&gt; CacheWrapper(Cache cache)
        {
            _cache = cache;
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Count
        {
            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _cache.Count; }
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; EffectivePercentagePhysicalMemoryLimit
        {
            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _cache.EffectivePercentagePhysicalMemoryLimit; }
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; EffectivePrivateBytesLimit
        {
            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _cache.EffectivePrivateBytesLimit; }
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;[&lt;span class="kwrd"&gt;string&lt;/span&gt; key]
        {
            get
            {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; _cache[key];
            }
            set
            {
                _cache[key] = &lt;span class="kwrd"&gt;value&lt;/span&gt;;
            }
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Add(&lt;span class="kwrd"&gt;string&lt;/span&gt; key, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback)
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; _cache.Add(key, &lt;span class="kwrd"&gt;value&lt;/span&gt;, dependencies, absoluteExpiration, slidingExpiration, priority, onRemoveCallback);
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Get(&lt;span class="kwrd"&gt;string&lt;/span&gt; key)
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; _cache.Get(key);
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; IDictionaryEnumerator GetEnumerator()
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; _cache.GetEnumerator();
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Insert(&lt;span class="kwrd"&gt;string&lt;/span&gt; key, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;)
        {
            _cache.Insert(key, &lt;span class="kwrd"&gt;value&lt;/span&gt;);
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Insert(&lt;span class="kwrd"&gt;string&lt;/span&gt; key, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;, CacheDependency dependencies)
        {
            _cache.Insert(key, &lt;span class="kwrd"&gt;value&lt;/span&gt;, dependencies);
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Insert(&lt;span class="kwrd"&gt;string&lt;/span&gt; key, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration)
        {
            _cache.Insert(key, &lt;span class="kwrd"&gt;value&lt;/span&gt;, dependencies, absoluteExpiration, slidingExpiration);
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Insert(&lt;span class="kwrd"&gt;string&lt;/span&gt; key, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback)
        {
            _cache.Insert(key, &lt;span class="kwrd"&gt;value&lt;/span&gt;, dependencies, absoluteExpiration, slidingExpiration, priority, onRemoveCallback);
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; Remove(&lt;span class="kwrd"&gt;string&lt;/span&gt; key)
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; _cache.Remove(key);
        }
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6482605" width="1" height="1"&gt;</content><author><name>zowens</name><uri>http://weblogs.asp.net/members/zowens.aspx</uri></author></entry></feed>