<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Technical Jargon</title>
	<atom:link href="http://jeremyskinner.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://jeremyskinner.wordpress.com</link>
	<description>Thoughts on Windows, Mac and Software Development</description>
	<lastBuildDate>Sat, 21 Jun 2008 16:06:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='jeremyskinner.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Technical Jargon</title>
		<link>http://jeremyskinner.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://jeremyskinner.wordpress.com/osd.xml" title="Technical Jargon" />
	<atom:link rel='hub' href='http://jeremyskinner.wordpress.com/?pushpress=hub'/>
		<item>
		<title>ASP.NET Routing, DataBinding and WebForms</title>
		<link>http://jeremyskinner.wordpress.com/2008/06/21/aspnet-routing-databinding-and-webforms/</link>
		<comments>http://jeremyskinner.wordpress.com/2008/06/21/aspnet-routing-databinding-and-webforms/#comments</comments>
		<pubDate>Sat, 21 Jun 2008 16:06:28 +0000</pubDate>
		<dc:creator>Jeremy Skinner</dc:creator>
				<category><![CDATA[ASP.NET]]></category>

		<guid isPermaLink="false">http://jeremyskinner.wordpress.com/?p=37</guid>
		<description><![CDATA[One of the great things about ASP.NET MVC is the automatic databinding support for routing. For example, if you define a route like this: routes.Add(new Route("{controller}/{action}/{id}", new MvcRouteHandler()) { Defaults = new RouteValueDictionary(new { action = "Index", id = (string)null }) }); &#8230;and you have a controller like this: public class HomeController : Controller { [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=37&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>
One of the great things about ASP.NET MVC is the automatic databinding support for routing. For example, if you define a route like this:
</p>
<pre style="overflow:auto;background-color:#eaf3fa;">
routes.Add(new Route("{controller}/{action}/{id}", new MvcRouteHandler()) {
	Defaults = new RouteValueDictionary(new { action = "Index", id = (string)null })
});
</pre>
<p>&#8230;and you have a controller like this:</p>
<pre style="overflow:auto;background-color:#eaf3fa;">
public class HomeController : Controller {
	public ActionResult Show(int id) {
		// do stuff
		return View();
	}
}
</pre>
<p>
&#8230;then visiting a url like <strong>mysite.com/Home/Show/5</strong> will automatically popuate the id parameter of the Show action with the value 5.
</p>
<p>
I thought it would be fun to see if I could get something similar working using WebForms. It actually turned out to be quite straightforward.
</p>
<p>
First, you&#8217;ll need to set up ASP.NET Routing to work with WebForms. I&#8217;m using Phil Haack&#8217;s WebFormRouting library which can be found <a href="http://haacked.com/archive/2008/05/19/updated-routing-with-webforms.aspx">here</a>.
</p>
<p>
I&#8217;ve added an extension method to RouteCollection that allows me to declare routes like this:
</p>
<pre style="overflow:auto;background-color:#eaf3fa;">
RouteTable.Routes.MapWithAutoBinding("Customer/{CustomerId}").To("~/Customer.aspx");
</pre>
<p>
In the code behind file for my customer.aspx page I can now declare a property like this:
</p>
<pre style="overflow:auto;background-color:#eaf3fa;">
public partial class Customer : Page {
	protected void Page_Load(object sender, EventArgs e) {
		customerNameLabel.Text = CustomerId;
	}

	[DataBind]
	public string CustomerId { get; set; }
}
</pre>
<p>
So when I visit MySite.com/Customer/Jeremy the &#8220;CustomerId&#8221; property on the Customer.aspx page will automatically be set to &#8220;Jeremy&#8221;.
</p>
<h2>How does it work?</h2>
<p>
Calling RouteTable.MapWithAutoBinding will create a route using the <strong>AutoBoundWebFormRouteHandler</strong> which inherits from Phil Haack&#8217;s WebFormRouteHandler. After GetHttpHandler is called, reflection is used to find any properties on the page that have a DataBindAttribute.
</p>
<p>
The RequestContext is then passed to the <strong>PerformBinding</strong> method on the DataBindAttribute, which will find the appropriate value from the RouteData and invoke the property&#8217;s setter.
</p>
<h2>Taking it a stage further: using Linq to Sql</h2>
<p>
Just for fun, I thought I&#8217;d see if it was possible to automatically fetch an entity from the database based on the value in the RouteData in a similar way to <a href="http://www.castleproject.org/monorail/documentation/trunk/integration/ar.html">Monorail&#8217;s ARDataBind attribute</a>. I thought I&#8217;d try and use Linq to SQL as I haven&#8217;t used this in a project before.
</p>
<p>
The first stage was to inherit from the DataBindAttribute class and override the PerformBinding method. Now, instead of just passing the value from the RouteData to the property, we have to run a linq query using the value from the route data as the primary key. This is very easy to do thanks to the Dynamic Linq provider that Microsoft ship in the Visual Studio 2008 samples folder.</p>
<p>
So, now the property on the Customer.aspx page can look like this:
</p>
<pre style="overflow:auto;background-color:#eaf3fa;">
[LinqBind("CustomerId")]
public Customer Cust { get; set; }
</pre>
<p>
The &#8220;CustomerId&#8221; being passed into the LinqBind attribute tells the binder the name of the RouteData value it should use as the primary key for the Customer entity. Currently, this only works with single primary keys, although it should be possible to get it work with composite keys too.</p>
<p>Visiting <strong>mysite.com/customer/ALFKI</strong> will now run a linq query to load a customer from the Customers table using the customer id of &#8220;ALFKI&#8221; and then set the &#8220;Cust&#8221; property to be a reference to this entity.
</p>
<p>
It is also necessary to tell the LinqBindAttribute which DataContext should be used to do the fetching. This can be set in the Global.asax&#8217;s Application_Start method using a delegate:
</p>
<pre style="overflow:auto;background-color:#eaf3fa;">
LinqBindAttribute.DataContextFactory = () =&gt; new MyDataContext();
</pre>
<p>
I&#8217;ve uploaded the code <a href="http://www.jeremyskinner.me.uk/files/RoutingWithAutoBinding.zip">here</a> if anyone wants to play with it. </p>
<p>Disclaimer: The zip file contains Phil Haack&#8217;s WebFormRouting.dll and Microsoft&#8217;s Dynamic Linq provider from the Visual Studio 2008 samples.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/jeremyskinner.wordpress.com/37/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/jeremyskinner.wordpress.com/37/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremyskinner.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremyskinner.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremyskinner.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremyskinner.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremyskinner.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremyskinner.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremyskinner.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremyskinner.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremyskinner.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremyskinner.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremyskinner.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremyskinner.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremyskinner.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremyskinner.wordpress.com/37/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=37&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremyskinner.wordpress.com/2008/06/21/aspnet-routing-databinding-and-webforms/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a1c7fe5c1af943c56be58b1dd817b97c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Jez</media:title>
		</media:content>
	</item>
		<item>
		<title>Twitter</title>
		<link>http://jeremyskinner.wordpress.com/2008/06/16/twitter/</link>
		<comments>http://jeremyskinner.wordpress.com/2008/06/16/twitter/#comments</comments>
		<pubDate>Mon, 16 Jun 2008 10:52:34 +0000</pubDate>
		<dc:creator>Jeremy Skinner</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jeremyskinner.wordpress.com/?p=36</guid>
		<description><![CDATA[The end is nigh! I have joined twitter!<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=36&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The end is nigh! I have <a href="http://twitter.com/JeremySkinner">joined twitter</a>!</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/jeremyskinner.wordpress.com/36/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/jeremyskinner.wordpress.com/36/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremyskinner.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremyskinner.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremyskinner.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremyskinner.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremyskinner.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremyskinner.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremyskinner.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremyskinner.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremyskinner.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremyskinner.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremyskinner.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremyskinner.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremyskinner.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremyskinner.wordpress.com/36/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=36&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremyskinner.wordpress.com/2008/06/16/twitter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a1c7fe5c1af943c56be58b1dd817b97c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Jez</media:title>
		</media:content>
	</item>
		<item>
		<title>LLBLGen Pro 2.6 Available</title>
		<link>http://jeremyskinner.wordpress.com/2008/06/08/llblgen-pro-26-available/</link>
		<comments>http://jeremyskinner.wordpress.com/2008/06/08/llblgen-pro-26-available/#comments</comments>
		<pubDate>Sun, 08 Jun 2008 12:05:53 +0000</pubDate>
		<dc:creator>Jeremy Skinner</dc:creator>
				<category><![CDATA[LLBLGen Pro]]></category>

		<guid isPermaLink="false">http://jeremyskinner.wordpress.com/?p=34</guid>
		<description><![CDATA[Version 2.6 of my favourite Object Relational Mapper, LLBLGen Pro, is now available. The main addition to V2.6 is support for a full Linq provider, so writing queries in LLBLGen just became a lot easier. V2.6 also includes a new Prefetching API which I wrote during the 2.6 beta period, which Frans then included in [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=34&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Version 2.6 of my favourite Object Relational Mapper, <a href="http://llblgen.com">LLBLGen Pro</a>, is now available.</p>
<p>
The main addition to V2.6 is support for a full Linq provider, so writing queries in LLBLGen just became a lot easier. V2.6 also includes a new Prefetching API which I wrote during the 2.6 beta period, which <a href="http://weblogs.asp.net/fbouma">Frans</a> then included in the product.</p>
<p>
For example, to eagerly load a Customer -&gt; Orders relationship prior to v2.6, you&#8217;d have to do something like this:
</p>
<pre style="overflow:auto;background-color:#eaf3fa;">
EntityCollection&lt;CustomerEntity&gt; customers = new EntityCollection&lt;CustomerEntity&gt;(new CustomerEntityFactory());

PrefetchPath2 prefetcher = new PrefetchPath2(EntityType.Customer);
prefetcher.Add(CustomerEntity.PrefetchPathOrders);

using(DataAccessAdapter adapter = new DataAccessAdapter()) {
	adapter.FetchEntityCollection(customers, null, prefetcher);
}
</pre>
<p>Now, with the lambda prefetching API you can do this:</p>
<pre style="overflow:auto;background-color:#eaf3fa;">
using(var adapter = new DataAccessAdapter()) {
	var linq = new LinqMetaData(adapter);

	var customers = (from c in linq.Customers select c)
				.WithPath(path =&gt; path.Prefetch(c =&gt; c.Orders));

}
</pre>
<p>
Likewise, if you wanted to filter the prefetched orders (eg, only return orders costing more than £10) and prefetch each order&#8217;s OrderDetail, you&#8217;d need to do something like this:
</p>
<pre style="overflow:auto;background-color:#eaf3fa;">
EntityCollection&lt;CustomerEntity&gt; customers = new EntityCollection&lt;CustomerEntity&gt;(new CustomerEntityFactory());

PrefetchPath2 prefetcher = new PrefetchPath2(EntityType.Customer);
prefetcher.Add(CustomerEntity.PrefetchPathOrders, 0, new PredicateExpression(OrderFields.TotalCost &gt; 10))
	.SubPath.Add(OrderEntity.PrefetchPathOrderDetail);

using(DataAccessAdapter adapter = new DataAccessAdapter()) {
	adapter.FetchEntityCollection(customers, null, prefetcher);
}
</pre>
<p>&#8230;while now you can do this:</p>
<pre style="overflow:auto;background-color:#eaf3fa;">
using(var adapter = new DataAccessAdapter()) {
	var linq = new LinqMetaData(adapter);

	var customers = (from c in linq.Customers select c)
				.WithPath(path =&gt;
					path.Prefetch&lt;OrderEntity&gt;(c =&gt; c.Orders)
						.FilterOn(o =&gt; o.TotalCost &gt; 10)
						.SubPath(orderPath =&gt; orderPath.Prefetch(o =&gt; o.OrderDetail))
				);

}
</pre>
<p>Lambdas rock :)</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/jeremyskinner.wordpress.com/34/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/jeremyskinner.wordpress.com/34/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremyskinner.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremyskinner.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremyskinner.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremyskinner.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremyskinner.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremyskinner.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremyskinner.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremyskinner.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremyskinner.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremyskinner.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremyskinner.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremyskinner.wordpress.com/34/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremyskinner.wordpress.com/34/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremyskinner.wordpress.com/34/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=34&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremyskinner.wordpress.com/2008/06/08/llblgen-pro-26-available/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a1c7fe5c1af943c56be58b1dd817b97c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Jez</media:title>
		</media:content>
	</item>
		<item>
		<title>ASP.NET MVC &#8211; Intercepting the RouteValueDictionary</title>
		<link>http://jeremyskinner.wordpress.com/2008/06/03/aspnet-mvc-intercepting-the-routevaluedictionary/</link>
		<comments>http://jeremyskinner.wordpress.com/2008/06/03/aspnet-mvc-intercepting-the-routevaluedictionary/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 08:02:52 +0000</pubDate>
		<dc:creator>Jeremy Skinner</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[aspnetmvc]]></category>

		<guid isPermaLink="false">http://jeremyskinner.wordpress.com/?p=33</guid>
		<description><![CDATA[ASP.NET MVC Preview 3 suffers from a bug where the controller name is omitted from the RouteValueDictionary when you call Html.ActionLink or Url.Action unless you explicitly specify it. Imagine you have the following routes defined: routes.Add(new Route("Other/List", new RouteValueDictionary(new { controller = "Other", action = "List" }), new MvcRouteHandler()) ); routes.Add(new Route("{controller}/{action}/{id}", new RouteValueDictionary(new { [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=33&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>ASP.NET MVC Preview 3 suffers from a bug where the controller name is omitted from the RouteValueDictionary when you call Html.ActionLink or Url.Action unless you explicitly specify it. </p>
<p>Imagine you have the following routes defined:</p>
<pre style="background-color:#eaf3fa;">
routes.Add(new Route("Other/List",
	new RouteValueDictionary(new {
		controller = "Other",
		action = "List"
	}),
	new MvcRouteHandler())
);

routes.Add(new Route("{controller}/{action}/{id}",
	new RouteValueDictionary(new {
		action = "Index",
		id = (string)null
	}),
	new MvcRouteHandler())
);
</pre>
<p>..and you have a HomeController with two actions: Index and List</p>
<pre style="background-color:#eaf3fa;">
public class HomeController : Controller {
	public ActionResult Index() {
		return View();
	}

	public ActionResult List() {
		return View();
	}
}
</pre>
<p>
And imagine the following code in the Index view:
</p>
<pre style="background-color:#eaf3fa;">
&lt;%= Url.Action("List") %&gt;
</pre>
<p>This should generate <b>MyApp/Home/List</b> but instead it generates <b>MyApp/Other/List</b>. </p>
<p>To work around this, you can intercept the RouteValueDictionary before it is passed to your routes by adding a route &#8216;pre-parser&#8217;. In here, you can copy the controller name from the routedata into the RouteValuesDictionary.</p>
<pre style="overflow:auto;background-color:#eaf3fa;">
public class RouteValuePreParser : RouteBase {
	public override RouteData GetRouteData(HttpContextBase httpContext) {
		return null;
	}

	public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) {
		if(!values.ContainsKey("controller") &amp;&amp; requestContext.RouteData.Values.ContainsKey("controller")) {
			values.Add("controller", requestContext.RouteData.Values["controller"]);
		}
		return null;
	}
}
</pre>
<p>You can then add this &#8216;fake&#8217; route to your RouteTable, but it must be the <b>first</b> route:</p>
<pre style="background-color:#eaf3fa;">
RouteTable.Routes.Add(new RouteValuePreParser());
</pre>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/jeremyskinner.wordpress.com/33/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/jeremyskinner.wordpress.com/33/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremyskinner.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremyskinner.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremyskinner.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremyskinner.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremyskinner.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremyskinner.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremyskinner.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremyskinner.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremyskinner.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremyskinner.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremyskinner.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremyskinner.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremyskinner.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremyskinner.wordpress.com/33/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=33&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremyskinner.wordpress.com/2008/06/03/aspnet-mvc-intercepting-the-routevaluedictionary/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a1c7fe5c1af943c56be58b1dd817b97c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Jez</media:title>
		</media:content>
	</item>
		<item>
		<title>MvcContrib upgraded to ASP.NET MVC Preview 3</title>
		<link>http://jeremyskinner.wordpress.com/2008/05/30/mvccontrib-upgraded-to-aspnet-mvc-preview-3/</link>
		<comments>http://jeremyskinner.wordpress.com/2008/05/30/mvccontrib-upgraded-to-aspnet-mvc-preview-3/#comments</comments>
		<pubDate>Fri, 30 May 2008 16:31:00 +0000</pubDate>
		<dc:creator>Jeremy Skinner</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[mvccontrib]]></category>
		<category><![CDATA[aspnetmvc]]></category>

		<guid isPermaLink="false">http://jeremyskinner.wordpress.com/?p=32</guid>
		<description><![CDATA[I&#8217;ve just finished upgrading MvcContrib to work with ASP.NET MVC Preview 3. The source can be downloaded from http://mvccontrib.googlecode.com/svn/trunk/ using your favourite Subversion client.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=32&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just finished upgrading <a href="http://mvccontrib.org">MvcContrib</a> to work with <a href="http://weblogs.asp.net/scottgu/archive/2008/05/27/asp-net-mvc-preview-3-release.aspx">ASP.NET MVC Preview 3.</a></p>
<p>The source can be downloaded from <strong>http://mvccontrib.googlecode.com/svn/trunk/</strong> using your favourite Subversion client.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/jeremyskinner.wordpress.com/32/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/jeremyskinner.wordpress.com/32/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremyskinner.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremyskinner.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremyskinner.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremyskinner.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremyskinner.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremyskinner.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremyskinner.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremyskinner.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremyskinner.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremyskinner.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremyskinner.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremyskinner.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremyskinner.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremyskinner.wordpress.com/32/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=32&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremyskinner.wordpress.com/2008/05/30/mvccontrib-upgraded-to-aspnet-mvc-preview-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a1c7fe5c1af943c56be58b1dd817b97c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Jez</media:title>
		</media:content>
	</item>
		<item>
		<title>Introducing the Smart Grid for ASP.NET MVC</title>
		<link>http://jeremyskinner.wordpress.com/2008/05/21/introducing-the-smart-grid-for-aspnet-mvc/</link>
		<comments>http://jeremyskinner.wordpress.com/2008/05/21/introducing-the-smart-grid-for-aspnet-mvc/#comments</comments>
		<pubDate>Wed, 21 May 2008 11:45:38 +0000</pubDate>
		<dc:creator>Jeremy Skinner</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[mvccontrib]]></category>
		<category><![CDATA[aspnetmvc]]></category>

		<guid isPermaLink="false">http://jeremyskinner.wordpress.com/?p=29</guid>
		<description><![CDATA[Edit: Some documentation for the Grid is now available at the MvcContrib Wiki. I&#8217;ve recently been working on an equivalent of the ASP.NET GridView for use with ASP.NET MVC. This is partially inspired by the SmartGrid component which is part of the Castle Contrib project, but uses lambdas in order to build up a set [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=29&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>
<strong>Edit:</strong> Some documentation for the Grid is now available at the <a href="http://www.codeplex.com/MVCContrib/Wiki/View.aspx?title=Grid">MvcContrib Wiki</a>.
</p>
<p>I&#8217;ve recently been working on an equivalent of the ASP.NET GridView for use with ASP.NET MVC. </p>
<p>
This is partially inspired by the <a href="http://using.castleproject.org/display/Contrib/Smart+Grid+Component">SmartGrid component</a> which is part of the Castle Contrib project, but uses lambdas in order to build up a set of columns that can be automatically turned into an HTML table. For example, I might have this in an ASP.NET MVC Controller:
</p>
<pre>
public class HomeController {
	private UserRepository repository = new UserRepository();

	public ActionResult Index() {
		ViewData["users"] = repository.FindAll();
		return RenderView();
	}
}
</pre>
<p>
Then in my View I could have this:
</p>
<pre>
&lt;%
Html.Grid&lt;Person&gt;(
	"people",
	column =&gt; {
		column.For(p =&gt; p.Id);
		column.For(p =&gt; p.Name);
		column.For(p =&gt; p.Gender);
		column.For(p =&gt; p.RoleId);
	}
);
%&gt;
</pre>
<p>
Which would create something like this:
</p>
<p><img src="http://jeremyskinner.files.wordpress.com/2008/05/grid1.gif?w=780" alt="grid1" /></p>
<p>
Note how the column names are automatically generated from the lambda expressions. However, you can override a column heading:
</p>
<pre>
column.For(p =&gt; p.Id, "ID Number");
</pre>
<p>
You can also create custom columns using lambda statements&#8230;
</p>
<pre>
column.For("Custom Column").Do(p =&gt; { %&gt;
	&lt;td&gt;A custom column...&lt;/td&gt;
&lt;% });
</pre>
<p>&#8230;and columns can have formatting applied to them:</p>
<pre>
column.For(p =&gt; p.DateOfBirth).Formatted("{0:d}");
</pre>
<p>
Pagination is also fully supported by using the AsPagination extension method which works on any IEnumerable&lt;T&gt; or IQueryable&lt;T&gt;
</p>
<pre>
public ActionResult Index(int? page) {
	ViewData["users"] = repository.FindAll().AsPagination(page ?? 1);
	return RenderView();
}
</pre>
<p>
Which would produce something like this:
</p>
<p><img src="http://jeremyskinner.files.wordpress.com/2008/05/grid2.gif?w=780" alt="grid2" /></p>
<p>The source code is available in the <a href="http://mvccontrib.org">mvccontrib</a> trunk.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/jeremyskinner.wordpress.com/29/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/jeremyskinner.wordpress.com/29/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremyskinner.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremyskinner.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremyskinner.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremyskinner.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremyskinner.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremyskinner.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremyskinner.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremyskinner.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremyskinner.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremyskinner.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremyskinner.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremyskinner.wordpress.com/29/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremyskinner.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremyskinner.wordpress.com/29/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=29&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremyskinner.wordpress.com/2008/05/21/introducing-the-smart-grid-for-aspnet-mvc/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a1c7fe5c1af943c56be58b1dd817b97c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Jez</media:title>
		</media:content>

		<media:content url="http://jeremyskinner.files.wordpress.com/2008/05/grid1.gif" medium="image">
			<media:title type="html">grid1</media:title>
		</media:content>

		<media:content url="http://jeremyskinner.files.wordpress.com/2008/05/grid2.gif" medium="image">
			<media:title type="html">grid2</media:title>
		</media:content>
	</item>
		<item>
		<title>ASP.NET MVC Controllers, Windsor and IDisposable</title>
		<link>http://jeremyskinner.wordpress.com/2008/05/03/aspnet-mvc-controllers-windsor-and-idisposable/</link>
		<comments>http://jeremyskinner.wordpress.com/2008/05/03/aspnet-mvc-controllers-windsor-and-idisposable/#comments</comments>
		<pubDate>Sat, 03 May 2008 13:06:48 +0000</pubDate>
		<dc:creator>Jeremy Skinner</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[aspnetmvc]]></category>

		<guid isPermaLink="false">http://jeremyskinner.wordpress.com/?p=28</guid>
		<description><![CDATA[I recently upgraded one of my larger intranet applications to the latest ASP.NET MVC release and after doing so, I noticed that the memory usage on our webserver would gradually go up and up. After 4-5 hours all the memory on the server was in use (2gb) and the only solution was to restart the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=28&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I recently upgraded one of my larger intranet applications to the latest ASP.NET MVC release and after doing so, I noticed that the memory usage on our webserver would gradually go up and up. After 4-5 hours all the memory on the server was in use (2gb) and the only solution was to restart the application.
</p>
<p>
After doing some investigation I realised what the problem was: System.Web.Mvc.Controller implements IDisposable and the <a href="http://castleproject.org/container/index.html">Windsor IoC container</a> will <a href="http://www.nablasoft.com/Alkampfer/?p=105">keep a reference to all transient objects that it creates if they implement IDisposable</a>. So not only was every controller being kept alive, but also <b>everything stored in the ViewData dictionary</b>.
</p>
<p>
Explicitly calling container.Release() inside the controller factory&#8217;s DisposeController method fixed the problem.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/jeremyskinner.wordpress.com/28/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/jeremyskinner.wordpress.com/28/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremyskinner.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremyskinner.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremyskinner.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremyskinner.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremyskinner.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremyskinner.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremyskinner.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremyskinner.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremyskinner.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremyskinner.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremyskinner.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremyskinner.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremyskinner.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremyskinner.wordpress.com/28/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=28&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremyskinner.wordpress.com/2008/05/03/aspnet-mvc-controllers-windsor-and-idisposable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a1c7fe5c1af943c56be58b1dd817b97c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Jez</media:title>
		</media:content>
	</item>
		<item>
		<title>Testing Action Results with ASP.NET MVC</title>
		<link>http://jeremyskinner.wordpress.com/2008/04/19/testing-action-results-with-aspnet-mvc/</link>
		<comments>http://jeremyskinner.wordpress.com/2008/04/19/testing-action-results-with-aspnet-mvc/#comments</comments>
		<pubDate>Sat, 19 Apr 2008 18:50:51 +0000</pubDate>
		<dc:creator>Jeremy Skinner</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[mvccontrib]]></category>
		<category><![CDATA[aspnetmvc]]></category>

		<guid isPermaLink="false">http://jeremyskinner.wordpress.com/?p=27</guid>
		<description><![CDATA[The latest preview of ASP.NET MVC supports returning ActionResult objects from controller actions. This makes it very easy to test the results of an action (for example, redirecting to another controller) which was a much more involved process in previous releases. Imagine the following controller: public class HomeController : Controller { public ActionResult Index() { [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=27&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://weblogs.asp.net/scottgu/archive/2008/04/16/asp-net-mvc-source-refresh-preview.aspx">latest preview</a> of <a href="http://www.codeplex.com/aspnet">ASP.NET MVC</a> supports returning ActionResult objects from controller actions.</p>
<p>This makes it very easy to test the results of an action (for example, redirecting to another controller) which was a much more involved process in previous releases.</p>
<p>Imagine the following controller:</p>
<pre>
public class HomeController : Controller {
	public ActionResult Index() {
		return RedirectToAction(new { controller = "Home", action = "about" });
	}

	public ActionResult About() {
		return RenderView();
	}
}
</pre>
<p>While previously you&#8217;d have to mock the Response.Redirect method, now you can do this:</p>
<pre>
var controller = new HomeController();
ActionRedirectResult result = controller.Index() as ActionRedirectResult;

if(result == null) {
	Assert.Fail("Expected an ActionRedirectResult");
}
else {
	Assert.That(result.Values["controller"], Is.EqualTo("Home"));
	Assert.That(result.Values["action"], Is.EqualTo("about"));
}
</pre>
<p>While this is certainly easier, it is still a little cumbersome. To help with this, I&#8217;ve added some extension methods to MvcContrib&#8217;s &#8216;TestHelper&#8217; project. So now I can write:</p>
<pre>
var controller = new HomeController();
controller.Index().AssertIsActionRedirect().ToController("Home").ToAction("about");
</pre>
<p>
Much better!</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/jeremyskinner.wordpress.com/27/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/jeremyskinner.wordpress.com/27/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremyskinner.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremyskinner.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremyskinner.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremyskinner.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremyskinner.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremyskinner.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremyskinner.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremyskinner.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremyskinner.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremyskinner.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremyskinner.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremyskinner.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremyskinner.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremyskinner.wordpress.com/27/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=27&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremyskinner.wordpress.com/2008/04/19/testing-action-results-with-aspnet-mvc/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a1c7fe5c1af943c56be58b1dd817b97c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Jez</media:title>
		</media:content>
	</item>
		<item>
		<title>Linq Repositories</title>
		<link>http://jeremyskinner.wordpress.com/2008/03/24/linq-repositories/</link>
		<comments>http://jeremyskinner.wordpress.com/2008/03/24/linq-repositories/#comments</comments>
		<pubDate>Mon, 24 Mar 2008 19:49:22 +0000</pubDate>
		<dc:creator>Jeremy Skinner</dc:creator>
				<category><![CDATA[Linq]]></category>
		<category><![CDATA[LLBLGen Pro]]></category>

		<guid isPermaLink="false">http://blog.jeremyskinner.me.uk/?p=26</guid>
		<description><![CDATA[Recently, the beta of Linq to LLBLGen Pro was announced, which adds linq-querying capabilities to LLBLGen, the Object Relational Mapper that I use in most of my projects. LLBLGen&#8217;s querying API is very powerful, but also somewhat complex. For example, to retrieve a list of orders from all customers in the Northwind database for customers [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=26&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>
Recently, the beta of <a href="http://weblogs.asp.net/fbouma/archive/2008/03/12/beta-of-linq-to-llblgen-pro-released.aspx">Linq to LLBLGen Pro</a> was announced, which adds linq-querying capabilities to LLBLGen, the Object Relational Mapper that I use in most of my projects.
</p>
<p>
LLBLGen&#8217;s querying API is very powerful, but also somewhat complex. For example, to retrieve a list of orders from all customers in the Northwind database for customers in the UK, you would write something like this:
</p>
<pre>
EntityCollection&lt;OrderEntity&gt; orders = new EntityCollection&lt;OrderEntity&gt;(new OrderEntityFactory());
RelationPredicateBucket bucket = new RelationPredicateBucket(CustomerFields.Country == "UK")
bucket.Relations.Add(OrderEntity.Relations.CustomerEntityUsingCustomerId)
using(DataAccessAdapter adapter = new DataAccessAdapter())
{
	adapter.FetchEntityCollection(orders, bucket)
}
</pre>
<p>
Linq support maintains the type safety, whilst also allowing this query to be expressed in a more SQL-like fashion (which I personally find to be more intuitive):
</p>
<pre>
using(DataAccessAdapter adapter = new DataAccessAdapter())
{
	var meta = new LinqMetaData(adapter);
	var query = from o in meta.Order
			where o.Customer.Country == "UK"
			select o;

	var results = query.ToList();
}
</pre>
<p>This got me thinking&#8230;now that there are several ORMs that have linq support, wouldn&#8217;t it be nice if there was a consistent method for performing linq-based queries, independent of the underlying ORM implementation. And thus the linq-repository was born.</p>
<p>
The majority of the work is done by the BaseRepository class which acts as a wrapper around the underlying linq provider. There&#8217;s also an IRepository interface which the BaseRepository implements:
</p>
<pre>
public interface IRepository&lt;T&gt; : IQueryable&lt;T&gt; where T : class
{
	void Save(T toSave);
	void Save(T toSave, bool isNew);
	void Delete(T toDelete);
}

public abstract class BaseRepository&lt;T&gt; : IRepository&lt;T&gt; where T : class
{
	private IQueryable&lt;T&gt; source;

	protected IQueryable&lt;T&gt; Source
	{
		get { return source; }
		set { source = value; }
	}

	protected BaseRepository(IQueryable&lt;T&gt; source)
	{
		this.source = source;
	}

	IEnumerator&lt;T&gt; IEnumerable&lt;T&gt;.GetEnumerator()
	{
		return source.GetEnumerator();
	}

	public IEnumerator GetEnumerator()
	{
		return source.GetEnumerator();
	}

	public Expression Expression
	{
		get { return source.Expression; }
	}

	public Type ElementType
	{
		get { return source.ElementType; }
	}

	public IQueryProvider Provider
	{
		get { return source.Provider; }
	}

	public abstract void Save(T toSave);
	public abstract void Delete(T toDelete);
	public abstract void Save(T toSave, bool isNew);
</pre>
<p>
Note that the constructor for BaseRepository takes an IQueryable representing the underlying linq provider. Now, the LLBLGen-specific subclass:
</p>
<pre>
public class LLBLGenRepository&lt;T&gt; : BaseRepository&lt;T&gt; where T : EntityBase2, IEntity2, new()
{
	public IDataAccessAdapter Adapter { get; private set; }

	public LLBLGenRepository(IDataAccessAdapter adapter, IElementCreator2 elementCreator)
			: base(CreateQuery(adapter, elementCreator))
	{
		this.Adapter = adapter;
	}

	private static IQueryable CreateQuery(IDataAccessAdapter adapter, IElementCreator2 elementCreator)
	{
		return new DataSource2(adapter, elementCreator, functionMappings, null);
	}

	public override void Save(T toSave)
	{
		if (toSave == null)
			throw new ArgumentNullException("toSave");

		Adapter.SaveEntity(toSave);
	}

	public override void Save(T toSave, bool isNew)
	{
		if (toSave == null)
			throw new ArgumentNullException("toSave");

		if (isNew) toSave.IsNew = true;

		Adapter.SaveEntity(toSave);
	}

	public override void Delete(T toDelete)
	{
		Adapter.DeleteEntity(entity);
	}
</pre>
<p>
Note that the constructor for the LLBLGenRepository takes instances of an IDataAccessAdapter and an IElementCreator (the two objects necessary for running linq-queries against LLBLGen) and creates a DataSource2 object (the LLBLGen query provider) which is then passed to the BaseRepository&#8217;s constructor.
</p>
<p>So, I can now write code like this:</p>
<pre>
IRepository&lt;OrderEntity&gt; orders = new LLBLGenRepository&lt;OrderEntity&gt;(new DataAccessAdapter(), new ElementCreator());

var query = from o in orders
		where o.Customer.Country == "UK"
		select o;
</pre>
<p>
To remove the calls to <i>new DataAccessAdapter()</i> and <i>new ElementCreator()</i>, I moved the responsibility for instantiating the repository over to an IoC container:
</p>
<pre>
//in my application startup routine:
IoC.Initialise(new WindsorContainer());
IoC.Container.AddComponent&lt;IDataAccessAdapter, DataAccessAdapter&gt;();
IoC.Container.AddComponent&lt;IElementCreator2, ElementCreator&gt;();
IoC.Container.AddComponent("Repository", typeof(IRepository&lt;&gt;), typeof(LLBLGenRepository&lt;&gt;));
</pre>
<p>
The IoC static class is simply a wrapper for the <a href="http://www.castleproject.org/container/index.html">Windsor container</a>.
</p>
<p>Now I can instantiate repositories like this:</p>
<pre>
IRepository&lt;OrderEntity&gt; orders = IoC.Resolve&lt;IRepository&lt;OrderEntity&gt;&gt;();
</pre>
<p>
I don&#8217;t really like this, so I wrap it in a static gateway:
</p>
<pre>
public static class Repository
{
	public static IRepository&lt;T&#038;t; For&lt;T&gt;() where T : class, new()
	{
		return IoC.Resolve&lt;IRepository&lt;T&gt;&gt;();
	}
}
</pre>
<p>&#8230;and now I can write queries like this:</p>
<pre>
var query = from o in Repository.For&lt;OrderEntity&gt;
		where o.Customer.Country == "UK"
		select o;
</pre>
<p>
Alternatively, now that the repository is registered with Windsor, I can inject the repository directly into my ASPNET MVC Controllers:
</p>
<pre>
public class OrdersController : ConventionController
{
	private IRepository&lt;OrderEntity&gt; ordersRepository;

	public OrdersController(IRepository&lt;OrderEntity&gt; repository)
	{
		this.ordersRepository = repository;
	}

	public void OrdersFromCustomersInTheUk()
	{
		ViewData["orders"] = from o in ordersRepository
						where o.Customer.Country == "UK"
						select o;
	}
}
</pre>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/jeremyskinner.wordpress.com/26/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/jeremyskinner.wordpress.com/26/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremyskinner.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremyskinner.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremyskinner.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremyskinner.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremyskinner.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremyskinner.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremyskinner.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremyskinner.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremyskinner.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremyskinner.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremyskinner.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremyskinner.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremyskinner.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremyskinner.wordpress.com/26/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=26&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremyskinner.wordpress.com/2008/03/24/linq-repositories/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a1c7fe5c1af943c56be58b1dd817b97c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Jez</media:title>
		</media:content>
	</item>
		<item>
		<title>Helpers for the MS MVC Framework</title>
		<link>http://jeremyskinner.wordpress.com/2008/02/02/helpers-for-the-ms-mvc-framework/</link>
		<comments>http://jeremyskinner.wordpress.com/2008/02/02/helpers-for-the-ms-mvc-framework/#comments</comments>
		<pubDate>Sat, 02 Feb 2008 14:24:32 +0000</pubDate>
		<dc:creator>Jeremy Skinner</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[mvccontrib]]></category>
		<category><![CDATA[aspnetmvc]]></category>

		<guid isPermaLink="false">http://jeremyskinner.wordpress.com/?p=25</guid>
		<description><![CDATA[Go to the bottom of this post for the download. There&#8217;s a discussion going on at the MvcContrib site about including UI Helpers in the MvcContrib project. The discussion seems to be centralising around the issue of whether helpers should be implemented through extension methods (the approach the MVCToolkit takes), regular static methods or instance [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=25&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Go to the bottom of this post for the download.</p>
<p>There&#8217;s <a href="http://www.codeplex.com/MVCContrib/WorkItem/View.aspx?WorkItemId=972">a discussion</a> going on at the MvcContrib site about including UI Helpers in the MvcContrib project. The discussion seems to be centralising around the issue of whether helpers should be implemented through extension methods (the approach the MVCToolkit takes), regular static methods or instance methods.</p>
<p>
My preference is for instance methods on dedicated helper classes. This approach is the most flexible as it allows you to:</p>
<ul>
<li>Replace an entire helper with a custom implementation</li>
<li>Easily share services between all helpers</li>
</ul>
<p>
 I decided to put together a sample application that uses an IoC container (<a href="http://www.castleproject.org/container/index.html">Windsor</a>) for creating helpers. The sample project includes:</p>
<ul>
<li>FormHelper and UrlHelper implementations that are created using the MvcContrib DependencyResolver.</li>
<li>Services for generating URLs (IUrlBuilder) and for automatic data binding (IDataBinder) </li>
<li>Delegate-based rendering (see <a href="http://abombss.com/blog/2007/12/28/ms-mvc-gets-blocks-from-rails/">this post</a> on Adam Tybor&#8217;s blog for more info).</li>
<li> Using IDictionaries for specifying HTML attributes</li>
<li>Methods for generating text fields, text areas, hidden fields, forms and hyperlinks</li>
</ul>
<p>
Some sample code:
</p>
<pre>
&lt;% Form.For("person", new Hash(action =&gt; "Save"), form =&gt; { %&gt;
	Surname: &lt;%= form.TextField("Surname", new Hash(style =&gt; "width: 200px")) %&gt;
	&lt;br /&gt;
	Forename: &lt;%= form.TextField("Forename", new Hash(style =&gt; "width: 200px"))%&gt;
	&lt;br /&gt;&lt;br /&gt;
	&lt;%= form.HiddenField("id") %&gt;
	&lt;%= form.Submit() %&gt;
&lt;% }); %&gt;
</pre>
<p>Which generates&#8230;</p>
<pre>
&lt;form method="post" action="/Home/Save"&gt;
	Surname: &lt;input type="text" id="person_Surname" name="person.Surname" value="Smith" style="width: 200px" /&gt;
	&lt;br /&gt;
	Forename: &lt;input type="text" id="person_Forename" name="person.Forename" value="Jane" style="width: 200px" /&gt;
	&lt;br /&gt;&lt;br /&gt;
	&lt;input type="hidden" id="person_id" name="person.id" value="2" /&gt;
	&lt;input type="submit" value="Submit" /&gt;
&lt;/form&gt;
</pre>
<p>
Note: To run the sample you will need the <a href="http://www.asp.net/downloads/3.5-extensions/">.NET 3.5 Extensions CTP</a> installed.
</p>
<p>
Disclaimers:</p>
<ul>
<li>The DefaultDataBinder implementation uses code from Castle&#8217;s <a href="http://castleproject.org/monorail/">MonoRail</a></li>
<li>The DefaultUrlBuilder uses code from Rob Conery&#8217;s <a href="http://blog.wekeroad.com/2007/12/05/aspnet-mvc-preview-using-the-mvc-ui-helpers/">MvcToolkit</a></li>
<li>The Hash class is inspired by <a href="http://blechie.com/WPierce/archive/2007/12/30/Updated-A-Better-Dictionary-Initializer.aspx">this post</a> on Bill Pierce&#8217;s blog.
</ul>
</p>
<p>
The download can be <a href="http://cid-4a31ad0f2a6040f3.skydrive.live.com/self.aspx/Public/MvcHelpers.zip">found here</a>.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/jeremyskinner.wordpress.com/25/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/jeremyskinner.wordpress.com/25/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jeremyskinner.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jeremyskinner.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jeremyskinner.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jeremyskinner.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jeremyskinner.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jeremyskinner.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jeremyskinner.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jeremyskinner.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jeremyskinner.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jeremyskinner.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jeremyskinner.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jeremyskinner.wordpress.com/25/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jeremyskinner.wordpress.com/25/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jeremyskinner.wordpress.com/25/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jeremyskinner.wordpress.com&amp;blog=813482&amp;post=25&amp;subd=jeremyskinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jeremyskinner.wordpress.com/2008/02/02/helpers-for-the-ms-mvc-framework/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a1c7fe5c1af943c56be58b1dd817b97c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Jez</media:title>
		</media:content>
	</item>
	</channel>
</rss>
