<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title> Unhandled Exception</title><link>http://weblogs.asp.net/davidfowler/default.aspx</link><description>A technical blog about asp.net and other geeky things. Follow me &lt;a href="http://twitter.com/davidfowl/"&gt;http://twitter.com/davidfowl/&lt;/a&gt;
</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>SignalR 1.1 beta</title><link>http://weblogs.asp.net/davidfowler/archive/2013/04/11/signalr-1-1-beta.aspx</link><pubDate>Fri, 12 Apr 2013 05:54:43 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:10139598</guid><dc:creator>davidfowl</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=10139598</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2013/04/11/signalr-1-1-beta.aspx#comments</comments><description>&lt;p&gt;We released SignalR 1.1 yesterday with a bunch of performance improvements and new features (detailed in the &lt;a href="https://github.com/SignalR/SignalR/blob/master/ReleaseNotes.md#110beta"&gt;release notes&lt;/a&gt;). Among these new features, were improvements to the .NET client including the ability to set custom headers, client certificates and a custom JSON serializer. We also fixed a long standing issue people were experiencing in IE7 and IE8 with the loading bar showing up forever in the browser. However, most of this release focused on rewriting SignalR’s scaling out story from the ground up.&lt;/p&gt;  &lt;h2&gt;Scaling out&lt;/h2&gt;  &lt;p&gt;The previous releases of SignalR’s scale out implementation did not handle a lot of scenarios when it came to scaling it across web servers. We took a step back and redesigned the core scale out architecture and backplanes for SQL Server, Azure Service Bus and Redis.&lt;/p&gt;  &lt;p&gt;There are now 3 new packages on NuGet that you can choose from when scaling out SignalR:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://nuget.org/packages/Microsoft.AspNet.SignalR.SqlServer/"&gt;SQL Server&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/packages/Microsoft.AspNet.SignalR.ServiceBus/"&gt;Azure Service Bus&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://nuget.org/packages/Microsoft.AspNet.SignalR.Redis/"&gt;Redis&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;These backplanes share a common base class (ScaleoutMessageBus) that contains the core logic allowing SignalR to work across a webfarm. &lt;/p&gt;  &lt;h4&gt;Using Scale out&lt;/h4&gt;  &lt;p&gt;Registering a backplane hasn’t changed much from the previous versions but there are some new features to be aware of.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;ALL backplanes&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Scale out backplanes have 2 modes controlled by a single flag RetryOnError. Users can create a configuration object for their backplane and specify which mode they want to use. This flag determines if SignalR should start buffering messages when the scale out backplane encounters errors; by default this flag is false. Here is an example:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt; &lt;script src="https://gist.github.com/davidfowl/5369429.js?file=redis.cs"&gt;&lt;/script&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt; &lt;script src="https://gist.github.com/davidfowl/5369429.js?file=retryonerror.cs"&gt;&lt;/script&gt;  &lt;p&gt;In the above scenario, if the Redis service went offline, with RetryOnError = false the call to send a message to all clients would throw synchronously. If RetryOnError was true, the OnError callback would be raised the call would be queued until Redis came back online. This queue does have a limit and when it is full it will also fail.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;SQL SERVER&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The SQL backplane requires that you create the database before hand. &lt;/li&gt;    &lt;li&gt;The SQL scale out backplane works with or without service broker turned on. &lt;/li&gt;    &lt;li&gt;Performance is usually better with service broker on since this enables query notifications to work. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Once the database is set up, you can enable SQL like this:&lt;/p&gt; &lt;script src="https://gist.github.com/davidfowl/5369429.js?file=sql.cs"&gt;&lt;/script&gt;  &lt;p&gt;It’s all you need to get running with SQL server.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;SERVICE BUS&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The new service bus scale out backplane only works with the Windows Azure service. The &lt;a href="https://github.com/SignalR/SignalR/wiki/Azure-service-bus"&gt;wiki&lt;/a&gt; has been updated with new steps that show how to setup service bus on Windows Azure. &lt;/p&gt;  &lt;p&gt;Windows Azure Websites is also supported.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;TRACING&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If you are encountering problems with scale out and want to troubleshoot what’s going on, you can turn on tracing with this xml snippet in your config file:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt; &lt;script src="https://gist.github.com/davidfowl/5369429.js?file=trace.xml"&gt;&lt;/script&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The purpose of this beta release is to get feedback, so do give it a try and let us know what you think. As always, file issues on github, and questions on stackoverflow, &lt;a href="https://jabbr.net/#/rooms/signalr"&gt;jabbr&lt;/a&gt; or the &lt;a href="http://forums.asp.net/1254.aspx"&gt;SignalR forum&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=10139598" width="1" height="1"&gt;</description></item><item><title>Microsoft ASP.NET SignalR</title><link>http://weblogs.asp.net/davidfowler/archive/2012/11/11/microsoft-asp-net-signalr.aspx</link><pubDate>Mon, 12 Nov 2012 02:18:42 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:9369555</guid><dc:creator>davidfowl</dc:creator><slash:comments>35</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=9369555</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2012/11/11/microsoft-asp-net-signalr.aspx#comments</comments><description>&lt;p&gt;Yes, you read that right, &lt;strong&gt;Microsoft.AspNet.SignalR&lt;/strong&gt;. It’s been a while since I last blogged as we’re super busy trying to make SignalR rock solid and 1.0 quality for you all to use. I’ve also given my &lt;strong&gt;first talk ever &lt;/strong&gt;at &lt;a href="http://monkeyspace.org/" target="_blank"&gt;Monkeyspace&lt;/a&gt; and then &lt;a href="http://channel9.msdn.com/Events/Build/2012/3-034" target="_blank"&gt;BUILD&lt;/a&gt; - both on SignalR. SignalR 1.0 alpha has been live for just over 2 weeks on &lt;a href="https://nuget.org/packages/Microsoft.AspNet.SignalR" target="_blank"&gt;NuGet&lt;/a&gt;, and a few seconds ago I just published alpha2. A lot has changed since 0.5.3 and there have been several people poking around trying to find out what’s changed and what’s new in the alpha. There’s also been lots of confusion about what to use, so I’m going to clear things up by enumerating the list of major changes. &lt;/p&gt;  &lt;h2&gt;New Packages&lt;/h2&gt;  &lt;p&gt;There are new packages that you can use today in your applications. &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Microsoft.AspNet.SignalR – meta package (use this) &lt;/li&gt;    &lt;li&gt;Microsoft.AspNet.SignalR.Client – .NET 4 and WinRT client &lt;/li&gt;    &lt;li&gt;Microsoft.AspNet.SignalR.JS – The Javascript client.&lt;/li&gt;    &lt;li&gt;Microsoft.AspNet.SignalR.Core – Core server package with no host implementation &lt;/li&gt;    &lt;li&gt;Microsoft.AspNet.SignalR.Hosting.AspNet – The ASP.NET host &lt;/li&gt;    &lt;li&gt;Microsoft.AspNet.SignalR.Hosting.Utils – utilities for signalr (&lt;strong&gt;signalr.exe&lt;/strong&gt;) &lt;/li&gt;    &lt;li&gt;Microsoft.AspNet.SignalR.Redis – Redis message bus implementation &lt;/li&gt;    &lt;li&gt;Microsoft.AspNet.SignalR.ServiceBus – Service bus message bus implementation &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you’re using the NuGet dialog, pick the IncludePrerelease in the dropdown to see them. If you’re using the package manager console, use the –pre flag to install it.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Install-Package Microsoft.AspNet.SignalR –pre&lt;/strong&gt;&lt;/p&gt;  &lt;h2&gt;Visual Studio Integration&lt;/h2&gt;  &lt;p&gt;When you install the &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=35493"&gt;ASP.NET 2012 Fall Update&lt;/a&gt;, you’ll see a few new things in your &lt;strong&gt;Add New Item&lt;/strong&gt; menu. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/davidfowler/VsIntegration_15ABE3B9.png"&gt;&lt;img title="VsIntegration" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 10px 10px 0px 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="VsIntegration" src="http://weblogs.asp.net/blogs/davidfowler/VsIntegration_thumb_401814D6.png" width="644" height="411" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;These will bring in the alpha1 packages but you can update them using NuGet to get the latest and greatest.&lt;/p&gt;  &lt;h2&gt;Hub API changes&lt;/h2&gt; &lt;script src="https://gist.github.com/4057152.js?file=NewClient.js"&gt;&lt;/script&gt;  &lt;p&gt;First thing to notice is the &lt;strong&gt;client &lt;/strong&gt;and&lt;strong&gt; server&lt;/strong&gt; members on the hub object. This came about because there was a subtle issue with naming methods on the client and server. If they were called the same thing it just wouldn’t work so we decided to separate the namespaces. As you already guessed, you can declare methods that the server calls on the client object and call methods that exist on the server with the server object.&lt;/p&gt;  &lt;p&gt;On the server side we’ve added quite a few new APIs for hubs after lots of feedback and discussion. &lt;/p&gt; &lt;script src="https://gist.github.com/4057152.js?file=AllMethods.cs"&gt;&lt;/script&gt;  &lt;p&gt;This is a dump of all the new surface we’ve added for hubs. The comments are pretty self explanatory but as part of this work we resolved this long standing feature request &lt;a title="https://github.com/SignalR/SignalR/issues/105" href="https://github.com/SignalR/SignalR/issues/105"&gt;https://github.com/SignalR/SignalR/issues/105&lt;/a&gt; (it’s almost a year old!).&lt;/p&gt;  &lt;h2&gt;Connected, Disconnected and Reconnected&lt;/h2&gt;  &lt;p&gt;Before we had these awful interfaces you had to implement to detect this, now it’s just an override on the Hub itself.&lt;/p&gt; &lt;script src="https://gist.github.com/4057152.js?file=Connections.cs"&gt;&lt;/script&gt;  &lt;h2&gt;No more magic?&lt;/h2&gt;  &lt;p&gt;There’s obviously still some magic, just a bit less than before. When using hubs, people always wondered how this magic ~/signalr/hubs url was getting registered. This is now an explicit call the developer has to make to enable this route. When you install the new package, it’ll add a &lt;strong&gt;RegisterHubs.cs&lt;/strong&gt; file to the project in the App_Start folder.&lt;/p&gt; &lt;script src="https://gist.github.com/4057152.js?file=Startup.cs"&gt;&lt;/script&gt;There's even a little comment telling you what MapHubs does. If you want to, you can remove this file and just add the call to your global asax with the rest of your route registration.   &lt;h2&gt;Hub Pipeline&lt;/h2&gt;  &lt;p&gt;This is the most powerful feature we’ve added in the new release. Think of the hub pipeline like mvc filters but more powerful. You get to inject any piece of code anywhere in the hub pipeline for incoming and outgoing calls. Here’s an example of a hub pipeline module that logs all outgoing and incoming calls.&lt;/p&gt; &lt;script src="https://gist.github.com/4057152.js?file=PipelineModule.cs"&gt;&lt;/script&gt;  &lt;p&gt;The module has a bunch of different methods you can override, the above sample only shows 2 of them. Each method takes the appropriate context so you can get whatever information you want about the incoming or outgoing invocation. The next feature on the list builds on the pipeline implementation.&lt;/p&gt;  &lt;h2&gt;Authorization&lt;/h2&gt;  &lt;p&gt;Many of you wanted an easy way to mark a hub as requiring authorization and now you can do that by just specifying an attribute similar to MVC.&lt;/p&gt; &lt;script src="https://gist.github.com/4057152.js?file=Auth.cs"&gt;&lt;/script&gt;  &lt;p&gt;Now you can decorate your hubs or hub methods or both to get different granularities of security. The first example shows requires authorization for all connections to the hub and calls to any incoming methods. In the second example, any connection to the hub as well as calls to Send require authorization, but calls to Send2 do not.&lt;/p&gt;  &lt;h2&gt;Client side keep alive&lt;/h2&gt;  &lt;p&gt;This feature allows clients to react to slow/buggy networks that drop connectivity often. The JavaScript client checks for a keep alive ping from the server on a configurable interval and raises the “connection slow” event before it drops the connection and starts reconnecting.&lt;/p&gt; &lt;script src="https://gist.github.com/4057152.js?file=KeepAlive.js"&gt;&lt;/script&gt;  &lt;h2&gt;Rejoining Groups&lt;/h2&gt;  &lt;p&gt;There’s tons of confusion about how groups work in SignalR and how it works in scaled out environments (&lt;a title="http://stackoverflow.com/questions/11143220/signalr-groups-filtering-handled-on-client-or-server" href="http://stackoverflow.com/questions/11143220/signalr-groups-filtering-handled-on-client-or-server" target="_blank"&gt;http://stackoverflow.com/questions/11143220/signalr-groups-filtering-handled-on-client-or-server&lt;/a&gt;). SignalR stores enough state on the server to make groups work, but all groups that a client is a member of is round-tripped with that client. This of course means that any client can claim they are in a group and spy on your messages. Groups are not a security feature, it’s about message filtering. By default, SignalR will ignore groups that are sent from client to server (to be secure by default). Clients will not be able to receive messages for groups they were in after a reconnect for most transports, but for longpolling it will be immediate. Developers can re-enable the default behavior by enabling a pipeline module that trusts the client’s groups.&lt;/p&gt; &lt;script src="https://gist.github.com/4057152.js?file=RejoiningGroups.cs"&gt;&lt;/script&gt;  &lt;p&gt;If you’re more advanced and want to apply a custom filter to pre-process groups for particular clients, you can write a custom pipeline module to do so.&lt;/p&gt;  &lt;h2&gt;New Scale Out Providers&lt;/h2&gt;  &lt;p&gt;We’ve completely re-worked the scale out providers for service bus and redis and added sql server to the list (not shipping with this release but you can use the &lt;a href="https://github.com/SignalR/SignalR/tree/master/src/Microsoft.AspNet.SignalR.SqlServer" target="_blank"&gt;source&lt;/a&gt;). As part of this work, we’ve abstracted a ScaleOutMessageBus base class that each of these providers derive from in order to cleanly plug into SignalR. Check out the &lt;a title="https://github.com/SignalR/SignalR/blob/master/src/Microsoft.AspNet.SignalR.Core/MessageBus/ScaleoutMessageBus.cs" href="https://github.com/SignalR/SignalR/blob/master/src/Microsoft.AspNet.SignalR.Core/MessageBus/ScaleoutMessageBus.cs" target="_blank"&gt;class&lt;/a&gt; for more details.&lt;/p&gt;  &lt;h2&gt;More Memory Efficient and huge throughput gains&lt;/h2&gt;  &lt;p&gt;The MessageBus was complete re-written and optimized for small messages (we normally test with 32 byte sized message payloads) and high throughput. More memory efficient means that we can get more connections on a single node. By the time we RTM, we’ll have documentation and guidance on how to do capacity planning on your webservers and on azure. &lt;/p&gt;  &lt;h2&gt;Performance Counters&lt;/h2&gt;  &lt;p&gt;We have a utility called &lt;strong&gt;signalr.exe &lt;/strong&gt;(in the &lt;a href="https://nuget.org/packages/Microsoft.AspNet.SignalR.Hosting.Utils/"&gt;Microsoft.AspNet.SignalR.Hosting.Utils&lt;/a&gt; package) that you can use to do a few things.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Install/Uninstall SignalR performance counters &lt;/li&gt;    &lt;li&gt;Generate a static js file for the magic ~/signalr/hubs url. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You can install the performance counters if you want to see more detailed information about your SignalR applications. Here’s a view of what that looks like:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/davidfowler/Counters_0B812A6A.png"&gt;&lt;img title="Counters" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 10px 10px 0px 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Counters" src="http://weblogs.asp.net/blogs/davidfowler/Counters_thumb_5191E77D.png" width="644" height="462" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;NOTE: &lt;/strong&gt;To use these on full IIS you need to add the app pool user for your application to the &lt;strong&gt;Performance Monitor Users&lt;/strong&gt; group.&lt;/p&gt;  &lt;h2&gt;Message payload size&lt;/h2&gt;  &lt;p&gt;We’ve made some changes (not in alpha2 but later) to reduce the size of our payload dramatically and as a result changed the protocol for 1.0 as well. I’ll talk about this more in a later post.&lt;/p&gt;  &lt;h2&gt;Documentation&lt;/h2&gt;  &lt;p&gt;We’re in the process of updating it as well as preparing content for &lt;a title="http://www.asp.net/signalr" href="http://www.asp.net/signalr" target="_blank"&gt;http://www.asp.net/signalr&lt;/a&gt;. Stay tuned!&lt;/p&gt;  &lt;h2&gt;THANK YOU ALL&lt;/h2&gt;  &lt;p&gt;Thank you all for being a part of this amazing journey from side project to official project. Thanks to your enthusiasm it has has grown rapidly into a framework that people just love to use! Keep giving us feedback! Ping me on &lt;a href="https://jabbr.net/#/rooms/signalr" target="_blank"&gt;jabbr&lt;/a&gt; or &lt;a href="https://twitter.com/davidfowl" target="_blank"&gt;twitter&lt;/a&gt; if you have any questions! &lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=9369555" width="1" height="1"&gt;</description></item><item><title>SignalR 0.5.1 Released</title><link>http://weblogs.asp.net/davidfowler/archive/2012/06/10/signalr-0-5-1-released.aspx</link><pubDate>Mon, 11 Jun 2012 05:17:01 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8594574</guid><dc:creator>davidfowl</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=8594574</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2012/06/10/signalr-0-5-1-released.aspx#comments</comments><description>&lt;p&gt;Here comes another exciting release of &lt;a href="http://signalr.net/releases/"&gt;SignalR&lt;/a&gt;. This release has some new features that you can take advantage of as well as a few bug fixes. Let’s go over the big changes for this release.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Windows 8 Client support&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;With the Windows 8 Release Preview, we’ve finally added a new client to support “.NET for Metro Style Apps” and also made some fixes so that SignalR’s JavaScript client works with WinJS.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;WebSocket Support&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Previously, websocket support required a separate package, now it’s built into SignalR. The ASP.NET host is the only one that supports this and that’s only when running an application targeting .NET 4.5 on IIS8.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;&lt;strong&gt;Improved Cross Domain Support&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;We introduced cross domain support for SignalR in 0.5. In this release we’ve improved that support in a few ways: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;All SignalR end points are CORS enabled by default. This means you can point the JavaScript client to the endpoint and have it just work without having to manually add the cors header to web.config. &lt;/li&gt;    &lt;li&gt;SignalR will choose automatically negotiate the transport so there’s no need to specify it or the xdomain flag (which is no longer supported). &lt;/li&gt; &lt;/ol&gt;  &lt;pre style="font-family: ; background: white"&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;$.connection.hub.url = &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;'http://localhost:8081/signalr;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;&lt;br /&gt; &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;$.connection.hub.start();&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;The above code is all you need to do to connect to a remote server using SignalR. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Connection State Changes&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A SignalR connection has always been a black box to the user and this made it hard to detect changes in the underlying connection state. We’ve exposed a new stateChanged event in the JavaScript and .NET clients. This allows you to listen for state changes and react to them in different ways. Here’s an example that shows the user a message if the connection went into a reconnecting state and didn’t recover after 10 seconds:&lt;/p&gt;

&lt;pre style="font-family: ; background: white; color: "&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt; chat = $.connection.chat;&lt;/font&gt;&lt;br /&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; timeout = &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;null&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; interval = 10000;&lt;br /&gt; &lt;br /&gt;chat.addMessage = &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;function&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; (msg) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;'#messages'&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;).append(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;'&amp;lt;li&amp;gt;'&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; + msg + &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;'&amp;lt;/li&amp;gt;'&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;);&lt;br /&gt;};&lt;br /&gt; &lt;br /&gt;$.connection.hub.stateChanged(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;function&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; (change) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; (change.newState === $.signalR.connectionState.reconnecting) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; timeout = setTimeout(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;function&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; () {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;'#state'&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;).css(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;'backgroundColor'&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;'red'&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .html(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;'The server is unreachable...'&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }, interval);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;else&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; (timeout &amp;amp;&amp;amp; change.newState === $.signalR.connectionState.connected) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;'#state'&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;).css(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;'backgroundColor'&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;'green'&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .html(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;'The server is online'&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;);&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; clearTimeout(timeout);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; timeout = &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;null&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;br /&gt;});&lt;br /&gt; &lt;br /&gt;$.connection.hub.start();&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;When the connection state changes to reconnecting, we set a 10 second timer, if the state doesn’t change to “connected” in those 10 seconds then we set the message to say the server is unreachable. When the connection comes back online (i.e the state the connected), we set the message, “The server is online”. &lt;/p&gt;

&lt;p&gt;This feature should give app developers a chance to deliver nicer user experiences when for clients on crappy connections or when servers go down unexpectedly. We’ll continue to improve this in the future.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Clean Disconnect&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Normally when a connection is broken between the browser and server, the underlying http request takes some time to go away (you can use fiddler to see this). In 0.5.1 we’ve added the ability for the client to send a packet to the server whenever a connection is stopped or the browser is closed. This means disconnect will fire more immediately on browser close or on page refreshes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Hubify.exe&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’s not a nuget package but will be in the &lt;a href="http://chocolatey.org/"&gt;http://chocolatey.org/&lt;/a&gt; gallery soon. For now, you can run get &lt;strong&gt;hubify.exe &lt;/strong&gt;by building &lt;a href="https://github.com/SignalR/SignalR/tree/master/SignalR.ProxyGenerator"&gt;https://github.com/SignalR/SignalR/tree/master/SignalR.ProxyGenerator&lt;/a&gt;. You can run this against your project’s bin directory or a remote url to generate or download the hubs.js file that would normally be dynamically generated when referencing the magic script url:&lt;/p&gt;

&lt;pre style="font-family: ; background: white; color: "&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;script&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;src&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;signalR/hubs&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;type&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;script&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font style="font-size: 9.8pt" color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;You can add this to a post build event in your project to generate the file a build time so that you can take advantage of http caching when you deploy your application (See an example &lt;a href="https://github.com/SignalR/SignalR/blob/master/samples/SignalR.Hosting.AspNet.Samples/SignalR.Hosting.AspNet.Samples.csproj#L273"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Keep Alive&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Keep alive is now on by default and is set to 30 seconds.&lt;/p&gt;

&lt;p&gt;Those are the highlights, &lt;a href="https://github.com/SignalR/SignalR/blob/master/ReleaseNotes.md"&gt;view the release notes&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;Get it on NuGet today! &lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8594574" width="1" height="1"&gt;</description></item><item><title>API Improvements made in SignalR 0.5</title><link>http://weblogs.asp.net/davidfowler/archive/2012/05/04/api-improvements-made-in-signalr-0-5.aspx</link><pubDate>Fri, 04 May 2012 21:23:32 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8439829</guid><dc:creator>davidfowl</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=8439829</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2012/05/04/api-improvements-made-in-signalr-0-5.aspx#comments</comments><description>&lt;p&gt;We made lots of breaking changes in 0.5 in order to gain more API consistency across the board. Some of the changes may not affect you if you weren’t doing anything with lower level APIs. These types of breaking changes will obviously slow down as we get closer to a 1.0 release.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;&lt;strong&gt;API comments&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;This release, we spent some time writing API comments that should be helpful during development.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Breaking changes&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;A bunch of APIs were removed from PersistentConnection including the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;All overloads of Send &lt;/li&gt;    &lt;li&gt;SendToGroup &lt;/li&gt;    &lt;li&gt;AddToGroup &lt;/li&gt;    &lt;li&gt;RemoveFromGroup &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Sending Data&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;All data is now sent through an IConnection (Connection property). Now, whether you’re within a PersistentConnection or outside of one, the logic to send data over that connection will look exactly the same.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;SignalR 0.4&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;pre style="font-family: ; background: white; color: "&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MyConnection&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;PersistentConnection&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Task&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; OnConnectedAsync(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;IRequest&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; request, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;IEnumerable&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;lt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;gt; groups, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; connectionId)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Connection.Broadcast(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;A new connection was made!&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Task&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; OnReceivedAsync(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; connectionId, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt; data)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Send(data);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;SignalR 0.5&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;pre style="font-family: ; background: white; color: "&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MyConnection&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;PersistentConnection&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Task&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; OnConnectedAsync(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;IRequest&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; request, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; connectionId)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Connection.Broadcast(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;A new connection was made!&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Task&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; OnReceivedAsync(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; connectionId, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt; data)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Connection.Send(connectionId, data);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Groups&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Group management is now centralized and consistent across Hubs and PersistentConnections. Each of those types have a property Groups of type IGroupManager that are scoped to a specific PersistentConnection or Hub. Here’s an example of adding a group in 0.4 and 0.5:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;SignalR 0.4&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;pre style="font-family: ; background: white"&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MyConnection&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;PersistentConnection&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Task&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; OnConnectedAsync(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;IRequest&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; request, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;IEnumerable&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;lt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;gt; groups, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; connectionId)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; AddToGroup(connectionId, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;foo&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Task&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; OnReceivedAsync(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; connectionId, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt; data)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; SendToGroup(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;foo&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;, data);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: ; background: white; color: "&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MyHub&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Hub&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Task&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Join(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; group)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; AddToGroup(group);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Task&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Send(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; group, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt; message)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Clients[group].addMessage(message);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;SignalR 0.5&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;pre style="font-family: ; background: white"&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MyConnection&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;PersistentConnection&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Task&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; OnConnectedAsync(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;IRequest&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; request, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; connectionId)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Groups.Add(connectionId, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;foo&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Task&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; OnReceivedAsync(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; connectionId, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt; data)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Groups.Send(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;foo&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;, data);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: ; background: white; color: "&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MyHub&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Hub&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Task&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Join(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; group)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; Groups.Add(Context.ConnectionId, group);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Task&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Send(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; group, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt; message)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Clients[group].addMessage(message);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Dependency Injection&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We’ve removed the AspNetHost type that from SignaR 0.4 and added a type that is purely optional to use, &lt;strong&gt;GlobalHost&lt;/strong&gt;. The idea behind this type is to allow easy access to items in the container that will be used most commonly in any SignalR application, as well as a host agnostic default dependency resolver. This type exists in a new assembly &lt;strong&gt;SignalR.Hosting.Common.dll.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Replacing the resolver&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;SignalR 0.4&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;pre style="font-family: ; background: white"&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Global&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : System.Web.&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;HttpApplication&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Application_Start(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;object&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; sender, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;EventArgs&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt; e)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;AspNetHost&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.SetResolver(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;CustomResolver&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;());&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;SignalR 0.5&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;pre style="font-family: ; background: white"&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Global&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : System.Web.&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;HttpApplication&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Application_Start(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;object&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; sender, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;EventArgs&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; e)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;GlobalHost&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.DependencyResolver = &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;CustomResolver&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;();&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;RouteTable&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.Routes.MapHubs();&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;Here, we’re changing the global resolver and remapping the default hub route to pick it up. The hub route is automatically added at a very early stage in the application (PreApplicationStart) so we need to remap it to use the new default resolver or we can specify a new one for the hub route directly:&lt;/p&gt;

&lt;pre style="font-family: ; background: white; color: "&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Global&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : System.Web.&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;HttpApplication&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Application_Start(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;object&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; sender, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;EventArgs&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt; e)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;RouteTable&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.Routes.MapHubs(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;CustomResolver&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;());&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;The above logic doesn’t replace the global resolver but instead creates a self contained SignalR world using the specified resolver. If you go with this more “pure” approach, you’re opting out of using the &lt;strong&gt;GlobalHost.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Changing the Hub route&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In 0.4, the magical &lt;strong&gt;signalr/hubs &lt;/strong&gt;url was implemented as a dynamic http module. Now it’s just a regular route in the route table that can be replaced. Here’s an example of changing it to signalr2:&lt;/p&gt;

&lt;pre style="font-family: ; background: white; color: "&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Global&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : System.Web.&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;HttpApplication&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Application_Start(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;object&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; sender, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;EventArgs&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt; e)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;RouteTable&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.Routes.MapHubs(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;~/signalr2&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;Obviously this change needs to be accompanied by a change to your JavaScript include:&lt;/p&gt;

&lt;pre style="font-family: ; background: white; color: "&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;&amp;lt;!&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;DOCTYPE&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;html&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: "&gt;&amp;lt;&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;html&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: "&gt;&amp;lt;&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;head&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;font color="#000000"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;title&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;title&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;font color="#000000"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;script&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;src&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;Scripts/jquery-1.6.4.js&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;type&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;script&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;font color="#000000"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;script&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;src&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;Scripts/jquery.signalR-0.5rc.js&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;type&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;script&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;font color="#000000"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;script&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;src&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;signalr2/hubs&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;type&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;script&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: "&gt;&amp;lt;/&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;head&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: "&gt;&amp;lt;&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;body&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;br /&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;body&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: "&gt;&amp;lt;/&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;html&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font style="font-size: 9.8pt" color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Getting a reference to the connection/hub outside of a connection or hub&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is an extremely popular pattern for integrating with other frameworks. Here’s an example of broadcasting to all clients from an mvc controller:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;SignalR 0.4&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;pre style="font-family: ; background: white; color: "&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;HomeController&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Controller&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; PerformLongRunningOperation()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; connection = &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;AspNetHost&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.DependencyResolver.Resolve&amp;lt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;IConnectionManager&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;gt;().GetConnection&amp;lt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MyConnection&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;&amp;gt;();&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; connection.Broadcast(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;Called from an mvc controller&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; PerformLongRunningHubOperation()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; clients = &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;AspNetHost&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.DependencyResolver.Resolve&amp;lt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;IConnectionManager&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;gt;().GetClients&amp;lt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MyHub&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;gt;();&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; clients.notify(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;Hello world&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;SignalR 0.5&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;pre style="font-family: ; background: white"&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;HomeController&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Controller&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; PerformLongRunningOperation()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;IPersistentConnectionContext&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; context = &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;GlobalHost&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.ConnectionManager.GetConnectionContext&amp;lt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MyConnection&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;&amp;gt;();&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context.Connection.Broadcast(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;Called from an mvc controller&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; PerformLongRunningHubOperation()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;IHubContext&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; context = &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;GlobalHost&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.ConnectionManager.GetHubContext&amp;lt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MyHub&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;gt;();&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; context.Clients.notify(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;Hello world&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;With this, you can inject these new context objects into your mvc controller or whatever framework you want to combine with SignalR. For example:&lt;/p&gt;

&lt;pre style="font-family: ; background: white; color: "&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;HomeController&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Controller&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;readonly&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;IHubContext&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; _hubContext;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; HomeController(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;IHubContext&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; hubContext)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _hubContext = hubContext;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt; PerformLongRunningHubOperation()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _hubContext.Clients.notify(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;Hello world&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Configuring SignalR&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On each host (Self host and GlobalHost) there’s a Configuration property. This gives you access to the server configuration for things like setting timeouts, the keep alive interval and the heart beat interval:&lt;/p&gt;

&lt;pre style="font-family: ; background: white; color: "&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Global&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : System.Web.&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;HttpApplication&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Application_Start(&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;object&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; sender, &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;EventArgs&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#000000"&gt; e)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;GlobalHost&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.Configuration.KeepAlive = &lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;TimeSpan&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.FromSeconds(20);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;I’ll be blogging about more of these changes as we get closer to the release of 0.5. &lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8439829" width="1" height="1"&gt;</description></item><item><title>SignalR 0.5</title><link>http://weblogs.asp.net/davidfowler/archive/2012/05/02/signalr-0-5.aspx</link><pubDate>Thu, 03 May 2012 04:29:38 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8433746</guid><dc:creator>davidfowl</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=8433746</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2012/05/02/signalr-0-5.aspx#comments</comments><description>&lt;p&gt;This is the rebirth of my blog. I’ve been busy over the last few months with projects like &lt;a href="https://github.com/davidfowl/JabbR"&gt;JabbR&lt;/a&gt;, &lt;a href="http://signalr.net"&gt;SignalR&lt;/a&gt; and other stuff. With the upcoming release of SignalR 0.5, I thought it’d be good to write a blog post that touches on some of the things we did.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Webfarm Support&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;There’s a lot of confusion as to what webfarm support means in SignalR. This is an FYI, SignalR 0.5 will not automatically make your application work on azure with zero effort. SignalR needs a way to communicate between instances of your webserver, in 0.5 we implemented 2 of those providers on NuGet (message buses):&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;SignalR.WindowsAzureServiceBus&lt;/strong&gt; - &lt;a href="http://vasters.com/clemensv/2012/02/13/SignalR+Powered+By+Service+Bus.aspx"&gt;http://vasters.com/clemensv/2012/02/13/SignalR+Powered+By+Service+Bus.aspx&lt;/a&gt; (blog post slightly outdated but information is relevant). &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;SignalR.Redis&lt;/strong&gt; – Redis message bus implementation for SignalR - &lt;a href="https://github.com/SignalR/SignalR.Redis"&gt;https://github.com/SignalR/SignalR.Redis&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;When deciding to make SignalR work in a webfarm, you’ll have these 2 options. We’re going to continue improving them as well as implement solutions on top of popular message buses like NServiceBus and lower fidelity solutions built on top of SQL QNS and possibly SQL Server Service Broker. &lt;/p&gt;  &lt;p&gt;This wasn’t the only hurdle to making SignalR work in webfarms, there were some nasty bugs that caused some bad behavior that we fixed:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Disconnect notifications across webfarms &lt;/li&gt;    &lt;li&gt;Load balancer idle timeout in azure. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Fixing disconnect in webfarms was the most important issue to fix. Before SignalR 0.5rc, disconnect in a webfarm (using service bus or redis) could fire for the same client multiple times. This is more obvious when using longPolling and load balancing happens between web server instances. If you had control of your LB, you could affinitize clients to a server so you’d never see this behavior, but I’m glad to say we got this fixed.&lt;/p&gt;  &lt;p&gt;For load balancer idle timeouts (especially on azure), we support keep-alive. You can now tell SignalR to send an empty packet on a specific time interval. This will fend off nosy network devices that like to kill idle connections waiting for data. This is especially important for things like server sent events and forever frame transports.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Mono Support&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In the 0.4 release, SignalR only “worked” when self hosted on mono so I spent time making SignalR work across the board (ASP.NET and all). When I say work, I mean both the client and the server. You can now literally clone SignalR onto your OSX (I didn’t try linux) box and run &lt;strong&gt;make&lt;/strong&gt; and get a successful build (see the README for more details). This wasn’t a simple task as I had to make changes to the NuGet targets file so that package restore worked on mono.&lt;/p&gt;  &lt;p&gt;If you’re using Mono develop, open SignalR.Mono.sln. You can run the samples as you would normally. Here’s a glimpse of the chat demo running:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/davidfowler/551939760_611EAF3C.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 10px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="551939760" border="0" alt="551939760" src="http://weblogs.asp.net/blogs/davidfowler/551939760_thumb_20743ACF.png" width="644" height="404" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Not much time was spent optimizing and tuning specifically for mono but in the future we’ll have time to do that.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;JsonP Longpolling support (XDomain)&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This feature wasn’t planned for 0.5 but thanks to an awesome contribution from &lt;a href="https://github.com/codeputty"&gt;codeputty&lt;/a&gt;, this became a reality. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Dynamic Hubs Implementation&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Contributor &lt;a href="https://github.com/pszmyd"&gt;pszmyd&lt;/a&gt; was trying to build better integration between SignalR and Orchard and ended up adding infrastructure to SignalR to decouple Hubs from types (System.Type). This is a great example of why I love OSS development (scratch your own itch).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Continuous Integration and NuGet Server&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;We finally got a CI server setup on codebetter’s teamcity instance. You can view SignalR here &lt;a href="http://teamcity.codebetter.com/project.html?projectId=project188"&gt;http://teamcity.codebetter.com/project.html?projectId=project188&lt;/a&gt;. The CI also builds packages and pushes them to our myget feed. If you want to live on the bleeding edge but don’t want to build from source, you can configure nuget to point to &lt;a href="http://www.myget.org/F/signalr/"&gt;http://www.myget.org/F/signalr/&lt;/a&gt; (make sure you use the –Pre flag or select the &lt;strong&gt;&lt;a href="http://docs.nuget.org/docs/release-notes/nuget-1.7#Show_prerelease_packages_in_the_Manage_NuGet_packages_dialog"&gt;Include Prerelease in the dialog&lt;/a&gt;&lt;/strong&gt;).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;0.5 Release&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Help us test the RC now on NuGet! (&lt;a href="http://signalr.net/releases/v0584.html"&gt;http://signalr.net/releases/v0584.html&lt;/a&gt;). We’re reserving this week for any bugs that we consider ship stoppers. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;What’s Next&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;We’re going to continue improving SignalR. Future releases will focus on some of the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Performance Improvements &lt;/li&gt;    &lt;li&gt;In the box WebSockets support for Windows8 &lt;/li&gt;    &lt;li&gt;Windows 8 .NET Client &lt;/li&gt;    &lt;li&gt;.NET Micro Framework Client &lt;/li&gt;    &lt;li&gt;Web API Host &lt;/li&gt;    &lt;li&gt;Build time hubs.js generation (instead of runtime). &lt;/li&gt;    &lt;li&gt;Better network availability handling &lt;/li&gt;    &lt;li&gt;Better Mobile support (optimized for battery life) &lt;/li&gt;    &lt;li&gt;Web Forms control &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;… And much more! Check the &lt;a href="https://github.com/SignalR/SignalR/issues?labels=&amp;amp;milestone=7&amp;amp;page=1&amp;amp;state=open"&gt;issue backlog&lt;/a&gt; for details on what else we've got planned for upcoming releases.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Come Talk with us&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;We’re always around in the &lt;a href="http://jabbr.net/#/rooms/signalr"&gt;signalr&lt;/a&gt; room on jabbr. Come say hi!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8433746" width="1" height="1"&gt;</description></item><item><title>Razor Debugger for ASP.NET WebPages</title><link>http://weblogs.asp.net/davidfowler/archive/2010/11/14/razor-debugger-for-asp-net-webpages.aspx</link><pubDate>Mon, 15 Nov 2010 07:47:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7643596</guid><dc:creator>davidfowl</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=7643596</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2010/11/14/razor-debugger-for-asp-net-webpages.aspx#comments</comments><description>&lt;P&gt;I have neglected blogging recently because I’ve been super busy working on Razor tooling, NuGet and &lt;A href="http://www.microsoft.com/web/webmatrix/" mce_href="http://www.microsoft.com/web/webmatrix/"&gt;Beta 3 Release of the Web Stack&lt;/A&gt;. Now that I have some free time, I can blog about a really cool project I’ve been working on.&lt;/P&gt;  &lt;P&gt;The Razor Debugger is a simple web based debugger for ASP.NET WebPages (it might work in MVC but hasn’t really be tested). It started off as an experiment to see if it was possible to have a simple debugging experience for developers using WebMatrix. &lt;/P&gt;  &lt;H2&gt;It’s a NuGet Package&lt;/H2&gt;  &lt;P&gt;Of course the Razor Debugger is distributed as a &lt;A href="http://nuget.codeplex.com/" mce_href="http://nuget.codeplex.com/"&gt;NuGet&lt;/A&gt; &lt;A href="http://nuget.org/Packages/Packages/Details/RazorDebugger-0-1" mce_href="http://nuget.org/Packages/Packages/Details/RazorDebugger-0-1"&gt;package&lt;/A&gt; and is available today on the WebMatrix feed. You can learn more about ASP.NET WebPages package management &lt;A href="http://channel9.msdn.com/Blogs/gduthie/Microsoft-WebMatrix-Beta-3-New-Features" mce_href="http://channel9.msdn.com/Blogs/gduthie/Microsoft-WebMatrix-Beta-3-New-Features"&gt;here&lt;/A&gt;.&lt;/P&gt;  &lt;H2&gt;Debugging Tutorial&lt;/H2&gt;  &lt;P&gt;Let’s step through a simple example on how to use the debugger with your site.&lt;/P&gt;  &lt;P&gt;Start by opening WebMatrix and choose &lt;STRONG&gt;Site From Template&lt;/STRONG&gt;. Create a new &lt;STRONG&gt;Empty Site &lt;/STRONG&gt;and create a new cshtml page.&lt;/P&gt;  &lt;P&gt;&lt;A href="http://weblogs.asp.net/blogs/davidfowler/image_282AF9CD.png" mce_href="http://weblogs.asp.net/blogs/davidfowler/image_282AF9CD.png"&gt;&lt;IMG style="border-width: 0px; margin: 10px 10px 0px 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_260DFB04.png" width="1028" height="612" mce_src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_260DFB04.png"&gt;&lt;/A&gt;&lt;/P&gt;  &lt;P&gt;Next, we’re going to install the RazorDebugger through the admin UI. Launch the website and navigate to the _Admin url in your browser:&lt;/P&gt;  &lt;P&gt;&lt;A href="http://weblogs.asp.net/blogs/davidfowler/image_2B7C6BA8.png" mce_href="http://weblogs.asp.net/blogs/davidfowler/image_2B7C6BA8.png"&gt;&lt;IMG style="border-width: 0px; margin: 10px 10px 0px 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_7120F5C6.png" width="1028" height="612" mce_src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_7120F5C6.png"&gt;&lt;/A&gt;&lt;/P&gt;  &lt;P&gt;Type your secret password and continue to the Package Manager. List all packages from the online feed and install the RazorDebugger package:&lt;/P&gt;  &lt;P&gt;&lt;A href="http://weblogs.asp.net/blogs/davidfowler/image_33B0913F.png" mce_href="http://weblogs.asp.net/blogs/davidfowler/image_33B0913F.png"&gt;&lt;IMG style="border-width: 0px; margin: 10px 10px 0px 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_468514E9.png" width="1028" height="612" mce_src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_468514E9.png"&gt;&lt;/A&gt;&lt;/P&gt;  &lt;P&gt;After installing the debugger, navigate to the debugger page by going to ~/debugger.&lt;/P&gt;  &lt;P&gt;&lt;A href="http://weblogs.asp.net/blogs/davidfowler/image_0431FCA6.png" mce_href="http://weblogs.asp.net/blogs/davidfowler/image_0431FCA6.png"&gt;&lt;IMG style="border-width: 0px; margin: 10px 10px 0px 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_6DFBE153.png" width="1028" height="612" mce_src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_6DFBE153.png"&gt;&lt;/A&gt;&lt;/P&gt;  &lt;P&gt;The debugger is a section of the website that shows all of the pages on the left, and some UI on the right that we’ll describe in further details below.&lt;/P&gt;  &lt;P&gt;To start debugging your site, put some code in the page and click on the page in the debug view.&lt;/P&gt;  &lt;P&gt;&lt;A href="http://weblogs.asp.net/blogs/davidfowler/image_618DBE2A.png" mce_href="http://weblogs.asp.net/blogs/davidfowler/image_618DBE2A.png"&gt;&lt;IMG style="border-width: 0px; margin: 10px 10px 0px 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_1240C5D6.png" width="1028" height="612" mce_src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_1240C5D6.png"&gt;&lt;/A&gt;&lt;/P&gt;  &lt;P&gt;Now that we have some code in our page we can set a break point by clicking on the gray pane beside the line numbers in source view. When a break point is set, a red circle will be placed on the line where the break point was set.&lt;/P&gt;  &lt;P&gt;Start debugging! Click on &lt;STRONG&gt;Launch Page &lt;/STRONG&gt;at the top of the page to run the page. Switch back to the debugger and see the break point being hit.&lt;/P&gt;  &lt;P&gt;&lt;A href="http://weblogs.asp.net/blogs/davidfowler/image_65B795EF.png" mce_href="http://weblogs.asp.net/blogs/davidfowler/image_65B795EF.png"&gt;&lt;IMG style="border-width: 0px; margin: 10px 10px 0px 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_4F817A9D.png" width="1028" height="612" mce_src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_4F817A9D.png"&gt;&lt;/A&gt;&lt;/P&gt;  &lt;P&gt;Now that we’re debugging, we can use the &lt;STRONG&gt;Step Into, Step Over, Step Out &lt;/STRONG&gt;and&lt;STRONG&gt; Run &lt;/STRONG&gt;buttons or the associated shortcut keys&lt;STRONG&gt;. &lt;/STRONG&gt;Also, as you step, the locals, watches and stack trace UI at the bottom will change to show locals and watches respectively.&lt;/P&gt;  &lt;P&gt;&lt;A href="http://weblogs.asp.net/blogs/davidfowler/image_750AF7FE.png" mce_href="http://weblogs.asp.net/blogs/davidfowler/image_750AF7FE.png"&gt;&lt;IMG style="border-width: 0px; margin: 10px 10px 0px 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_3AAF821D.png" width="1028" height="612" mce_src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_3AAF821D.png"&gt;&lt;/A&gt;&lt;/P&gt;  &lt;P&gt;You can also change the values of locals by clicking on the value of the local and typing a new one.&lt;/P&gt;  &lt;P&gt;&lt;A href="http://weblogs.asp.net/blogs/davidfowler/image_6B6289C8.png" mce_href="http://weblogs.asp.net/blogs/davidfowler/image_6B6289C8.png"&gt;&lt;IMG style="border-width: 0px; margin: 10px 10px 0px 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_310713E7.png" width="1028" height="612" mce_src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_310713E7.png"&gt;&lt;/A&gt;&lt;/P&gt;    &lt;H2&gt;Stepping into other pages&lt;/H2&gt;  &lt;P&gt;It’s possible to step into other pages if a call to &lt;STRONG&gt;RenderPage&lt;/STRONG&gt; is made within the page you are debugging. I’ve updated the sample to contain 2 pages, Page.cshtml passes an anonymous type with the Name “David” to Page2.cshtml.&lt;/P&gt;  &lt;P&gt;&lt;A href="http://weblogs.asp.net/blogs/davidfowler/image_0FA76E4B.png" mce_href="http://weblogs.asp.net/blogs/davidfowler/image_0FA76E4B.png"&gt;&lt;IMG style="border-width: 0px; margin: 10px 10px 0px 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_074398F4.png" width="1028" height="612" mce_src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_074398F4.png"&gt;&lt;/A&gt;&lt;/P&gt;  &lt;P&gt;Now we can hit S&lt;STRONG&gt;tep Into or i &lt;/STRONG&gt;and step into Page2.cshtml.&lt;/P&gt;  &lt;P&gt;&lt;A href="http://weblogs.asp.net/blogs/davidfowler/image_5ABA690D.png" mce_href="http://weblogs.asp.net/blogs/davidfowler/image_5ABA690D.png"&gt;&lt;IMG style="border-width: 0px; margin: 10px 10px 0px 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_2B1C4A81.png" width="1028" height="612" mce_src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_2B1C4A81.png"&gt;&lt;/A&gt;&lt;/P&gt;    &lt;H2&gt;Exceptions&lt;/H2&gt;  &lt;P&gt;The debugger also supports unhandled exceptions. The page below shows an example of a NullReferenceException. When an exception occurs the line is highlighted with a dotted border (it’s kind of hard to see) and the exception object shows up in the locals window.&lt;/P&gt;  &lt;P&gt;&lt;A href="http://weblogs.asp.net/blogs/davidfowler/image_69A19827.png" mce_href="http://weblogs.asp.net/blogs/davidfowler/image_69A19827.png"&gt;&lt;IMG style="border-width: 0px; margin: 10px 10px 0px 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_080BD911.png" width="1028" height="612" mce_src="http://weblogs.asp.net/blogs/davidfowler/image_thumb_080BD911.png"&gt;&lt;/A&gt;&lt;/P&gt;    &lt;H2&gt;Start Debugging&lt;/H2&gt;  &lt;P&gt;This debugger is a prototype and isn’t meant to replace the debugger in visual studio by any means. It is however a pretty cool experiment and you can try it out today in your ASP.NET WebPages!&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7643596" width="1" height="1"&gt;</description></item><item><title>Dynamic LINQ Part 2 (Evolution)</title><link>http://weblogs.asp.net/davidfowler/archive/2010/08/19/dynamic-linq-part-2-evolution.aspx</link><pubDate>Thu, 19 Aug 2010 08:34:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7596386</guid><dc:creator>davidfowl</dc:creator><slash:comments>13</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=7596386</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2010/08/19/dynamic-linq-part-2-evolution.aspx#comments</comments><description>&lt;p&gt;A while ago, Scott Gu &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx"&gt;blogged&lt;/a&gt; about a Dynamic LINQ library that was part of the C# samples in VS2008. This library let developers put together late bound LINQ queries using a special syntax. This really comes in handy when you want to build a LINQ query based on dynamic input. Consider the following example:&lt;/p&gt;  &lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ActionResult&lt;/span&gt; List(&lt;span style="color: blue"&gt;string&lt;/span&gt; sort) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; northwind = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;NorthwindEntities&lt;/span&gt;();&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&amp;gt; products = northwind.Products;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;switch&lt;/span&gt; (sort) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;case&lt;/span&gt;&amp;#160;&lt;span style="color: #a31515"&gt;&amp;quot;ProductName&amp;quot;&lt;/span&gt;:&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; products = products.OrderBy(p =&amp;gt; p.ProductName);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;case&lt;/span&gt;&amp;#160;&lt;span style="color: #a31515"&gt;&amp;quot;UnitsInStock&amp;quot;&lt;/span&gt;:&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; products = products.OrderBy(p =&amp;gt; p.UnitsInStock);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;default&lt;/span&gt;:&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; View(products.ToList());&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;In the above example, we’re trying to sort a list of products based on the sort parameter before we render the view. Writing the above code is painful, especially if you have a large number of sortable fields. Of course this isn’t the only way to write this code, in fact, if you’re a LINQ expert you can &lt;a href="http://weblogs.asp.net/davidfowler/archive/2008/12/11/dynamic-sorting-with-linq.aspx"&gt;build an expression tree at runtime&lt;/a&gt; that represents the sort expression, but that solution is far from trivial to implement.&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;&lt;a href="http://weblogs.asp.net/davidfowler/archive/2010/08/04/dynamic-linq-a-little-more-dynamic.aspx"&gt;Last time&lt;/a&gt; we showed how we can (ab)use C# 4 dynamic feature to enable LINQ queries against dynamic types. Today I’ll show you how we can expand on that concept, and turn our previous solution into a general purpose library that allows us to execute late bound queries against existing LINQ providers.&lt;/p&gt;

&lt;p&gt;The library itself is pretty small, it consists of 2 classes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;DynamicExpressionBuilder – The dynamic object that we used last time to build the actual expression tree &lt;/li&gt;

  &lt;li&gt;DynamicQueryable – a static class with a bunch of extension methods that are parallel to the actual Queryable static class &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DynamicExpressionBuilder uses the same trick as last time (dynamic dispatch to build expressions), but this time we’re building expressions that would be recognized by most LINQ providers.&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;override&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;bool&lt;/span&gt; TryGetMember(&lt;span style="color: #2b91af"&gt;GetMemberBinder&lt;/span&gt; binder, &lt;span style="color: blue"&gt;out&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;object&lt;/span&gt; result) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; result = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicExpressionBuilder&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Property(Expression, binder.Name));&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;true&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;override&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;bool&lt;/span&gt; TryBinaryOperation(&lt;span style="color: #2b91af"&gt;BinaryOperationBinder&lt;/span&gt; binder, &lt;span style="color: blue"&gt;object&lt;/span&gt; arg, &lt;span style="color: blue"&gt;out&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;object&lt;/span&gt; result) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; result = MakeBinaryBuilder(Expression, binder.Operation, arg);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;true&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;override&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;bool&lt;/span&gt; TryInvokeMember(&lt;span style="color: #2b91af"&gt;InvokeMemberBinder&lt;/span&gt; binder, &lt;span style="color: blue"&gt;object&lt;/span&gt;[] args, &lt;span style="color: blue"&gt;out&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;object&lt;/span&gt; result) {&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;MethodInfo&lt;/span&gt; methodInfo = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (args.Any(a =&amp;gt; a == &lt;span style="color: blue"&gt;null&lt;/span&gt;)) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; methodInfo = Expression.Type.GetMethod(binder.Name);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;else&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; types = args.Select(arg =&amp;gt; arg.GetType()).ToArray();&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; methodInfo = Expression.Type.GetMethod(binder.Name, types);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (methodInfo != &lt;span style="color: blue"&gt;null&lt;/span&gt;) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; expression = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Call(Expression, methodInfo, args.Select(&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Constant));&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicExpressionBuilder&lt;/span&gt;(expression);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;true&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;base&lt;/span&gt;.TryInvokeMember(binder, args, &lt;span style="color: blue"&gt;out&lt;/span&gt; result);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;The actual implementation overrides more methods, but for brevity we’re only going to look at 3 of them. Each method captures the intent of the code &lt;br /&gt;and turns it into the appropriate&lt;/font&gt;&lt;font face="Trebuchet MS"&gt; expression tree. &lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicQueryable&lt;/span&gt; {&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt; Where(&lt;span style="color: blue"&gt;this&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt; source, &lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt;, &lt;span style="color: blue"&gt;dynamic&lt;/span&gt;&amp;gt; predicate) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; Where(source, GetExpression(source.ElementType, predicate));&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;LambdaExpression&lt;/span&gt; GetExpression(&lt;span style="color: #2b91af"&gt;Type&lt;/span&gt; elementType, &lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt;, &lt;span style="color: blue"&gt;dynamic&lt;/span&gt;&amp;gt; expressionBuilder) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;ParameterExpression&lt;/span&gt; parameterExpression = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Parameter(elementType, expressionBuilder.Method.GetParameters()[0].Name);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;DynamicExpressionBuilder&lt;/span&gt; dynamicExpression = expressionBuilder(&lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicExpressionBuilder&lt;/span&gt;(parameterExpression));&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt; body = dynamicExpression.Expression;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Lambda(body, parameterExpression);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt; Where(&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt; source, &lt;span style="color: #2b91af"&gt;LambdaExpression&lt;/span&gt; expression) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; source.Provider.CreateQuery(&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Call(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Queryable&lt;/span&gt;),&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #a31515"&gt;&amp;quot;Where&amp;quot;&lt;/span&gt;,&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;new&lt;/span&gt;[] { source.ElementType },&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; source.Expression,&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Quote(expression)));&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;    …etc&lt;br /&gt;}&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Normally when you’re writing LINQ queries, the implementations of Where, Select, SelectMany and other extension methods come from either the &lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.aspx"&gt;Enumerable&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.queryable.aspx"&gt;Queryable&lt;/a&gt; &lt;br /&gt;class.The DynamicQueryable class uses this pattern to provide overloads of the same extension methods on the non generic IQueryable.&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;This lets us do a lot of cool things with existing LINQ providers. Let’s look at some examples:&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Program&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;void&lt;/span&gt; Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;NorthwindEntities&lt;/span&gt; northwind = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;NorthwindEntities&lt;/span&gt;();&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; query = northwind.Products.Where(p =&amp;gt; p.UnitPrice &amp;lt; 10).OrderBy(p =&amp;gt; p.ProductName);&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt; p &lt;span style="color: blue"&gt;in&lt;/span&gt; query) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(p.ProductName);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Above we have a regular LINQ to Entities query against Northwind. Notice the usings are System, and System.Linq, those make sure that you’re using the Queryable &lt;br /&gt;implementations of Where and OrderBy.&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;We can write this same code in with Dynamic LINQ:&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; DynamicLINQ;&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Program&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;void&lt;/span&gt; Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;NorthwindEntities&lt;/span&gt; northwind = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;NorthwindEntities&lt;/span&gt;();&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; query = northwind.Products.Where(p =&amp;gt; p.UnitPrice &amp;lt; 10).OrderBy(p =&amp;gt; p.ProductName);&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt; p &lt;span style="color: blue"&gt;in&lt;/span&gt; query) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(p.ProductName);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;We replaced the System.Linq using with a DynamicLINQ using, which makes use of our extensions methods. If we wanted to sort by a dynamic variable you could do it &lt;br /&gt;using the indexer syntax supported by DynamicQueryBuilder:&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; DynamicLINQ;&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Program&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;void&lt;/span&gt; Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;NorthwindEntities&lt;/span&gt; northwind = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;NorthwindEntities&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; query = northwind.Products.Where(p =&amp;gt; p.UnitPrice &amp;lt; 10).OrderBy(p =&amp;gt; p[&lt;span style="color: #a31515"&gt;&amp;quot;ProductName&amp;quot;&lt;/span&gt;]);&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt; p &lt;span style="color: blue"&gt;in&lt;/span&gt; query) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(p.ProductName);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;That’s all pretty cool, but there are more scenarios that can’t be done today using regular LINQ which Dynamic LINQ makes easy. &lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;One of the biggest annoyances for me using LINQ today, is the fact that custom functions can’t be used inside of query expressions. This makes total sense once &lt;br /&gt;you understand how LINQ expressions work, but if it were possible, you could make big queries a lot be more maintainable.&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Take the following query using LINQ to Entities:&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Program&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;void&lt;/span&gt; Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;NorthwindEntities&lt;/span&gt; northwind = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;NorthwindEntities&lt;/span&gt;();&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; query = northwind.Products.Where(p =&amp;gt; IsCheap(p));&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt; p &lt;span style="color: blue"&gt;in&lt;/span&gt; query) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(p.ProductName);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;bool&lt;/span&gt; IsCheap(&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt; product) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; !product.Discontinued &amp;amp;&amp;amp; product.UnitsInStock &amp;lt; 10;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Anyone who has done any programming with LINQ to Entities knows that this won’t work. When we try to run this code, we get an error saying that this expression &lt;br /&gt;cannot be converted to SQL, or more precisely:&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Unhandled Exception: System.NotSupportedException: LINQ to Entities does not recognize the method 'Boolean IsCheap(Sample.Product)' method, and this method cannot be translated into a store expression&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#333333"&gt;The reason this doesn’t work is because the compiler puts the IsCheap method call in the expression tree and EF tries to convert it into SQL:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Convert(value(System.Data.Objects.ObjectSet`1[Sample.Product])).MergeAs(AppendOnly).Where(p =&amp;gt; IsCheap(p))&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#333333"&gt;What we really wanted is for the compiler to replace IsCheap with the expression in the body of IsCheap, i.e. replace IsCheap with !product.Discontinued &amp;amp;&amp;amp; product.UnitsInStock &amp;lt; 10.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;This same expression would work today with DynamicLINQ:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; DynamicLINQ;&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Program&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;void&lt;/span&gt; Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;NorthwindEntities&lt;/span&gt; northwind = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;NorthwindEntities&lt;/span&gt;();&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; query = northwind.Products.Where(p =&amp;gt; IsCheap(p));&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt; p &lt;span style="color: blue"&gt;in&lt;/span&gt; query) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(p.ProductName);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt; IsCheap(&lt;span style="color: blue"&gt;dynamic&lt;/span&gt; product) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; !product.Discontinued &amp;amp;&amp;amp; product.UnitsInStock &amp;lt; 10;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;We tweaked the method slightly, changing the argument and return type to be dynamic. When we run this code it works and we see a list of cheap products. &lt;/p&gt;

&lt;p&gt;The difference here is that we’re actually executing code to build the expression tree, so instead of putting the method call into the resultant tree we actually invoke the method and the expression tree ends up looking like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Convert(value(System.Data.Objects.ObjectSet`1[Sample.Product])).MergeAs(AppendOnly).Where(p =&amp;gt; (Not(p.Discontinued) And (Convert(p.UnitsInStock) &amp;lt; 10)))&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are also some scenarios that don’t work in the current implementation. For example, casting and some projections don’t work well with existing LINQ providers. I’ve put the code on a bitbucket repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://bitbucket.org/dfowler/dynamiclinq"&gt;http://bitbucket.org/dfowler/dynamiclinq&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7596386" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/davidfowler/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/davidfowler/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://weblogs.asp.net/davidfowler/archive/tags/Dynamic/default.aspx">Dynamic</category></item><item><title>Dynamic LINQ (A little more dynamic)</title><link>http://weblogs.asp.net/davidfowler/archive/2010/08/04/dynamic-linq-a-little-more-dynamic.aspx</link><pubDate>Wed, 04 Aug 2010 08:15:17 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7578406</guid><dc:creator>davidfowl</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=7578406</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2010/08/04/dynamic-linq-a-little-more-dynamic.aspx#comments</comments><description>&lt;p&gt;It seems I’ve become (in)&lt;a href="http://ayende.com/Blog/archive/2010/08/03/microsoft.data-because-the-90s-were-so-good-we-want-to.aspx"&gt;famous&lt;/a&gt; &lt;a href="http://ayende.com/Blog/archive/2010/08/04/microsoft.data-and-positioning.aspx"&gt;in&lt;/a&gt; &lt;a href="http://www.weirdlover.com/2010/08/03/microsoft-data-lets-inject-some-love-into-the-conversation/"&gt;the&lt;/a&gt; &lt;a href="http://h30507.www3.hp.com/t5/The-Watering-Can-of-Enterprise/IDE-Doing-Enterprise-Software-Development-Visual-Studio/ba-p/81821"&gt;last&lt;/a&gt; &lt;a href="http://blog.cincura.net/231885-microsoft-data-dll-after-crop/"&gt;two&lt;/a&gt; days. With all the buzz around Microsoft.Data, I figure I’d post on something else that is somewhat related. &lt;/p&gt;  &lt;p&gt;There were a bunch of comments on my previous posts that said we should do something to this effect:&lt;/p&gt;  &lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt; db = &lt;span style="color: #2b91af"&gt;Database&lt;/span&gt;.Open(&lt;span style="color: #a31515"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; q = &lt;span style="color: blue"&gt;from&lt;/span&gt; p &lt;span style="color: blue"&gt;in&lt;/span&gt; db.Products&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;where&lt;/span&gt; p.UnitsInStock &amp;lt; 20&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;select&lt;/span&gt; p;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Which looks like LINQ but it would be over a dynamic object. Of course you don’t get the strong typing benefits of LINQ since there are no classes, but at least the &lt;br /&gt;syntax is nice and the user is protected from SQL injection. &lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;font color="#ff0000"&gt;Disclaimer&lt;/font&gt;&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;This blog post is a technical discussion about the limitations that exist today around LINQ and dynamic and interesting ways to get around it. Nothing more. Continue reading.&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Unfortunately when we try to compile this the compiler screams:&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Query expressions over source type 'dynamic' or with a join sequence of type 'dynamic' are not allowed&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#333333"&gt;Maybe it’s better if we just use a real ORM now, or the &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx"&gt;other Dynamic LINQ library&lt;/a&gt;, but now I’m curious and want to figure out if this is even possible.&lt;/font&gt; Let’s try it another way:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt; db = &lt;span style="color: #2b91af"&gt;Database&lt;/span&gt;.Open(&lt;span style="color: #a31515"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; q = db.Products.Where(p =&amp;gt; p.UnitsInStock &amp;lt; 20);&lt;/pre&gt;

&lt;p&gt;The compiler complains again, but this time with a different error:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type &lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#333333"&gt;So we’re being blocked in two different ways. Can we work around this somehow?&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Since we can’t query over a dynamic object we’ll give the Database and the Products property static types:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Database &lt;/span&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;string&lt;/span&gt; _databaseName;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; Database(&lt;span style="color: blue"&gt;string&lt;/span&gt; databaseName) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _databaseName = databaseName;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Database&lt;/span&gt; Open(&lt;span style="color: blue"&gt;string&lt;/span&gt; name) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Database&lt;/span&gt;(name);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Query&lt;/span&gt; Products {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;get&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Query&lt;/span&gt;();&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Query&lt;/span&gt; {&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;Now we can do this:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; db = &lt;span style="color: #2b91af"&gt;Database&lt;/span&gt;.Open(&lt;span style="color: #a31515"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; q = &lt;span style="color: blue"&gt;from&lt;/span&gt; p &lt;span style="color: blue"&gt;in&lt;/span&gt; db.Products&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;where&lt;/span&gt; p.UnitsInStock &amp;lt; 20&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;select&lt;/span&gt; p;&lt;/pre&gt;

&lt;p&gt;Changing dynamic to var lets type inference take over so that db is typed as a Database instead of dynamic. Now we try to compile again:&lt;/p&gt;

&lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Could not find an implementation of the query pattern for source type 'Query'.&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#333333"&gt;This is a problem we can solve. The compiler translates code written using the query syntax:&lt;/font&gt;&lt;/p&gt;
&lt;font face="Consolas"&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; q = &lt;span style="color: blue"&gt;from&lt;/span&gt; p &lt;span style="color: blue"&gt;in&lt;/span&gt; db.Products 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;where&lt;/span&gt; p.UnitsInStock &amp;lt; 20 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;select&lt;/span&gt; p;&lt;/font&gt; 

&lt;p&gt;Into this:&lt;/p&gt;

&lt;p&gt;&lt;font face="Consolas"&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; q = db.Products.Where(p =&amp;gt; p.UnitsInStock &amp;lt; 20);&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Bart de Smet has a great explanation on how this &lt;a href="http://community.bartdesmet.net/blogs/bart/archive/2008/09/14/who-ever-said-linq-predicates-need-to-be-boolean-valued.aspx"&gt;works&lt;/a&gt;. What this means is that we can implement the Select, Where, SelectMany or any other methods on our dynamic object that will make the compiler happy.&lt;/p&gt;

&lt;p&gt;Given that, we can implement a dummy Where method to try to get this code to compile:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Query&lt;/span&gt; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt; Where(Expression&amp;lt;Func&amp;lt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt;, &lt;span style="color: blue"&gt;dynamic&lt;/span&gt;&amp;gt;&amp;gt; predicate) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Turns out that trying to compile this yields yet another error:&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font color="#ff0000" face="Trebuchet MS"&gt;&lt;strong&gt;An expression tree may not contain a dynamic operation&lt;/strong&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font color="#333333" face="Trebuchet MS"&gt;Three different compiler errors, all to do with LINQ and dynamic. Looks like the compiler team went out of their way to block this. Let’s see if removing the &lt;br /&gt;&lt;/font&gt;&lt;font color="#333333" face="Trebuchet MS"&gt;expression works:&lt;/font&gt;&lt;/pre&gt;
&lt;font face="Consolas"&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Query&lt;/span&gt; { 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt; Where(Func&amp;lt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt;, &lt;span style="color: blue"&gt;dynamic&lt;/span&gt;&amp;gt; predicate) { 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;null&lt;/span&gt;; 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } 

  &lt;br /&gt;}&lt;/font&gt; 

&lt;p&gt;Finally we’ve gotten the code to compile, now what? Well if this was LINQ to SQL/EF/SharePoint/etc., the query would be translated into an expression tree and executed on the server when we enumerated the results. I’m more interested in the first part of that, i.e. can we build an expression tree using dynamic LINQ.&lt;/p&gt;

&lt;p&gt;Normally when you declare a lambda it can act like an expression tree or a delegate:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;Func&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt;&amp;gt; expr = (a, b) =&amp;gt; a + b;&lt;br /&gt;Func&amp;lt;&lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt;&amp;gt; add = (a, b) =&amp;gt; a + b;&lt;br /&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(expr);&lt;br /&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(add);&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;The above code prints out (a, b) =&amp;gt; (a + b) and System.Func`3[System.Int32,System.Int32,System.Int32], as expected. The compiler does all the hard work of figuring &lt;br /&gt;out how to build an expression tree from the code the user writes, but we don’t have this luxury since we’re in the dynamic world.&lt;/font&gt;&lt;/pre&gt;

&lt;h2&gt;Enter Dynamic Expression&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;NOTE: If you aren’t familiar with the new dynamic in C#/VB feature, read up on it &lt;a href="http://blogs.msdn.com/b/cburrows/archive/2008/10/27/c-dynamic.aspx"&gt;here&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We introduce a new class called DynamicExpression that we will use to make the compiler do our bidding:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;DynamicObject&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;}&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Before we dig into the implementation of this class, we have to figure out what kind of expressions we are going to build. How can we represent p.UnitsInStock in an&lt;br /&gt;expression tree. Normally that would be a &lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.expressions.expression.property.aspx"&gt;PropertyExpression&lt;/a&gt; that represents the UnitsInStock property on the Product class generated by either LINQ to SQL or &lt;br /&gt;&lt;br /&gt;LINQ to Entities. We can’t do this since we don’t have any strong types.&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;For simplicity, we’re going to assume that all of the properties are integers, and that property access will be represented by a call to a Property method defined &lt;br /&gt;on DynamicExpression i.e. p.UnitsInStock will become a call to Property(“UnitsInStock”).&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Now that we have that our of the way, we can get to the implemention. Lets start with TryGetMember:&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;DynamicObject&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; DynamicExpression(&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt; expression) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GeneratedExpression = expression;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt; GeneratedExpression { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;override&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;bool&lt;/span&gt; TryGetMember(&lt;span style="color: #2b91af"&gt;GetMemberBinder&lt;/span&gt; binder, &lt;span style="color: blue"&gt;out&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;object&lt;/span&gt; result) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;MethodInfo&lt;/span&gt; propertyMethod = &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt;).GetMethod(&lt;span style="color: #a31515"&gt;&amp;quot;Property&amp;quot;&lt;/span&gt;, BindingFlags.NonPublic | BindingFlags.Static);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; expression = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Call(propertyMethod, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Constant(binder.Name));&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt;(expression);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;true&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;int&lt;/span&gt; Property(&lt;span style="color: blue"&gt;string&lt;/span&gt; propertyName) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; 0;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;We’re storing the generated expression in a property so we can grab it after doing a bunch of manipulation. The Property method doesn’t actually have to do anything since &lt;br /&gt;its sole purpose is to represent property access.&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Next we move on to simple binary expressions:&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;override&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;bool&lt;/span&gt; TryBinaryOperation(&lt;span style="color: #2b91af"&gt;BinaryOperationBinder&lt;/span&gt; binder, &lt;span style="color: blue"&gt;object&lt;/span&gt; arg, &lt;span style="color: blue"&gt;out&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;object&lt;/span&gt; result) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt; dynamicExpression = arg &lt;span style="color: blue"&gt;as&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt; rhs = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (dynamicExpression != &lt;span style="color: blue"&gt;null&lt;/span&gt;) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; rhs = dynamicExpression.GeneratedExpression;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;else&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; rhs = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Constant(arg);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; expression = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.MakeBinary(binder.Operation, GeneratedExpression, rhs);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; result = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt;(expression);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;true&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;First we are checking to see if the right hand side of the expression is itself a DynamicExpression and unwrapping the underlying expression if that is the case. Otherwise it&lt;br /&gt;takes the right hand side to be a constant.&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Some people may have already put the big picture together, if you haven’t as yet don’t worry, it isn’t exactly obvious how this works. We are trying to create an expression&lt;br /&gt;tree using dynamic dispatch, that is, using the execution of the dynamic operations to build an expression tree.&lt;/font&gt;&lt;font face="Trebuchet MS"&gt;&lt;br /&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;h2&gt;&lt;font face="Trebuchet MS"&gt;Putting the pieces together&lt;/font&gt;&lt;/h2&gt;

&lt;p&gt;Remember how the compiler complained earlier when we tried to use dynamic in an expression tree? That’s why our overload of Where doesn’t take a Expression&amp;lt;Func&amp;lt;dynamic, dynamic&amp;gt;&amp;gt; but instead it takes a Func&amp;lt;dynamic, dynamic&amp;gt;. We’re going to fill in that blank implementation of the Where method we left off earlier. &lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Query&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; Query(&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt; expression) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GeneratedExpression = expression;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt; GeneratedExpression { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Query&lt;/span&gt; Where(Func&amp;lt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt;, &lt;span style="color: blue"&gt;dynamic&lt;/span&gt;&amp;gt; predicate) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt; expr = predicate(&lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt;(GeneratedExpression));&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Query&lt;/span&gt;(expr.GeneratedExpression);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Let’s we go back to the original query:&lt;/font&gt;&lt;/pre&gt;
&lt;font face="Consolas"&gt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt; db = &lt;span style="color: #2b91af"&gt;Database&lt;/span&gt;.Open(&lt;span style="color: #a31515"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;); 

  &lt;br /&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; q = &lt;span style="color: blue"&gt;from&lt;/span&gt; p &lt;span style="color: blue"&gt;in&lt;/span&gt; db.Products 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;where&lt;/span&gt; p.UnitsInStock &amp;lt; 20 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;select&lt;/span&gt; p;&lt;/font&gt; 

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;The compiler is going to turn this into a call to db.Products.Where(p =&amp;gt; p.UnitsInStock &amp;lt; 20). When this calls our implementation of Where, we construct a DynamicExpression &lt;br /&gt;and execute the lambda (p.UnitsInStock &amp;lt; 20) on it. While executing the lambda, the compiler sees a member access(p.UnitsInStock) on a dynamic object p and calls our &lt;br /&gt;implementation of TryGetMember. Instead of TryGetMember returning a value for p.UnitsInStock, it returns an &lt;strong&gt;Expression &lt;/strong&gt;that represents a member access and wraps &lt;br /&gt;it in another DynamicExpression so that the process continues. The compiler then sees the less than operator and calls our implementation of TryBinaryOperation. We use the &lt;br /&gt;&lt;/font&gt;&lt;font face="Trebuchet MS"&gt;same trick for this as we did for member access (return an expression instead of a value). This could be done for all of the operators but I chose to two for brevity.&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Now that we’ve done this, we can print out the generated expression. Here is the full program:&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Dynamic;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Linq.Expressions;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Reflection;&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Program&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;void&lt;/span&gt; Main(&lt;span style="color: blue"&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; db = &lt;span style="color: #2b91af"&gt;Database&lt;/span&gt;.Open(&lt;span style="color: #a31515"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; q = &lt;span style="color: blue"&gt;from&lt;/span&gt; p &lt;span style="color: blue"&gt;in&lt;/span&gt; db.Products&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;where&lt;/span&gt; p.UnitsInStock &amp;lt; p.Price + 1&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;select&lt;/span&gt; p;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(q.GeneratedExpression);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Database&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;string&lt;/span&gt; _databaseName;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; Database(&lt;span style="color: blue"&gt;string&lt;/span&gt; databaseName) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _databaseName = databaseName;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Database&lt;/span&gt; Open(&lt;span style="color: blue"&gt;string&lt;/span&gt; name) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Database&lt;/span&gt;(name);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Query&lt;/span&gt; Products {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;get&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Query&lt;/span&gt;(&lt;span style="color: blue"&gt;null&lt;/span&gt;);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Query&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; Query(&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt; expression) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GeneratedExpression = expression;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt; GeneratedExpression { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Query&lt;/span&gt; Where(Func&amp;lt;&lt;span style="color: blue"&gt;dynamic&lt;/span&gt;, &lt;span style="color: blue"&gt;dynamic&lt;/span&gt;&amp;gt; predicate) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt; expr = predicate(&lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt;(GeneratedExpression));&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Query&lt;/span&gt;(expr.GeneratedExpression);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;DynamicObject&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; DynamicExpression(&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt; expression) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; GeneratedExpression = expression;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt; GeneratedExpression { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;override&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;bool&lt;/span&gt; TryGetMember(&lt;span style="color: #2b91af"&gt;GetMemberBinder&lt;/span&gt; binder, &lt;span style="color: blue"&gt;out&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;object&lt;/span&gt; result) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;MethodInfo&lt;/span&gt; propertyMethod = &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt;).GetMethod(&lt;span style="color: #a31515"&gt;&amp;quot;Property&amp;quot;&lt;/span&gt;, BindingFlags.NonPublic | BindingFlags.Static);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; expression = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Call(propertyMethod, &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Constant(binder.Name));&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt;(expression);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;true&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;override&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;bool&lt;/span&gt; TryBinaryOperation(&lt;span style="color: #2b91af"&gt;BinaryOperationBinder&lt;/span&gt; binder, &lt;span style="color: blue"&gt;object&lt;/span&gt; arg, &lt;span style="color: blue"&gt;out&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;object&lt;/span&gt; result) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt; dynamicExpression = arg &lt;span style="color: blue"&gt;as&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt; rhs = &lt;span style="color: blue"&gt;null&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (dynamicExpression != &lt;span style="color: blue"&gt;null&lt;/span&gt;) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; rhs = dynamicExpression.GeneratedExpression;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;else&lt;/span&gt; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; rhs = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Constant(arg);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; expression = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.MakeBinary(binder.Operation, GeneratedExpression, rhs);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DynamicExpression&lt;/span&gt;(expression);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;true&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;override&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;bool&lt;/span&gt; TryUnaryOperation(&lt;span style="color: #2b91af"&gt;UnaryOperationBinder&lt;/span&gt; binder, &lt;span style="color: blue"&gt;out&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;object&lt;/span&gt; result) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (binder.Operation == ExpressionType.IsFalse || binder.Operation == ExpressionType.IsTrue) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; result = &lt;span style="color: blue"&gt;false&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;true&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;base&lt;/span&gt;.TryUnaryOperation(binder, &lt;span style="color: blue"&gt;out&lt;/span&gt; result);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;static&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;int&lt;/span&gt; Property(&lt;span style="color: blue"&gt;string&lt;/span&gt; propertyName) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; 0;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/pre&gt;

&lt;h2&gt;Caveats&lt;/h2&gt;

&lt;p&gt;So we were able to get some expression tree support while combining LINQ and dynamic, but there are things to be aware of.&lt;/p&gt;

&lt;p&gt;If the lhs of any operation isn’t dynamic then our TryBinaryOperation will never get called:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; q = &lt;span style="color: blue"&gt;from&lt;/span&gt; p &lt;span style="color: blue"&gt;in&lt;/span&gt; db.Products&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;where&lt;/span&gt; 1 &amp;gt; p.UnitsInStock&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;select&lt;/span&gt; p;&lt;/pre&gt;

&lt;p&gt;This would fail since 1 isn’t a dynamic object, we need something to bootstrap the dynamic dispatch.&amp;#160; Exercise for the reader, can we get around this limitation? 
  &lt;br /&gt;

  &lt;br /&gt;Nested queries won’t work without casting:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; q = &lt;span style="color: blue"&gt;from&lt;/span&gt; c &lt;span style="color: blue"&gt;in&lt;/span&gt; db.Categories&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;from&lt;/span&gt; p &lt;span style="color: blue"&gt;in&lt;/span&gt; c.Products&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;where&lt;/span&gt; p.UnitsInStock &amp;lt; 20&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;select&lt;/span&gt; p;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;This doesn’t work right now because we didn’t implement SelectMany, but also because of the first compiler error we encountered (Query expressions over source &lt;br /&gt;&lt;/font&gt;&lt;font face="Trebuchet MS"&gt;type 'dynamic' are not allowed). The nested query (from p in c.Products) would be trying to query over a dynamic source.&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Query syntax doesn’t work in VB. VB does semantic translation instead of syntactic translation:&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;Dim&lt;/span&gt; q = &lt;span style="color: blue"&gt;From&lt;/span&gt; p &lt;span style="color: blue"&gt;In&lt;/span&gt; db.Products&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;Where&lt;/span&gt; p.UnitsInStock &amp;lt; 20&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;Select&lt;/span&gt; p&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;When the VB compiler generates the method for p.UnitsInStock &amp;lt; 20, it injects a type check for a boolean result which completely breaks this approach. &lt;br /&gt;&lt;/font&gt;&lt;font face="Trebuchet MS"&gt;You can however still use the lambda syntax to work around this.&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;There are probably other quirks that come with using this approach, and it is clear that the C# team took time to block certain scenarios, so don’t expect this to &lt;br /&gt;be a 100% solution.&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;We’ve successfully abused the new dynamic feature to get it working with LINQ. Hopefully in some future version of C# and VB we get deeper integration with &lt;br /&gt;LINQ and dynamic.&lt;/font&gt;&lt;/pre&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7578406" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/davidfowler/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/davidfowler/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://weblogs.asp.net/davidfowler/archive/tags/Dynamic/default.aspx">Dynamic</category></item><item><title>Microsoft.Data.dll - A re-introduction</title><link>http://weblogs.asp.net/davidfowler/archive/2010/08/03/microsoft-data-dll-a-re-introduction.aspx</link><pubDate>Tue, 03 Aug 2010 16:27:45 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7578105</guid><dc:creator>davidfowl</dc:creator><slash:comments>30</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=7578105</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2010/08/03/microsoft-data-dll-a-re-introduction.aspx#comments</comments><description>&lt;p&gt;Before we look at the reasons for the existence of Microsoft.Data, we need some background on the WebMatrix initiative. Here are some excellent blog posts that describe the type of audience we are going after and the goals of the project:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2010/07/06/introducing-webmatrix.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2010/07/06/introducing-webmatrix.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/b/davidebb/archive/2010/07/07/how-webmatrix-razor-asp-net-web-pages-and-mvc-fit-together.aspx"&gt;http://blogs.msdn.com/b/davidebb/archive/2010/07/07/how-webmatrix-razor-asp-net-web-pages-and-mvc-fit-together.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/mbcrump/archive/2010/07/06/the-forrest-gump-guide-to-the-new-webmatrix.aspx"&gt;http://geekswithblogs.net/mbcrump/archive/2010/07/06/the-forrest-gump-guide-to-the-new-webmatrix.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;These blog posts point out that WebMatrix targets a different audience than our traditional pro developer audience. These are people who are not yet developers (if they ever plan to be). They may never want to become a pro developer, but want to be able to put together a simple website. If you've internalized best practices and patterns and know your way around an ORM, then you will most likely never use this library. We are trying to attract a different kind of customer: people who are on other platforms and are already using SQL today in their web pages, and people that are trying to get into programming and haven’t chosen a platform as yet. &lt;/p&gt;  &lt;p&gt;Most likely, if you're even reading this, you're not the intended audience, though we are still interested in your feedback.&lt;/p&gt;  &lt;h2&gt;Why Microsoft Data?&lt;/h2&gt;  &lt;p&gt;Scott Gu quote:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font style="background-color: #ffff00"&gt;&lt;/font&gt;&lt;em&gt;We've debated the role of ORMs for entry-level devs quite a bit (and have a dynamic ORM implemented - but which we didn't ship with today's preview).&amp;#160; For someone who understand objects and classes they can be great. When we brought in web developers to use the product for a few days, though, one interesting data point that came up repeatedly was that about 80% of them had never even heard the term &amp;quot;ORM&amp;quot;.&amp;#160; We found it took awhile for them to conceptually grok it - whereas adhoc SQL came much easier to them. It is something we are going to continue to work on finding the right balance on.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I could not put this any better. We didn’t immediately decide to go with SQL, but after going through several options, we decided it was the simplest way to go. &lt;/p&gt;  &lt;p&gt;Absolute beginners won’t have Visual Studio, and most of our existing data stack relies heavily on tooling support (designers, and code generators). We wanted to build something that felt like it could be authored from notepad. &lt;/p&gt;  &lt;h2&gt;Who Is it For?&lt;/h2&gt;  &lt;p&gt;Nikhil has a good blog post on personas &lt;a href="http://www.nikhilk.net/Personas.aspx"&gt;http://www.nikhilk.net/Personas.aspx&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Mort, the opportunistic developer, likes to create quick-working solutions for immediate problems and focuses on productivity and learn as needed. Elvis, the pragmatic programmer, likes to create long-lasting solutions addressing the problem domain, and learn while working on the solution. Einstein, the paranoid programmer, likes to create the most efficient solution to a given problem, and typically learn in advance before working on the solution.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;WebMatrix is trying to target beginners (like Mort, or pre-Mort). By beginners I mean, people that:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;May not understand generics (or don’t care for them) &lt;/li&gt;    &lt;li&gt;Do not care about TDD, DRY, SRP, (insert acronym here) &lt;/li&gt;    &lt;li&gt;Do not understand lambdas or expression trees. &lt;/li&gt;    &lt;li&gt;May not have any knowledge of OOP &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I could go on and on, but the point I am trying to get across is that if any of this sounds absurd to you or if it offends you in any way as a developer, then you are probably not the target audience.&lt;/p&gt;  &lt;p&gt;This post can be summarized by the following quote from Scott Gu’s blog:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;If you are a professional developer who uses VS today then WebMatrix is not really aimed at you - at least not for your &amp;quot;day job&amp;quot;.&amp;#160; You might find WebMatrix useful for quickly putting a blog on the web or doing lightweight scripting on the side.&amp;#160; But it isn't intended or focused on hard-core professional or enterprise development.&amp;#160; It is instead aimed more for people looking to learn how to program and/or who want to get a site up and running on the web without having to write much code.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7578105" width="1" height="1"&gt;</description></item><item><title>Introduction to Microsoft.Data.dll</title><link>http://weblogs.asp.net/davidfowler/archive/2010/08/02/introduction-to-microsoft-data-dll.aspx</link><pubDate>Mon, 02 Aug 2010 16:18:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7577137</guid><dc:creator>davidfowl</dc:creator><slash:comments>106</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=7577137</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2010/08/02/introduction-to-microsoft-data-dll.aspx#comments</comments><description>&lt;h2&gt;&lt;font color="#ff0000"&gt;UPDATE!&lt;/font&gt;&lt;/h2&gt;  &lt;p&gt;&lt;font color="#ff0000" size="2"&gt;Before you continue reading this blog post, check out the &lt;/font&gt;&lt;a href="http://weblogs.asp.net/davidfowler/archive/2010/08/03/microsoft-data-dll-a-re-introduction.aspx"&gt;&lt;font color="#ff0000" size="2"&gt;prequel&lt;/font&gt;&lt;/a&gt;&lt;font color="#ff0000" size="2"&gt;.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I’ve been pretty busy recently working on cool features for “ASP.NET WebPages with Razor Syntax” (what a mouth full) and other things. I’ve worked on tons of stuff that I wish I could share with you, but what I can share is something that many people haven’t blogged about - Microsoft.Data.dll.&lt;/p&gt;  &lt;h2&gt;What is Microsoft.Data&lt;/h2&gt;  &lt;p&gt;It’s an awesome new assembly/namespace that contains everything you’ll ever need to access a database. In ASP.NET WebPages we wanted people to be able to access the database without having to write too many lines of code. Any developer that has used raw ADO.NET knows this pain:&lt;/p&gt;  &lt;pre style="font-family: consolas"&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: blue"&gt;var&lt;/span&gt; connection = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;SqlConnection&lt;/span&gt;(&lt;/font&gt;&lt;span style="color: #a31515"&gt;&lt;font size="2"&gt;@&amp;quot;Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|&lt;/font&gt;&lt;/span&gt;&lt;font size="2"&gt;&lt;span style="color: #a31515"&gt;\Northwind.mdf;&lt;br /&gt;                                           &lt;/span&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: #a31515"&gt;Initial Catalog=|DataDirectory|\Northwind.mdf;Integrated Security=True;User Instance=True&amp;quot;&lt;/span&gt;)) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: blue"&gt;var&lt;/span&gt; command = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;SqlCommand&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;select * from products where UnitsInStock &amp;lt; 20&amp;quot;&lt;/span&gt;, connection)) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; connection.Open();&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;SqlDataReader&lt;/span&gt; reader = command.ExecuteReader()) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;while&lt;/span&gt; (reader.Read()) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Response.Write(reader[&lt;span style="color: #a31515"&gt;&amp;quot;ProductName&amp;quot;&lt;/span&gt;] + &lt;span style="color: #a31515"&gt;&amp;quot; &amp;quot;&lt;/span&gt; + reader[&lt;span style="color: #a31515"&gt;&amp;quot;UnitsInStock&amp;quot;&lt;/span&gt;]);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Wow, that’s a lot of code compared to:&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font size="2"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: blue"&gt;var&lt;/span&gt; db = Database.OpenFile(&lt;span style="color: #a31515"&gt;&amp;quot;Northwind&amp;quot;&lt;/span&gt;)) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue"&gt;var&lt;/span&gt; product &lt;span style="color: blue"&gt;in&lt;/span&gt; db.Query(&lt;span style="color: #a31515"&gt;&amp;quot;select * from products where UnitsInStock &amp;lt; @0&amp;quot;&lt;font color="#333333"&gt;, 20&lt;/font&gt;&lt;/span&gt;)) {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Response.Write(product.ProductName + &lt;span style="color: #a31515"&gt;&amp;quot; &amp;quot;&lt;/span&gt; + product.UnitsInStock);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;The user doesn’t have to learn about connection strings or how to create a command with a connection and then use a reader to get the results. Also, the above code is tied to Sql Server since we’re using specific implementations of the connection, command, and reader(SqlConnection, SqlCommand, SqlDataReader). &lt;/p&gt;

&lt;p&gt;Compare this with code below it. We’ve reduced the amount of lines required to connect to the database, and the syntax for accessing columns is also a lot nicer, that’s because we’re taking advantage of C#’s new &lt;a href="http://msdn.microsoft.com/en-us/library/dd264736.aspx"&gt;dynamic&lt;/a&gt; feature.&lt;/p&gt;

&lt;p&gt;Why is it so much easier you ask? Well, the &lt;strong&gt;Database&lt;/strong&gt; class is what you’ll be working with when accessing data. There are several methods that let you perform different kinds of queries and factory methods for connecting to the database.&lt;/p&gt;

&lt;h2&gt;Connecting to the Database&lt;/h2&gt;

&lt;p&gt;Sql Compact 4 is our main story when developing locally with web matrix, so we optimized for the “I have a database file under App_Data in my web site and I want to access it” case. The first overload we’re going to look at does exactly that and is named appropriately, Database.OpenFile.&lt;/p&gt;

&lt;p&gt;Database.OpenFile takes either a full path or a relative path, and uses a &lt;strong&gt;default connection string &lt;/strong&gt;based on the file extension in order to connect to a database. To see this in action, run the starter site template in &lt;a href="http://www.microsoft.com/web/webmatrix/"&gt;webmatrix&lt;/a&gt; and add this code to the &lt;strong&gt;Default.cshtml:&lt;/strong&gt;&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; db = Database.OpenFile(&lt;span style="color: #a31515"&gt;&amp;quot;StarterSite.sdf&amp;quot;&lt;/span&gt;);&lt;br /&gt;@ObjectInfo.Print(db.Connection)&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;The first line will create a database object with a connection pointing to the sdf file under App_Data. The second line is taking advantage of our &lt;/font&gt;&lt;font face="Trebuchet MS"&gt;ObjectInfo helper &lt;br /&gt;&lt;/font&gt;&lt;font face="Trebuchet MS"&gt;(more on this later) to show the properties of the database object. &lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;a href="http://weblogs.asp.net/blogs/davidfowler/WindowsLiveWriter/MoreDataWebMatrixStyle_21D9/sqlconnection_6.png"&gt;&lt;img style="border-right-width: 0px; margin: 10px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="sqlconnection" border="0" alt="sqlconnection" src="http://weblogs.asp.net/blogs/davidfowler/WindowsLiveWriter/MoreDataWebMatrixStyle_21D9/sqlconnection_thumb_2.png" width="1024" height="229" /&gt;&lt;/a&gt;&lt;/pre&gt;

&lt;p&gt;Looking at the properties you can see that the connection state is closed, pretty weird for a method called Open to return a closed connection no? The reason is we want to delay the work as long as possible(we don’t even create the connection up front) i.e. until we actually decide to do a query.&lt;/p&gt;

&lt;p&gt;If you look at the &lt;strong&gt;ConnectionString&lt;/strong&gt; property you’ll see |DataDirectory|\StarterSite.sdf, this is one of the default connection strings I mentioned earlier. We assume relative path means within the |DataDirectory| which is “App_Data” in this case. &lt;/p&gt;

&lt;p&gt;For simple cases OpenFile works. One of the big downsides is the fact that you are essentially hardcoding that you are using a database file, which will make it harder to migrate to sql server in the future. We have a solution for this that I’ll talk about below.&lt;/p&gt;

&lt;p&gt;For those developers that understand connection strings and need a litte more control, then Database.OpenConnectionString might be for you. This API does exactly what you think it does, create a database object with a connection that uses the connection string specified.&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; db = Database.OpenConnectionString(&lt;span style="color: #a31515"&gt;@&amp;quot;Data Source=.\SQLEXPRESS;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AttachDbFilename=|DataDirectory|\Northwind.mdf;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Integrated Security=True;User Instance=True&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;This is nice for more control but, connection strings are things that normally are stored in a web.config so it can be changed without recompiling the application.&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Last but not least is the most magical (and controversial) solution. We went back and forth about this one but put it in the beta in order to get some&lt;/font&gt;&lt;font face="Trebuchet MS"&gt; feedback. &lt;br /&gt;&lt;/font&gt;&lt;font face="Trebuchet MS"&gt;&lt;strong&gt;Database.Open&lt;/strong&gt; allows the user to specify a named connection, which can be one of 3 things (this is where the magic comes in):&lt;/font&gt;&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;A database file under the data directory (App_Data) that matches the name plus one of our supported extensions (.sdf or .mdf)&lt;/font&gt;&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;A connection registered with and Database.RegisterConnectionString, Database.RegisterFile APIs&lt;/font&gt;&lt;/pre&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;A connection string from web.config&lt;/font&gt;&lt;/pre&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;We had lots of debate (still ongoing) internally about what the fall back order should be and if there should even be a fallback order. Today, we look for a &lt;br /&gt;&lt;/font&gt;&lt;font face="Trebuchet MS"&gt;connection in all the mentioned places and throw an exception if it is ambiguous (i.e. more than one) to prevent confusion. Database.Open is what we recommend since &lt;br /&gt;it allows &lt;/font&gt;&lt;font face="Trebuchet MS"&gt;the user to change what connection a name maps to, making a simple migration from Sql Compact 4 to Sql Server possible without any code change.&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;With this in mind here are some examples on how you can use Database.Open:&lt;/font&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: green"&gt;&lt;strong&gt;&lt;font color="#000000" face="Trebuchet MS"&gt;&lt;u&gt;File based&lt;/u&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: green"&gt;&lt;/span&gt;&lt;span style="color: green"&gt;// (Assume you have Northwind.mdf in the database)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Database.Open(&lt;span style="color: #a31515"&gt;&amp;quot;Northwind&amp;quot;&lt;/span&gt;) &lt;/pre&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;Register API 
      &lt;br /&gt;&lt;/strong&gt;&lt;/u&gt;&lt;span style="color: green"&gt;
    &lt;br /&gt;// _start.cshtml&lt;/span&gt; 

  &lt;br /&gt;Database.RegisterConnectionString(&lt;span style="color: #a31515"&gt;&amp;quot;MyDatabaseServer&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;Data Source=192.168.1.20;Initial Catalog=MyDb&amp;quot;&lt;/span&gt;)&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;&lt;font color="#333333"&gt;&lt;span style="color: green"&gt;// SomeFile.cshtml&lt;/span&gt;&lt;/font&gt; 

  &lt;br /&gt;Database.Open(&lt;span style="color: #a31515"&gt;&amp;quot;MyDatabaseServer&amp;quot;&lt;/span&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Configuration&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="color: green"&gt;// web.config&lt;/span&gt;&lt;span style="color: blue"&gt; 
    &lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt; 

  &lt;br /&gt;&lt;span style="color: blue"&gt;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;connectionStrings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt; 

  &lt;br /&gt;&lt;span style="color: blue"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;#160;&lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Northwind2&lt;/span&gt;&amp;quot; 

  &lt;br /&gt;&lt;span style="color: blue"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: red"&gt;connectionString&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Data Source=.\SQLEXPRESS;Integrated Security = true;Initial Catalog=Northwind&lt;/span&gt;&amp;quot; 

  &lt;br /&gt;&lt;span style="color: blue"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: red"&gt;providerName&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;System.Data.SqlClient&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt; 

  &lt;br /&gt;&lt;span style="color: blue"&gt;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;connectionStrings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt; 

  &lt;br /&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;Database.Open(&lt;span style="color: #a31515"&gt;&amp;quot;Northwind2&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

&lt;p&gt;I mentioned that the code in the very first example was tied to SqlServer. We internally use &lt;a href="http://msdn.microsoft.com/en-us/library/a6cd7c08.aspx"&gt;ADO.NET’s data providers&lt;/a&gt; to construct connections, so Microsoft.Data will mostly work with any database has a registered ADO.NET provider.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;&lt;u&gt;Caveats&lt;/u&gt;&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Since we optimized for what we thought would be the most common scenario we set up some default values and behaviors that may be hard to debug. 
  &lt;br /&gt;One of these is the fact that the default ADO.NET provider is Sql Compact 4. To work around these limitations we added a providerName paramter to methods like OpenConnectionString and RegisterConnectionString. We also recommend that you specify the providerName attribute when defining connection strings in web.config. Following those patterns will mitigate most of the issues.&lt;/p&gt;

&lt;p&gt;We also provide a global override so you can change what the default provider is. For example, if you wanted to make the default provider Sql Server then you can do it by adding the following piece of configuration to your website:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;#160; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue"&gt;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;appSettings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;#160;&lt;/span&gt;&lt;span style="color: red"&gt;key&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;systemData:defaultProvider&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;#160;&lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;System.Data.SqlClient&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue"&gt;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;appSettings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="font-family: consolas"&gt;&lt;font face="Trebuchet MS"&gt;Today I covered connecting to the database, next time I’ll concentrate on querying. Stay tuned…&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7577137" width="1" height="1"&gt;</description></item><item><title>Hacking the ASP.NET Parser</title><link>http://weblogs.asp.net/davidfowler/archive/2009/12/01/hacking-the-asp-net-parser.aspx</link><pubDate>Tue, 01 Dec 2009 09:09:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7267711</guid><dc:creator>davidfowl</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=7267711</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2009/12/01/hacking-the-asp-net-parser.aspx#comments</comments><description>&lt;P&gt;A while ago I &lt;A href="http://weblogs.asp.net/davidfowler/archive/2009/03/16/external-itemplates-and-hierarchical-databinding.aspx" mce_href="http://weblogs.asp.net/davidfowler/archive/2009/03/16/external-itemplates-and-hierarchical-databinding.aspx"&gt;blogged&lt;/A&gt; about using external templates in an asp.net application. The problem with that was it wasn’t natively supported, so I had to create a derived &lt;STRONG&gt;SpecialRepeater&lt;/STRONG&gt; in order to take advantage of the external template system. &lt;/P&gt;
&lt;P&gt;In this latest parser hack I’ve managed to “trick” the asp.net parser into letting me declaratively set any template property to be a virtual path in order to load a user control into that template at runtime.&lt;/P&gt;
&lt;H2&gt;How it works&lt;/H2&gt;
&lt;P&gt;The ASP.NET compliation system is pretty complex. There are all kinds of extensibility points, including BuildProviders, PageParserFilters, ControlBuilders, ExpressionBuilders and the list goes on. One unknown *feature* of the parser is it’s ability to generate code from something called an &lt;A href="http://msdn.microsoft.com/en-us/library/system.componentmodel.design.serialization.instancedescriptor.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.design.serialization.instancedescriptor.aspx"&gt;InstanceDescriptor&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;The parser has a special way of dealing with ITemplate properties so if we try to do this:&lt;/P&gt;
&lt;P&gt;&lt;REPEATER itemtemplate="~/MyUserControl.ascx" runat="server"&gt;&lt;/REPEATER&gt;&lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:267a7f44-a825-4716-aeab-5e038dafffde class=wlWriterEditableSmartContent&gt;
&lt;DIV style="BORDER-BOTTOM: #000080 1px solid; BORDER-LEFT: #000080 1px solid; FONT-FAMILY: 'Consolas', Courier, Monospace; COLOR: #000; FONT-SIZE: 10pt; BORDER-TOP: #000080 1px solid; BORDER-RIGHT: #000080 1px solid"&gt;
&lt;DIV style="PADDING-BOTTOM: 2px; BACKGROUND-COLOR: #3f3f3f; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; WHITE-SPACE: nowrap; OVERFLOW: auto; PADDING-TOP: 2px"&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;asp:Repeater&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;ID=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #8f9d6a"&gt;"repeater"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;runat=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #8f9d6a"&gt;"server"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;ItemTemplate=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #8f9d6a"&gt;"~/MyUserControl.ascx"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;asp:Repeater&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;It fails because the there is no way to convert the string “~/MyUserControl.ascx” into an ITemplate. &lt;/P&gt;
&lt;P&gt;The parser uses the TypeConverter attribute defined on properties it parses to aid in the conversion.&amp;nbsp; Enter &lt;A href="http://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptionprovider.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptionprovider.aspx"&gt;TypeDescriptionProvider&lt;/A&gt;&lt;STRONG&gt;&lt;/STRONG&gt;. These complex beasts are used at the heart of all designers in Visual Studio. There are used for things like populating the property grid, and adding and removing properties dynamically, basically a general purpose metadata API (think of it as an abstraction on top of reflection).&lt;/P&gt;
&lt;H3&gt;&lt;/H3&gt;
&lt;H3&gt;&lt;U&gt;VirtualPathTemplate&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;The code we are going to generate will instantiate a VirtualPathTemplate with a virtual path pointing to a user control on our site. Normally when you define a template in markup, a special type called CompiledTemplateBuilder (which points to a delegate that builds the template at runtime) is assigned to it. We want to replace a line of code that looks like this:&lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:154e5123-95d1-4837-ace3-7e52040d0032 class=wlWriterEditableSmartContent&gt;
&lt;DIV style="BORDER-BOTTOM: #000080 1px solid; BORDER-LEFT: #000080 1px solid; FONT-FAMILY: 'Consolas', Courier, Monospace; COLOR: #000; FONT-SIZE: 10pt; BORDER-TOP: #000080 1px solid; BORDER-RIGHT: #000080 1px solid"&gt;
&lt;DIV style="PADDING-BOTTOM: 2px; BACKGROUND-COLOR: #3f3f3f; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; WHITE-SPACE: nowrap; OVERFLOW: auto; PADDING-TOP: 2px"&gt;&lt;SPAN style="COLOR: #ffffff"&gt;repeater.ItemTemplate = &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;new&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;CompiledTemplateBuilder&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;(BuildTemplate);&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;to this&lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:081a51c8-75e5-4dbc-a287-7bc9d554e8a7 class=wlWriterEditableSmartContent&gt;
&lt;DIV style="BORDER-BOTTOM: #000080 1px solid; BORDER-LEFT: #000080 1px solid; FONT-FAMILY: 'Consolas', Courier, Monospace; COLOR: #000; FONT-SIZE: 10pt; BORDER-TOP: #000080 1px solid; BORDER-RIGHT: #000080 1px solid"&gt;
&lt;DIV style="PADDING-BOTTOM: 2px; BACKGROUND-COLOR: #3f3f3f; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; WHITE-SPACE: nowrap; OVERFLOW: auto; PADDING-TOP: 2px"&gt;&lt;SPAN style="COLOR: #ffffff"&gt;repeater.ItemTemplate = &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;new&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;VirtualPathTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #8f9d6a"&gt;"~/MyUserControl.ascx"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;);&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;H3&gt;&lt;U&gt;TypeDescriptionProvider&lt;/U&gt;&lt;/H3&gt;
&lt;H3&gt;&lt;/H3&gt;
&lt;P&gt;After overriding about 4 classes (TypeDescriptionProvider, CustomTypeDescriptor, PropertyDescriptor, and finally TypeConverter) we are able to control what happens when the parser asks, “can we convert “~/MyUserControl.ascx” to an ITemplate?”.&lt;/P&gt;
&lt;P&gt;Here is the code for the TemplateTypeConverter:&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:bdf087b9-030f-4063-b36e-a213799579a8 class=wlWriterEditableSmartContent&gt;
&lt;DIV style="BORDER-BOTTOM: #000080 1px solid; BORDER-LEFT: #000080 1px solid; FONT-FAMILY: 'Consolas', Courier, Monospace; COLOR: #000; FONT-SIZE: 10pt; BORDER-TOP: #000080 1px solid; BORDER-RIGHT: #000080 1px solid"&gt;
&lt;DIV style="PADDING-BOTTOM: 2px; BACKGROUND-COLOR: #3f3f3f; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; WHITE-SPACE: nowrap; OVERFLOW: auto; PADDING-TOP: 2px"&gt;&lt;SPAN style="COLOR: #cda869"&gt;public&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;override&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;bool&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; CanConvertTo(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;ITypeDescriptorContext&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; context, &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;Type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; destinationType) {&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f5a60"&gt;// Allow InstanceDescriptor so that the code gen engine can use it to generate the correct&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f5a60"&gt;// code for the ITemplate property&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;return&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; destinationType == &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;typeof&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;InstanceDescriptor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;) || _converter.CanConvertTo(context, destinationType);&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;}&lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #cda869"&gt;public&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;override&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;object&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; ConvertTo(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;ITypeDescriptorContext&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; context, &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;CultureInfo&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; culture, &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;object&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; value, &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;Type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; destinationType) {&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;var&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; descriptorProvider = value &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;as&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;IInstanceDescriptorProvider&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; (descriptorProvider != &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;null&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;) {&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;return&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; descriptorProvider.Descriptor;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;return&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; _converter.ConvertTo(context, culture, value, destinationType);&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;}&lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #cda869"&gt;public&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;override&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;bool&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; CanConvertFrom(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;ITypeDescriptorContext&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; context, &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;Type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; sourceType) {&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;return&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; sourceType == &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;typeof&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;) || _converter.CanConvertFrom(context, sourceType);&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;}&lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #cda869"&gt;public&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;override&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;object&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; ConvertFrom(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;ITypeDescriptorContext&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; context, &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;CultureInfo&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; culture, &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;object&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; value) {&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; stringValue = value &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;as&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; (stringValue != &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;null&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;) {&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; (stringValue.StartsWith(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #8f9d6a"&gt;"~/"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&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&gt;&lt;SPAN style="COLOR: #5f5a60"&gt;// Assume this is a virtual path and return the instance description provider&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&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&gt;&lt;SPAN style="COLOR: #5f5a60"&gt;// for it&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&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&gt;&lt;SPAN style="COLOR: #cda869"&gt;return&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;new&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;VirtualPathInstanceDescriptorProvider&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;(stringValue);&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&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;&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&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;return&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; _converter.ConvertFrom(context, culture, value);&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;}&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;First the parser asks the converter if it can convert from a string so we always say yes. In ConvertFrom we try to convert the value to a string and check if the path starts with “~/” in order to determine if it’s a virtual path. If it is a virtual path we return an object that knows how to get an InstanceDescriptor from the virtual path (VirtualPathInstanceDescriptorProvider). Now we have successfully parsed the control. &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Next the code generator tries to generate code for the ITemplate property. The code generator will eventually ask if it can convert the object we returned earlier (VirtualPathInstanceDescriptorProvider) to an InstanceDescriptor. The implementation of VirtualPathInstanceDescriptorProvider returns an instance descriptor that wraps a constructor info for a custom template we are going to use:&lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a31ebd23-478c-49f1-aca8-7a8b36e878a5 class=wlWriterEditableSmartContent&gt;
&lt;DIV style="BORDER-BOTTOM: #000080 1px solid; BORDER-LEFT: #000080 1px solid; FONT-FAMILY: 'Consolas', Courier, Monospace; COLOR: #000; FONT-SIZE: 10pt; BORDER-TOP: #000080 1px solid; BORDER-RIGHT: #000080 1px solid"&gt;
&lt;DIV style="PADDING-BOTTOM: 2px; BACKGROUND-COLOR: #3f3f3f; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; WHITE-SPACE: nowrap; OVERFLOW: auto; PADDING-TOP: 2px"&gt;&lt;SPAN style="COLOR: #cda869"&gt;internal&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;class&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;VirtualPathInstanceDescriptorProvider&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; : &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;IInstanceDescriptorProvider&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; {&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;private&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; _virtualPath;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;private&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;static&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;ConstructorInfo&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; s_Constructor = GetConstructor();&lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;private&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;static&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;ConstructorInfo&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; GetConstructor() {&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;return&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;typeof&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;VirtualPathTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;).GetConstructor(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;new&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;[] { &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;typeof&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;) });&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;public&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;InstanceDescriptor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; Descriptor {&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;get&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; {&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&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&gt;&lt;SPAN style="COLOR: #cda869"&gt;return&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;new&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;InstanceDescriptor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;(s_Constructor, &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;new&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;[] { _virtualPath });&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;public&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; VirtualPathInstanceDescriptorProvider(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; virtualPath) {&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&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_virtualPath = virtualPath;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&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&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;}&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;The code generation engine then generates the resulting code we wanted to specify above using the constructor info and virtual path.&lt;/P&gt;
&lt;P&gt;At runtime we use BuildManager.CreateInstanceFromVirtualPath(“~/MyUserControl.ascx”) to create an instance of the user control and add it to the control’s collection and we’re done.&lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6865888d-d092-4565-9973-259ece0eef41 class=wlWriterEditableSmartContent&gt;
&lt;DIV style="BORDER-BOTTOM: #000080 1px solid; BORDER-LEFT: #000080 1px solid; FONT-FAMILY: 'Consolas', Courier, Monospace; COLOR: #000; FONT-SIZE: 10pt; BORDER-TOP: #000080 1px solid; BORDER-RIGHT: #000080 1px solid"&gt;
&lt;DIV style="PADDING-BOTTOM: 2px; BACKGROUND-COLOR: #3f3f3f; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; WHITE-SPACE: nowrap; OVERFLOW: auto; PADDING-TOP: 2px"&gt;&lt;SPAN style="COLOR: #cda869"&gt;public&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;class&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;VirtualPathTemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; : &lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;ITemplate&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; {&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;private&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; _virtualPath;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;public&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; VirtualPathTemplate(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; virtualPath) {&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_virtualPath = virtualPath;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;public&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;void&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; InstantiateIn(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;Control&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; container) {&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #5f5a60"&gt;// Try to create the control from the virtual path&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;Control&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; control = (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;Control&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;)&lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;BuildManager&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;.CreateInstanceFromVirtualPath(_virtualPath, &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;typeof&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #9b703f"&gt;Control&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;));&lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt; (control != &lt;/SPAN&gt;&lt;SPAN style="COLOR: #cda869"&gt;null&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ffffff"&gt;) {&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&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&gt;&lt;SPAN style="COLOR: #5f5a60"&gt;// Add it to the controls collection&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&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;container.Controls.Add(control);&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #ffffff"&gt;}&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;H2&gt;Caveats&lt;/H2&gt;
&lt;P&gt;In order to get the parser to use your TypeDescriptionProvider you have to make one call (which is nicely wrapped up in an API in the sample ParserConfiguration.RegisterTemplateOverride()) which registers a TypeDescriptionProvider for the control type so that it will work with any control that has an ITemplate property. If you are writing custom controls you can also specify the TypeConverter attribute and use this same trick to support this without the global override.&lt;/P&gt;
&lt;P&gt;Also design time support is busted with this, but hey its a hack what would you expect :).&lt;/P&gt;
&lt;P&gt;Check out the sample &lt;A href="http://weblogs.asp.net/blogs/davidfowler/CustomTemplates.zip" mce_href="http://weblogs.asp.net/blogs/davidfowler/CustomTemplates.zip"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;Note: Code sample was built using vs2010 beta 2 but nothing should stop it from working on 3.5 sp1.&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7267711" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/davidfowler/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>More Data Binding</title><link>http://weblogs.asp.net/davidfowler/archive/2009/11/14/more-data-binding.aspx</link><pubDate>Sun, 15 Nov 2009 07:54:56 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7255230</guid><dc:creator>davidfowl</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=7255230</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2009/11/14/more-data-binding.aspx#comments</comments><description>&lt;p&gt;Last time I tried to solve one of the deficiencies of data binding by taking advantage of expando attributes. Today I want to throw an idea out there that I’ve been playing with since that blog post.I was looking at WPF’s data binding and wondered what it would take to have data binding in ASP.NET be as first class as data binding in WPF.&lt;/p&gt;  &lt;p&gt;There is no imperative (unless you mimic the generated code) way to setup 2 way data binding in ASP.NET, but what if there was? Maybe we should be able to setup bindings in the markup as well as code.&lt;/p&gt;  &lt;h2&gt;SetBinding&lt;/h2&gt;  &lt;p&gt;This hypothetical re-design of ASP.NET data binding includes a SetBinding method on the base control class that allows users to specify bindings imperatively.&lt;/p&gt;  &lt;div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas; background: #3f3f3f; color: white; font-size: 10pt; padding-top: 5px"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #cda869"&gt;public&lt;/span&gt; &lt;span style="color: #cda869"&gt;partial&lt;/span&gt; &lt;span style="color: #cda869"&gt;class&lt;/span&gt; &lt;span style="color: #9b703f"&gt;_Default&lt;/span&gt; : System.Web.UI.&lt;span style="color: #9b703f"&gt;Page&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;protected&lt;/span&gt; &lt;span style="color: #cda869"&gt;void&lt;/span&gt; Page_Init() {&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; textBox.SetBinding(&lt;span style="color: #8f9d6a"&gt;&amp;quot;Text&amp;quot;&lt;/span&gt;, &lt;span style="color: #cda869"&gt;new&lt;/span&gt; &lt;span style="color: #9b703f"&gt;DataBinding&lt;/span&gt;(&lt;span style="color: #8f9d6a"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;));&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The above code would setup 2 way binding for the text property to the FirstName property in the current item being databound (if we were using some data control).&lt;/p&gt;  &lt;div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas; background: #3f3f3f; color: white; font-size: 10pt; padding-top: 5px"&gt;   &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:TextBox&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;{Binding FirstName}&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:TextBox&lt;/span&gt;&amp;gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This is the equivalent markup of the code above. &lt;/p&gt;  &lt;p&gt;Unlike the current data binding story that’s all parse time magic, all the work here would be done in the runtime. The binding syntax would just be syntactic sugar.&lt;/p&gt;  &lt;p&gt;So we’ve re-implemented the current binding that ASP.NET supports today but what else can we do. Let’s take this concept of a binding and extend it.&lt;/p&gt;  &lt;p&gt;Sometimes it’s useful to have control’s properties be dependant on each other. Imagine some UI where you have a pager and a drop down list of possible page sizes. Whenever the page size changes you want to update the pager’s page size so that the list updates and shows the correct number of items. This can be done today with a bunch of code but wouldn’t it be nice to have this support natively in the framework?&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas; background: #3f3f3f; color: white; font-size: 10pt; padding-top: 5px"&gt;   &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:ListView&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;ProductsList&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;ItemTemplate&lt;/span&gt;&amp;gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ...&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/&lt;span style="color: #9b703f"&gt;ItemTemplate&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:ListView&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:DataPager&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #9b703f"&gt;PagedControlID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;ProductsList&amp;quot;&lt;/span&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #9b703f"&gt;PageSize=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;{ControlBinding pageSizes, Property=SelectedValue}&amp;quot;&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:DataPager&lt;/span&gt;&amp;gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:DropDownList&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;pageSizes&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;10&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;20&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;30&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;40&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:DropDownList&lt;/span&gt;&amp;gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;We’re using a control binding to bind the pageSizes.SelectedValue property to the pager’s PageSize property. &lt;/p&gt;  &lt;h2&gt;The prototype&lt;/h2&gt;  &lt;p&gt;Can’t have a blog post without code right :)? I’ve put together a little prototype of what this could look like but there are some gotchas.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;There is only one bindable control in the prototype &lt;strong&gt;&amp;lt;asp:BindableTextBox&amp;gt;&lt;/strong&gt; since I don’t have the power (I do but I wanted to give out a sample) to change the base Control class. &lt;/li&gt;    &lt;li&gt;The binding syntax only works for text properties. The ASP parser doesn’t like it when you supply invalid values for properties. i.e&amp;#160; &amp;lt;asp:BindableTextBox TextMode=”{Binding Foo}” /&amp;gt; won’t work since it will complain that it can’t convert that text to a TextMode enum. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;However you have full power in the code behind to do all of these things.&lt;/p&gt;  &lt;p&gt;To use the bindable controls just add the following to the &amp;lt;pages&amp;gt; section in web.config&lt;/p&gt;  &lt;div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas; background: #3f3f3f; color: white; font-size: 10pt; padding-top: 5px"&gt;   &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;add&lt;/span&gt; &lt;span style="color: #cda869"&gt;tagPrefix&lt;/span&gt;=&amp;quot;&lt;span style="color: #8f9d6a"&gt;asp&lt;/span&gt;&amp;quot; &lt;span style="color: #cda869"&gt;namespace&lt;/span&gt;=&amp;quot;&lt;span style="color: #8f9d6a"&gt;Web.Binding.Controls&lt;/span&gt;&amp;quot; &lt;span style="color: #cda869"&gt;assembly&lt;/span&gt;=&amp;quot;&lt;span style="color: #8f9d6a"&gt;Web.Binding&lt;/span&gt;&amp;quot;/&amp;gt;&lt;/p&gt; &lt;/div&gt;  &lt;h3&gt;What’s in the package?&lt;/h3&gt;  &lt;p&gt;There is a &lt;strong&gt;BindableControl&lt;/strong&gt; base class just in case you want to write more bindable controls :). &lt;/p&gt;  &lt;p&gt;The &lt;strong&gt;BindableTextBox&lt;/strong&gt; wraps a &lt;strong&gt;BindableControl&lt;/strong&gt; since C# doesn’t support multiple inheritance and we want to get the behavior of both of those classes. Ideally this would be baked into the base &lt;strong&gt;Control &lt;/strong&gt;class so all of the controls get this behavior for free.&lt;/p&gt;  &lt;p&gt;The &lt;strong&gt;BindableControlBuilder &lt;/strong&gt;parses the binding expressions and generates the right binding code.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas; background: #3f3f3f; color: white; font-size: 10pt; padding-top: 5px"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="color: #cda869"&gt;public&lt;/span&gt; &lt;span style="color: #cda869"&gt;class&lt;/span&gt; &lt;span style="color: #9b703f"&gt;BindableControlBuilder&lt;/span&gt; : &lt;span style="color: #9b703f"&gt;ControlBuilder&lt;/span&gt; {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;private&lt;/span&gt; &lt;span style="color: #9b703f"&gt;HashSet&lt;/span&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;BindingExpression&lt;/span&gt;&amp;gt; _bindings = &lt;span style="color: #cda869"&gt;new&lt;/span&gt; &lt;span style="color: #9b703f"&gt;HashSet&lt;/span&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;BindingExpression&lt;/span&gt;&amp;gt;();&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;public&lt;/span&gt; &lt;span style="color: #cda869"&gt;override&lt;/span&gt; &lt;span style="color: #cda869"&gt;void&lt;/span&gt; Init(&lt;span style="color: #9b703f"&gt;TemplateParser&lt;/span&gt; parser, &lt;span style="color: #9b703f"&gt;ControlBuilder&lt;/span&gt; parentBuilder, &lt;span style="color: #9b703f"&gt;Type&lt;/span&gt; type, &lt;span style="color: #cda869"&gt;string&lt;/span&gt; tagName, &lt;span style="color: #cda869"&gt;string&lt;/span&gt; id, &lt;span style="color: #9b703f"&gt;IDictionary&lt;/span&gt; attribs) {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;foreach&lt;/span&gt; (&lt;span style="color: #9b703f"&gt;DictionaryEntry&lt;/span&gt; entry &lt;span style="color: #cda869"&gt;in&lt;/span&gt; attribs.Cast&amp;lt;&lt;span style="color: #9b703f"&gt;DictionaryEntry&lt;/span&gt;&amp;gt;().ToList()) {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;string&lt;/span&gt; key = (&lt;span style="color: #cda869"&gt;string&lt;/span&gt;)entry.Key;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;string&lt;/span&gt; value = entry.Value &lt;span style="color: #cda869"&gt;as&lt;/span&gt; &lt;span style="color: #cda869"&gt;string&lt;/span&gt;;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #9b703f"&gt;BindingExpression&lt;/span&gt; expr;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;if&lt;/span&gt; (value != &lt;span style="color: #cda869"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style="color: #9b703f"&gt;BindingExpression&lt;/span&gt;.TryParse(key, value, &lt;span style="color: #cda869"&gt;out&lt;/span&gt; expr)) {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #5f5a60"&gt;// Add to our list of bindings&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _bindings.Add(expr);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #5f5a60"&gt;// Remove the attribute so the binding expression doesn't show up as a property value&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; attribs.Remove(key);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;base&lt;/span&gt;.Init(parser, parentBuilder, type, tagName, id, attribs);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;public&lt;/span&gt; &lt;span style="color: #cda869"&gt;override&lt;/span&gt; &lt;span style="color: #cda869"&gt;void&lt;/span&gt; ProcessGeneratedCode(&lt;span style="color: #9b703f"&gt;CodeCompileUnit&lt;/span&gt; codeCompileUnit, &lt;span style="color: #9b703f"&gt;CodeTypeDeclaration&lt;/span&gt; baseType, &lt;span style="color: #9b703f"&gt;CodeTypeDeclaration&lt;/span&gt; derivedType, &lt;span style="color: #9b703f"&gt;CodeMemberMethod&lt;/span&gt; buildMethod, &lt;span style="color: #9b703f"&gt;CodeMemberMethod&lt;/span&gt; dataBindingMethod) {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;if&lt;/span&gt; (buildMethod != &lt;span style="color: #cda869"&gt;null&lt;/span&gt;) {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;foreach&lt;/span&gt; (&lt;span style="color: #cda869"&gt;var&lt;/span&gt; binding &lt;span style="color: #cda869"&gt;in&lt;/span&gt; _bindings) {&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #5f5a60"&gt;// Generate code foreach binding and add it to the &lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #5f5a60"&gt;// build method for this control&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;var&lt;/span&gt; statement = binding.GenerateCode(buildMethod);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;int&lt;/span&gt; len = buildMethod.Statements.Count;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; buildMethod.Statements.Insert(len - &lt;span style="color: #cf6a4c"&gt;1&lt;/span&gt;, statement);&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin: 0px"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Also included in the package are 3 types of bindings:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Databinding – What ASP.NET has today. &lt;/li&gt;    &lt;li&gt;ControlBinding – Bind a control property to another control’s property &lt;/li&gt;    &lt;li&gt;ValueBinding – Bind a control property by executing a delegate to get the value. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The first 2 can be used declaratively but the ValueBinding is only supported imperatively.&lt;/p&gt;  &lt;p&gt;I’d love to get feedback on what people think about this. You can download the prototype &lt;a href="http://weblogs.asp.net/blogs/davidfowler/WPFStyleBinding.zip"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7255230" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/davidfowler/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/davidfowler/archive/tags/DataBinding/default.aspx">DataBinding</category><category domain="http://weblogs.asp.net/davidfowler/archive/tags/WPF/default.aspx">WPF</category></item><item><title>Databinding 3.0</title><link>http://weblogs.asp.net/davidfowler/archive/2009/11/13/databinding-3-0.aspx</link><pubDate>Fri, 13 Nov 2009 10:37:21 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7253317</guid><dc:creator>davidfowl</dc:creator><slash:comments>13</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=7253317</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2009/11/13/databinding-3-0.aspx#comments</comments><description>&lt;p&gt;There was a post on our internal discussion group recently where a customer pointed out one of the weaknesses of 2 way data binding not working within user controls. Consider the following page:&lt;/p&gt;  &lt;div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas; background: #3f3f3f; color: white; font-size: 10pt; padding-top: 5px"&gt;   &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:ObjectDataSource&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;personSource&amp;quot;&lt;/span&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #9b703f"&gt;SelectMethod=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;GetPersons&amp;quot;&lt;/span&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #9b703f"&gt;UpdateMethod=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;Update&amp;quot;&lt;/span&gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #9b703f"&gt;DataObjectTypeName=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;ExtendedDatabinding.Person&amp;quot;&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #9b703f"&gt;TypeName=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;ExtendedDatabinding.PersonRepository&amp;quot;&lt;/span&gt;&amp;gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:ObjectDataSource&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:FormView&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;personFormView&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;DataSourceID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;personSource&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;DefaultMode=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;Edit&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;DataKeyNames=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;EditItemTemplate&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;custom:personedit&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;personForm&amp;quot;&lt;/span&gt; /&amp;gt; &amp;lt;&lt;span style="color: #9b703f"&gt;br&lt;/span&gt; /&amp;gt; &amp;lt;&lt;span style="color: #9b703f"&gt;br&lt;/span&gt; /&amp;gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;asp:Button&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;Update&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;CommandName=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;Update&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/&lt;span style="color: #9b703f"&gt;EditItemTemplate&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:FormView&lt;/span&gt;&amp;gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;I have an ObjectDataSource that points to some business object and is bound to a form view. Also note that we have one usercontrol is the form view, &amp;lt;custom:personedit&amp;gt; which contains UI for an edit form. This is pretty useful since I may want the same UI for edit and insert I could just use the same usercontrol.&lt;/p&gt;  &lt;p&gt;The problem is this doesn’t work with 2 way binding, so the FormView won’t extract the values from within the usercontrol even if there are &amp;lt;%# Bind() #&amp;gt; expressions declared. Here’s what the user control looks like:&lt;/p&gt;  &lt;div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas; background: #3f3f3f; color: white; font-size: 10pt; padding-top: 5px"&gt;   &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;First Name:&amp;lt;/&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:TextBox&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;TextBox1&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;'&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;# Bind(&amp;quot;FirstName&amp;quot;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;'&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:TextBox&lt;/span&gt;&amp;gt; &amp;lt;&lt;span style="color: #9b703f"&gt;br&lt;/span&gt; /&amp;gt; &amp;lt;&lt;span style="color: #9b703f"&gt;br&lt;/span&gt; /&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;Last Name:&amp;lt;/&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:TextBox&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;TextBox2&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;'&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;# Bind(&amp;quot;LastName&amp;quot;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;'&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:TextBox&lt;/span&gt;&amp;gt; &amp;lt;&lt;span style="color: #9b703f"&gt;br&lt;/span&gt; /&amp;gt; &amp;lt;&lt;span style="color: #9b703f"&gt;br&lt;/span&gt; /&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;Address:&amp;lt;/&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:TextBox&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;TextBox3&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;TextMode=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;MultiLine&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Rows=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;5&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;'&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;# Bind(&amp;quot;Address&amp;quot;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;'&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:TextBox&lt;/span&gt;&amp;gt; &amp;lt;&lt;span style="color: #9b703f"&gt;br&lt;/span&gt; /&amp;gt; &amp;lt;&lt;span style="color: #9b703f"&gt;br&lt;/span&gt; /&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;State:&amp;lt;/&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:DropDownList&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;DropDownList1&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;SelectedValue=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;'&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;# Bind(&amp;quot;State&amp;quot;) &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;'&lt;/span&gt;&amp;gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;FL&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;WA&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;CA&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:DropDownList&lt;/span&gt;&amp;gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The sad thing is all of those Bind expression will be ignored when we hit update.&lt;/p&gt;  &lt;p&gt;I don’t want to get into exactly why this is the case (you should read about how &lt;a href="http://weblogs.asp.net/davidfowler/archive/2008/12/13/how-bind-works.aspx"&gt;bind works&lt;/a&gt;), instead I’d like to introduce a new way to do 2 way databinding.&lt;/p&gt;  &lt;p&gt;In Dynamic Data 3.5 sp1 we introduced an interface &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.ibindablecontrol.aspx"&gt;IBindableControl&lt;/a&gt; which has an ExtractValues method that takes a dictionary to populate with name value pairs. FormView and ListView know about this interface and will look recursively for controls that implement IBindinableControl and call ExtractValues when performing an update, insert or delete (also to store the edit values in viewstate). We could make our usercontrol implement this interface and manually extract data from each control and put it into the dictionary, but that is tedious. &lt;/p&gt;  &lt;p&gt;Enter databinding 3.0. Using the hidden gem &lt;a href="http://blogs.msdn.com/davidebb/archive/2008/11/19/a-hidden-gem-for-control-builder-writers.aspx"&gt;ProcessGeneratedCode&lt;/a&gt; we can build a base class which I call BindableUserControl that supports a different Bind syntax to make this scenario work.&lt;/p&gt;  &lt;p&gt;The idea exploits the fact that most controls derive from WebControl so we take advantage of their ability to use expando attributes and use it to declare a bogus Binding attribute with a some bind expression as the value. But enough talk lets dive into some code!&lt;/p&gt;  &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;  &lt;div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas; background: #3f3f3f; color: white; font-size: 10pt; padding-top: 5px"&gt;   &lt;p style="margin: 0px"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;@ &lt;span style="color: #9b703f"&gt;Control&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Language=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;C#&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Inherits=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;Web.Binding.BindableUserControl&amp;quot;&lt;/span&gt; &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;First Name:&amp;lt;/&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:TextBox&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;firstName&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Binding=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;{Text=FirstName}&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:TextBox&lt;/span&gt;&amp;gt; &amp;lt;&lt;span style="color: #9b703f"&gt;br&lt;/span&gt; /&amp;gt; &amp;lt;&lt;span style="color: #9b703f"&gt;br&lt;/span&gt; /&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;Last Name:&amp;lt;/&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:TextBox&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;lastName&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Binding=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;{Text=LastName}&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:TextBox&lt;/span&gt;&amp;gt; &amp;lt;&lt;span style="color: #9b703f"&gt;br&lt;/span&gt; /&amp;gt; &amp;lt;&lt;span style="color: #9b703f"&gt;br&lt;/span&gt; /&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;Address:&amp;lt;/&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:TextBox&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;address&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;TextMode=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;MultiLine&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Rows=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;5&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Binding=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;{Text=Address}&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:TextBox&lt;/span&gt;&amp;gt; &amp;lt;&lt;span style="color: #9b703f"&gt;br&lt;/span&gt; /&amp;gt; &amp;lt;&lt;span style="color: #9b703f"&gt;br&lt;/span&gt; /&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;State:&amp;lt;/&lt;span style="color: #9b703f"&gt;strong&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:DropDownList&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;ddl&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Binding=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;{SelectedValue=State}&amp;quot;&lt;/span&gt;&amp;gt; &lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;FL&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;WA&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Text=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;CA&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:ListItem&lt;/span&gt;&amp;gt;&lt;/p&gt;    &lt;p style="margin: 0px"&gt;&amp;lt;/&lt;span style="color: #9b703f"&gt;asp:DropDownList&lt;/span&gt;&amp;gt;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;We’re going to use the &lt;strong&gt;Binding&lt;/strong&gt; attribute to determine what to bind and also the kind of binding to do. From just looking you can pretty much follow the syntax:     &lt;br /&gt;{ControlPropertyName=PropertyName}&lt;/p&gt;  &lt;p&gt;There is also an enum you can use to specify what kind of binding you want to do:    &lt;br /&gt;    &lt;br /&gt;{Text=Description, Mode=TwoWay}     &lt;br /&gt;{Text=Description, Mode=In}     &lt;br /&gt;{Text=Description, Mode=Out}&lt;/p&gt;  &lt;p&gt;It basically tells the ControlBuilder what to generate i.e. Eval or ExtractValues statements or both.&lt;/p&gt;  &lt;p&gt;The special base class BindableUserControl has a FileLevelControlBuilder that does all of the magic. The good news is that binding will work as expected now.&lt;/p&gt;  &lt;p&gt;You can download the sample project here:    &lt;br /&gt;    &lt;br /&gt;&lt;a title="ExtendedDatabinding.zip" href="http://weblogs.asp.net/blogs/davidfowler/ExtendedDatabinding.zip"&gt;ExtendedDatabinding.zip&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7253317" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/davidfowler/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/davidfowler/archive/tags/DataBinding/default.aspx">DataBinding</category><category domain="http://weblogs.asp.net/davidfowler/archive/tags/Data+Controls/default.aspx">Data Controls</category></item><item><title>My first channel 9 video!</title><link>http://weblogs.asp.net/davidfowler/archive/2009/10/22/my-first-channel-9-video.aspx</link><pubDate>Fri, 23 Oct 2009 04:16:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7236675</guid><dc:creator>davidfowl</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=7236675</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2009/10/22/my-first-channel-9-video.aspx#comments</comments><description>Wow, I haven't blogged in a while...but that will end soon. Watch me talk about the QueryExtender control. It's a new control we added in ASP.NET 4.0 to make Linq queries even simpler. The new control works with LinqDataSource and EntityDataSource. We also built all of the new DynamicData filters on top of this new control.

&lt;br/&gt; &lt;br/&gt;
Check it out &lt;a href="http://channel9.msdn.com/posts/Glucose/Hanselminutes-on-9-ASPNET-4-and-David-Fowler-on-LinqExtender/"&gt; here &lt;/a&gt;
&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7236675" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/davidfowler/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Dynamic Data in Regular Websites/Web Applications</title><link>http://weblogs.asp.net/davidfowler/archive/2009/05/06/dynamic-data-preview-4.aspx</link><pubDate>Thu, 07 May 2009 01:33:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7075337</guid><dc:creator>davidfowl</dc:creator><slash:comments>24</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/davidfowler/rsscomments.aspx?PostID=7075337</wfw:commentRss><comments>http://weblogs.asp.net/davidfowler/archive/2009/05/06/dynamic-data-preview-4.aspx#comments</comments><description>&lt;h4&gt;Update: David Ebbo has a great video on channel9 about this. You can watch it &lt;a href="http://channel9.msdn.com/posts/Glucose/Hanselminutes-on-9-ASPNET-4-and-David-Ebbo-on-Dynamic-Data-for-Older-Apps/"&gt;here&lt;/a&gt;.&lt;/h4&gt;  &lt;p mce_keep="true"&gt;Today I'm excited to share that we've released DynamicData Preview 4 on codeplex. Check out the latest bits &lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=27026" mce_href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=27026"&gt;here&lt;/a&gt;.     &lt;br /&gt;    &lt;br /&gt;This release is particularly interesting not only for people that have been using Dynamic Data for a while now, but anyone that has an existing application today who wants to use some of the niceties Dynamic Data offers without having to take all the &lt;strong&gt;junk&lt;/strong&gt; associated. Take a look at the &lt;strong&gt;SimpleDynamicData&lt;/strong&gt; project for examples.     &lt;br /&gt;    &lt;br /&gt;&lt;strong&gt;&lt;u&gt;Existing Sites&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p mce_keep="true"&gt;Here are 2 good reasons to use Dynamic Data:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;div mce_keep="true"&gt;Rich model validation&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;div mce_keep="true"&gt;Rich templating support via FieldTemplates&amp;#160; &lt;/div&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p mce_keep="true"&gt;If you've ever written a data driven app in webforms using our data controls, you would have realized that we are lacking a lot when it comes to validation. You can enable all of this goodness with a magic extension method.&lt;/p&gt;  &lt;div style="border-bottom: #ccc 1px solid; border-left: #ccc 1px solid; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; font-family: consolas; background: black; color: white; font-size: 8pt; border-top: #ccc 1px solid; border-right: #ccc 1px solid; padding-top: 2px"&gt;   &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&lt;span style="color: #cda869"&gt;protected&lt;/span&gt; &lt;span style="color: #cda869"&gt;void&lt;/span&gt; Page_Init() {&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;    GridView1.EnableDynamicData(&lt;font color="#cda869"&gt;your type here&lt;/font&gt;);&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;}&lt;/pre&gt;
&lt;!--EndFragment--&gt;&lt;/div&gt;

&lt;p mce_keep="true"&gt;&lt;strong&gt;Note: The method requires that you pass in the type that may have annotations in order for us to read Metadata. If you're not familiar with the way annotations work in Dynamic Data then watch the videos &lt;/strong&gt;&lt;a href="http://www.asp.net/dynamicdata/" mce_href="http://www.asp.net/dynamicdata/"&gt;&lt;strong&gt;here&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p mce_keep="true"&gt;This method call enables &lt;strong&gt;DynamicControl&lt;/strong&gt;/&lt;strong&gt;DynamicField&lt;/strong&gt; to work within any of the data controls which makes use of &lt;a href="http://msdn.microsoft.com/en-us/library/cc488523.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc488523.aspx"&gt;&lt;strong&gt;FieldTemplates&lt;/strong&gt;&lt;/a&gt;, and enables the rich validation support.&lt;/p&gt;

&lt;p mce_keep="true"&gt;&lt;strong&gt;&lt;u&gt;Making it work&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p mce_keep="true"&gt;So we know about this magic method call and somehow calling it with a type makes it all just work. Let's walk through an example of how we would use this. Here is my model:&lt;/p&gt;

&lt;div style="border-bottom: #ccc 1px solid; border-left: #ccc 1px solid; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; font-family: consolas; background: black; color: white; font-size: 8pt; border-top: #ccc 1px solid; border-right: #ccc 1px solid; padding-top: 2px"&gt;
  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&lt;span style="color: #cda869"&gt;public&lt;/span&gt; &lt;span style="color: #cda869"&gt;class&lt;/span&gt; &lt;span style="color: #9b703f"&gt;Student&lt;/span&gt; {&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color: #9b703f"&gt;Required&lt;/span&gt;]&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color: #9b703f"&gt;Range&lt;/span&gt;(&lt;span style="color: #cf6a4c"&gt;0&lt;/span&gt;, &lt;span style="color: #cf6a4c"&gt;100&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;public&lt;/span&gt; &lt;span style="color: #cda869"&gt;int&lt;/span&gt; Age { &lt;span style="color: #cda869"&gt;get&lt;/span&gt;; &lt;span style="color: #cda869"&gt;set&lt;/span&gt;; }&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color: #9b703f"&gt;Range&lt;/span&gt;(&lt;span style="color: #cf6a4c"&gt;0.0&lt;/span&gt;, &lt;span style="color: #cf6a4c"&gt;4.0&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;public&lt;/span&gt; &lt;span style="color: #cda869"&gt;double&lt;/span&gt; GPA { &lt;span style="color: #cda869"&gt;get&lt;/span&gt;; &lt;span style="color: #cda869"&gt;set&lt;/span&gt;; }&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color: #9b703f"&gt;Required&lt;/span&gt;]&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;public&lt;/span&gt; &lt;span style="color: #cda869"&gt;string&lt;/span&gt; FirstName { &lt;span style="color: #cda869"&gt;get&lt;/span&gt;; &lt;span style="color: #cda869"&gt;set&lt;/span&gt;; }&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color: #9b703f"&gt;Required&lt;/span&gt;]&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;public&lt;/span&gt; &lt;span style="color: #cda869"&gt;string&lt;/span&gt; LastName { &lt;span style="color: #cda869"&gt;get&lt;/span&gt;; &lt;span style="color: #cda869"&gt;set&lt;/span&gt;; }&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; [&lt;span style="color: #9b703f"&gt;DisplayFormat&lt;/span&gt;(DataFormatString = &lt;span style="color: #8f9d6a"&gt;&amp;quot;{0:d/M/yyyy}&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #cda869"&gt;public&lt;/span&gt; &lt;span style="color: #9b703f"&gt;DateTime&lt;/span&gt; BirthDate { &lt;span style="color: #cda869"&gt;get&lt;/span&gt;; &lt;span style="color: #cda869"&gt;set&lt;/span&gt;; }&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;

&lt;p&gt;This is the type we are going to use for metadata. Using the attributes from &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"&gt;System.ComponentModel.DataAnnotations&lt;/a&gt; we can add useful annotations to our model that will be used for validation and display formatting. Adding these attributes allows Dynamic Data to enable the appropriate validator. i.e RangeValidator, RequiredFieldValidator etc.&lt;/p&gt;

&lt;p&gt;Now we're going to enable this on our GridView using the same method call as above in conjunction with an ObjectDataSource to complete our application: 
  &lt;br /&gt;&lt;/p&gt;

&lt;div style="border-bottom: #ccc 1px solid; border-left: #ccc 1px solid; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; font-family: consolas; background: black; color: white; font-size: 8pt; border-top: #ccc 1px solid; border-right: #ccc 1px solid; padding-top: 2px"&gt;
  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&lt;span style="color: #cda869"&gt;protected&lt;/span&gt; &lt;span style="color: #cda869"&gt;void&lt;/span&gt; Page_Init() {&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; GridView1.EnableDynamicData(&lt;span style="color: #cda869"&gt;typeof&lt;/span&gt;(&lt;span style="color: #9b703f"&gt;Student&lt;/span&gt;));&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;

&lt;p mce_keep="true"&gt;&lt;strong&gt;&lt;u&gt;Markup&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: #ccc 1px solid; border-left: #ccc 1px solid; padding-bottom: 2px; padding-left: 2px; padding-right: 2px; font-family: consolas; background: black; color: white; font-size: 8pt; border-top: #ccc 1px solid; border-right: #ccc 1px solid; padding-top: 2px"&gt;
  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;lt;&lt;span style="color: #9b703f"&gt;asp:GridView&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;GridView1&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;DataSourceID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;ObjectDataSource1&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;AutoGenerateEditButton=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&amp;gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/&lt;span style="color: #9b703f"&gt;asp:GridView&lt;/span&gt;&amp;gt;&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;span style="color: #9b703f"&gt;asp:ObjectDataSource&lt;/span&gt; &lt;span style="color: #9b703f"&gt;ID=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;ObjectDataSource1&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;runat=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #9b703f"&gt;DataObjectTypeName=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;Student&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;DeleteMethod=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;DeleteStudent&amp;quot;&lt;/span&gt; &lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #9b703f"&gt;InsertMethod=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;InsertStudent&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;SelectMethod=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;GetStudents&amp;quot;&lt;/span&gt; &lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #9b703f"&gt;TypeName=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;StudentsRepository&amp;quot;&lt;/span&gt; &lt;span style="color: #9b703f"&gt;UpdateMethod=&lt;/span&gt;&lt;span style="color: #8f9d6a"&gt;&amp;quot;UpdateStudent&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;

  &lt;pre style="margin: 0px; font-family: consolas; font-size: 10pt"&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/&lt;span style="color: #9b703f"&gt;asp:ObjectDataSource&lt;/span&gt;&amp;gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Note: Dynamic Data takes care of the Metadata not the data. You still need databind the data control against some data source/data source control.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here are the results when we are editing:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/davidfowler/dynamic_data_grid.png" mce_href="http://weblogs.asp.net/blogs/davidfowler/dynamic_data_grid.png"&gt;&lt;img style="width: 927px; height: 160px" border="0" src="http://weblogs.asp.net/blogs/davidfowler/dynamic_data_grid.png" width="1094" height="174" mce_src="http://weblogs.asp.net/blogs/davidfowler/dynamic_data_grid.png" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the attributes we specified on our Student class directly affect the grid and validation is enabled.&lt;/p&gt;

&lt;p&gt;There's more cool stuff to talk about but I'll mention those in upcoming posts. For now, download the preview and read up on Dynamic Data!&lt;/p&gt;
&lt;!--EndFragment--&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7075337" width="1" height="1"&gt;</description></item></channel></rss>