<?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>Tales from the Evil Empire : ASP.NET</title><link>http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx</link><description>Tags: ASP.NET</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>Orchard team looking for a new developer</title><link>http://weblogs.asp.net/bleroy/archive/2009/11/23/orchard-team-looking-for-a-new-developer.aspx</link><pubDate>Mon, 23 Nov 2009 19:24:19 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7263678</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7263678</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/11/23/orchard-team-looking-for-a-new-developer.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 10px 0px; display: inline; border-top: 0px; border-right: 0px" title="(c) 2005 Bertrand Le Roy" border="0" alt="(c) 2005 Bertrand Le Roy" align="left" src="http://weblogs.asp.net/blogs/bleroy/Dragonfly_5E7683B7.jpg" width="244" height="164" /&gt; My team is looking for a new full-time developer. The project is to build a completely new open-source CMS based on ASP.NET MVC 2. It’s a lot of fun :)&lt;/p&gt;  &lt;p&gt;&lt;a href="https://careers.microsoft.com/JobDetails.aspx?ss=&amp;amp;pg=0&amp;amp;so=&amp;amp;rw=1&amp;amp;jid=9434&amp;amp;jlang=EN"&gt;https://careers.microsoft.com/JobDetails.aspx?ss=&amp;amp;pg=0&amp;amp;so=&amp;amp;rw=1&amp;amp;jid=9434&amp;amp;jlang=EN&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7263678" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/CSS/default.aspx">CSS</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/SQL/default.aspx">SQL</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>Enabling the ASP.NET Ajax script loader for your own scripts</title><link>http://weblogs.asp.net/bleroy/archive/2009/11/23/enabling-the-asp-net-ajax-script-loader-for-your-own-scripts.aspx</link><pubDate>Mon, 23 Nov 2009 15:00:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7262909</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7262909</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/11/23/enabling-the-asp-net-ajax-script-loader-for-your-own-scripts.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 10px 0px; display: inline; border-top: 0px; border-right: 0px" title="(c) 2009 Bertrand Le Roy" border="0" alt="(c) 2009 Bertrand Le Roy" align="left" src="http://weblogs.asp.net/blogs/bleroy/IMG_2351_078C57E8.jpg" width="244" height="164" /&gt; In previous posts, I’ve shown different ways to build a client-side class browser, using the ASP.NET Ajax Libary and jQuery.&lt;/p&gt;  &lt;p&gt;In this post, I’ll focus on a few lines of code from the latest version of that sample. Those few lines of code enable my custom script to benefit from the script loader’s features such as lazy and parallel loading and dependency management.&lt;/p&gt;  &lt;p&gt;An important feature of the script loader is the separation of the script meta-data from the script code itself. The meta-data can include the name of the script, its dependencies, instructions on how to figure out if it’s already loaded, its debug and release URL patterns and a declaration of the lazy components and plug-ins it introduces. The script loader can also handle composite scripts but I won’t cover that in this post.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The &lt;strong&gt;name&lt;/strong&gt; of the script is what will be used to reference it from other scripts and to generate the URL from a pattern. It shouldn’t include the “.js” extension.&lt;/li&gt;    &lt;li&gt;The &lt;strong&gt;dependencies&lt;/strong&gt; and executionDependencies are each a simple array of script names that the script depends on. I’ll explain the difference in a minute.&lt;/li&gt;    &lt;li&gt;The &lt;strong&gt;is loaded&lt;/strong&gt; criterion is a JavaScript expression that returns true if the script is already loaded. This is usually a test on an object that the script file defines. For example, the “templates” script uses !!(Sys.UI &amp;amp;&amp;amp; Sys.UI.Templates). It can assume Sys because it’s defined by start.js. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Debug and release patterns&lt;/strong&gt; are expressions that enable the framework to map script names into debug and release URLs. The ASP.NET Library uses “%/MicrosoftAjax{0}.debug.js” and “%/MicrosoftAjax{0}.js” where % gets replaced with the path where the script loader was downloaded from (this can be CDN or local) and {0} gets replaced with the script name. You can create your own pattern or just provide fixed URLs if you have only one script file. The debug pattern is optional.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Lazy components and plug-ins&lt;/strong&gt; are helpers that the script loader can create for you and that enable developers to start using your components before they are even loaded and hide the script loading aspects as much as possible. For example, it’s that feature that enables you to write this while still having only start.js loaded:       &lt;pre class="code"&gt;Sys.create.dataView(&lt;span style="color: maroon"&gt;&amp;quot;#myDataView&amp;quot;&lt;/span&gt;, {
    data: myData
});&lt;/pre&gt;
The code that needed to be written for this helper to be created was this: 

    &lt;pre class="code"&gt;behaviors: [&lt;span style="color: maroon"&gt;&amp;quot;Sys.UI.DataView&amp;quot;&lt;/span&gt;]&lt;/pre&gt;
This gets automatically transformed by the script loader into the Sys.create.dataView method, before it even tries to load the actual script that defines Sys.UI.DataView. And if you have jQuery loaded as well, you’ll also get a jQuery plug-in out of it for free, which means that you can do: 

    &lt;pre class="code"&gt;$(&lt;span style="color: maroon"&gt;&amp;quot;.data&amp;quot;&lt;/span&gt;).dataView({data: myData});&lt;/pre&gt;
and instantiate DataView controls over the results of a selector query in one operation. Groovy. Of course, you can do the same with the behaviors and controls that you write in your own scripts, with lots of options to customize names, add parameters, etc. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the case of the class library code, here’s the meta-data declaration code that I had to write:&lt;/p&gt;

&lt;pre class="code"&gt;Sys.loader.defineScript({
  name: &lt;span style="color: maroon"&gt;&amp;quot;classBrowserTree&amp;quot;&lt;/span&gt;,
  releaseUrl: &lt;span style="color: maroon"&gt;&amp;quot;%/TreejQuery.js&amp;quot;&lt;/span&gt;,
  executionDependencies:&lt;br /&gt;    [&lt;span style="color: maroon"&gt;&amp;quot;jQuery&amp;quot;&lt;/span&gt;, &lt;span style="color: maroon"&gt;&amp;quot;Templates&amp;quot;&lt;/span&gt;, &lt;span style="color: maroon"&gt;&amp;quot;ComponentModel&amp;quot;&lt;/span&gt;],
  isLoaded: !!(window.jQuery &amp;amp;&amp;amp;&lt;br /&gt;    window.jQuery.fn.classBrowserTreeView)
});&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This declares that my script, named “classBrowserTree”, can be found at the URL TreejQuery.js relative to the base URL of the script loader, that it depends on jQuery, Templates and ComponentModel (which themselves have their own dependencies) and that the loader can determine whether it’s already loaded by evaluating the classBrowserTreeView jQuery plug-in.&lt;/p&gt;

&lt;p&gt;Now, loading that script and all its dependencies is as simple as writing this:&lt;/p&gt;

&lt;pre class="code"&gt;Sys.require(Sys.scripts.classBrowserTree);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Notice that as you’re typing this, you actually get full IntelliSense in Visual Studio on the name of the script, which is great for speed and to avoid typos:&lt;img style="border-bottom: 0px; border-left: 0px; margin: 5px auto; display: block; float: none; border-top: 0px; border-right: 0px" title="ScriptLoaderIntelliSense" border="0" alt="ScriptLoaderIntelliSense" src="http://weblogs.asp.net/blogs/bleroy/ScriptLoaderIntelliSense_10B86D5C.png" width="520" height="387" /&gt; &lt;/p&gt;

&lt;p&gt;One of the things that enable the script loader to do its job is a special way to write your script that makes it possible to separate the loading and parsing of the code from its execution.&lt;/p&gt;

&lt;p&gt;Don’t freak out (yet) though as the code you have to introduce is very lightweight and it doesn’t prevent your script from being loaded &lt;em&gt;without&lt;/em&gt; the script loader (with a plain old script tag for example).&lt;/p&gt;

&lt;p&gt;Reversely, a script that doesn’t have the special script loader code can be handled by the script loader but its dependencies must be declared using “dependencies” instead of “executionDependencies” in the meta-data declaration code, which will in effect disable the more advanced features of the script loader such as parallel loading.&lt;/p&gt;

&lt;p&gt;The special code in question is the following:&lt;/p&gt;

&lt;pre class="code"&gt;(&lt;span style="color: blue"&gt;function&lt;/span&gt;() {
  &lt;span style="color: blue"&gt;function &lt;/span&gt;execute() {
    &lt;span style="color: #006400"&gt;// Your code goes here.
&lt;/span&gt;  }
  &lt;span style="color: blue"&gt;if &lt;/span&gt;(window.Sys &amp;amp;&amp;amp; Sys.loader) {
    Sys.loader.registerScript(&lt;br /&gt;      &lt;span style="color: maroon"&gt;&amp;quot;classBrowserTree&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;null&lt;/span&gt;, execute);
  }
  &lt;span style="color: blue"&gt;else &lt;/span&gt;{
    execute();
  }
})();&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;What you see here is a (function() {…})(); wrapper, which is standard practice to isolate code from the global namespace (essentially, it’s a local scope); we also have another named scope in there that we arbitrarily call “execute” (but the name doesn’t matter). This is where you’ll typically put your actual code. Then we have the bootstrapping code that looks for the script loader. If it isn’t found, the code in the execute function is immediately run. If it &lt;em&gt;is&lt;/em&gt; found, the execute function is registered with the script loader but is not immediately executed.&lt;/p&gt;

&lt;p&gt;This wrapper code is what enables the script loader to do its magic. Thanks to this little bit of code, it doesn’t care at all in what order the scripts are being loaded, because it can delay the time when any script actually gets executed until all its dependencies have been successfully loaded.&lt;/p&gt;

&lt;p&gt;This also allows the script loader to load scripts in parallel, even if one depends on another. Normally a script loader would have to download a dependent script first and wait for it to completely load before loading the next script. This ‘serializes’ the loading process and is not good for performance. Modern browsers can download 6 to 8 scripts simultaneously. Separating the loading of a script from its execution allows the loader to take advantage of that, and in most cases, even complex dependency trees can be downloaded completely in parallel, meaning the total time is not the sum of each script, but only the longest one.&lt;/p&gt;

&lt;p&gt;Of course, in order to be wrappable, your code needs to be able to run in a non-global scope. This is good practice anyways and is relatively easy to achieve in most cases, so if it can’t, it may be a good idea to try to determine why and fix it.&lt;/p&gt;

&lt;p&gt;And this is it. I hope I’ve convinced you that the script loader can help you to improve the performance of your applications at a really low cost. It also provides a very worthy client-side equivalent of the server-side ScriptManager that ASP.NET has been providing to developers for years: switching the whole application between debug and release scripts is a breeze, which minimizes the risk of deploying debug scripts in production; dependencies are being handled automatically; script combination is handled.&lt;/p&gt;

&lt;p&gt;(many thanks to &lt;a href="http://weblogs.asp.net/infinitiesloop"&gt;Dave Reed&lt;/a&gt; for helping with this post and of course for implementing an awesome script loader)&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7262909" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category></item><item><title>PDC week! Panel on OSS + ASP.NET</title><link>http://weblogs.asp.net/bleroy/archive/2009/11/16/pdc-week-panel-on-oss-asp-net.aspx</link><pubDate>Mon, 16 Nov 2009 22:13:48 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7257068</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7257068</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/11/16/pdc-week-panel-on-oss-asp-net.aspx#comments</comments><description>&lt;p&gt;&lt;img style="margin: 0px 10px 10px 0px" title="image" border="0" alt="image" align="left" src="http://blogs.msdn.com/blogfiles/brada/WindowsLiveWriter/PDC2009Icantwait_88A8/image_3.png" width="325" height="88" /&gt;I’ll be at PDC tomorrow, Wednesday and Thursday. If you are attending and want to say hi, you’re most likely to find me in the Web Pavilion (in the big room, next to the Surface lounge).&lt;/p&gt;  &lt;p&gt;Please also join us for a panel discussion on Wednesday about Open Source on ASP.NET. We’ll have the following people on the panel to answer your questions, and ask you a few too:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Scott Hanselman&lt;/li&gt;    &lt;li&gt;Shaun Walker&lt;/li&gt;    &lt;li&gt;Sara Ford&lt;/li&gt;    &lt;li&gt;Glenn Block&lt;/li&gt;    &lt;li&gt;Clemens Vasters&lt;/li&gt;    &lt;li&gt;Myself&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The discussion will be between 2PM and 3PM, in the Web Pavilion.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7257068" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/PDC/default.aspx">PDC</category></item><item><title>Metrics in software and physics</title><link>http://weblogs.asp.net/bleroy/archive/2009/11/13/metrics-in-software-and-physics.aspx</link><pubDate>Sat, 14 Nov 2009 07:32:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7254161</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7254161</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/11/13/metrics-in-software-and-physics.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 10px 0px; display: inline; border-top: 0px; border-right: 0px" title="A Horrible experiment" border="0" alt="A Horrible experiment" align="left" src="http://weblogs.asp.net/blogs/bleroy/IMG_3417_49AFDA4B.jpg" width="164" height="244" /&gt; Every so often, &lt;a href="http://codebetter.com/blogs/david_laribee/archive/2009/11/13/code-coverage-what-is-it-good-for.aspx"&gt;somebody points out how bad of a metric code coverage is&lt;/a&gt;. And of course, on its own, it doesn’t tell you much: after all, it’s a single number. How could it possibly reflect all the subtlety (or lack thereof) of your designs and of your testing artillery? Of course, within all the various *DD approaches, some better than others enable you to know whether or not your code conforms to its requirements, but I thought I’d take a moment to reflect on the general idea of a software metric and how it relates to the mothers of all metrics: physical ones, cause you know, I used to be a scientist. Proof: the lab coat on the picture.&lt;/p&gt;  &lt;p&gt;The theory of measurement is at the center of all experimental physics. This comes from the realization that any observation of the natural world is ultimately indirect.&lt;/p&gt;  &lt;p&gt;For example, when you look at a red ball, you don’t directly perceive it. Rather, photons hit it, some of them are absorbed by the surface of the ball (violet, blue, green and yellow ones, but not red ones) and some of them bounce back (the red ones if you’ve been following). Those red photons that bounced back then hit your eyes, where a lens distorts their paths so that all those photons that came from a specific point on the ball converge to roughly the same spot on your retina. Then, the photoreceptor cells on the retina transform the light signal into electric impulses in your optic nerve, which conveys all that information into your brain and then, only then the complex mechanisms of conscience give you the wonderful illusion of seeing a red ball in front of your eyes.&lt;/p&gt;  &lt;p&gt;The brain reconstructs a model of the universe, but what it really ever perceives is a pattern of electric impulses. Everything in between is a rather elaborate &lt;a href="http://rubegoldberg.com/"&gt;Rube-Goldberg&lt;/a&gt; contraption that can be trusted most of the time but that is actually &lt;a href="http://www.bing.com/images/search?q=optical+illusions"&gt;rather easy to fool&lt;/a&gt;. That it can be fooled at all is the simple consequence that what you observe is an indirect and partial measure of reality rather than reality itself.&lt;/p&gt;  &lt;p&gt;When we measure anything in physics, we build our own devices that transform objective reality into perceivable quantities. For example, when physicists say &lt;a href="http://exoplanet.eu/"&gt;they have “seen” a planet around a faraway sun&lt;/a&gt;, they don’t (always) mean that they put their eyes on the smaller end of a telescope and perceived the shape of that planet with their own eyes like I saw the red ball of the previous paragraph. No, what they saw is something like this on a computer monitor:&lt;a href="http://www.iop.org/EJ/article/1538-4357/529/1/L45/995832.html"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 10px auto; display: block; float: none; border-top: 0px; border-right: 0px" title="What a beautiful planet!" border="0" alt="What a beautiful planet!" src="http://weblogs.asp.net/blogs/bleroy/fg2_73632F71.gif" width="520" height="355" /&gt;&lt;/a&gt;This shows the very small (1.5%) variation of the light coming from the star as the planet transits in front of it. All this really tells them is that something dark that takes about 1.5% of the area of the star passed in front of it. By repeating that observation, they can see that it happens every 3.5 days. That’s it. No image, just measures of the amount of light coming out of a powerful telescope aimed at a star against time.&lt;/p&gt;  &lt;p&gt;But just from that minimal data and our centuries old knowledge of celestial mechanics, researchers were able to deduce that a planet 1.27 times the size of Jupiter but 0.63 times its mass and a surface gravity about the same as Earth’s was orbiting that star. That’s an impressively precise description of a big ball of gas that is 150 light years away (that’s 1.4 million billion kilometers in case you’re wondering or 880 thousand billion miles if you insist on using an archaic unit system).&lt;/p&gt;  &lt;p&gt;The Rube Goldberg device that enables us to see that big ball of gas from so far away is a mix of optics, electronics and &lt;em&gt;knowledge&lt;/em&gt;, the latter being the really awesome part. Science is awesome. The bottom line of all this is that although it seems less “direct” than seeing the red ball with our own eyes, it does just as well deserve to be described as “seeing” it. The only difference is that we’re not seeing with our eyes but more with our brains. How awesome is that?&lt;/p&gt;  &lt;p&gt;Where was I?&lt;/p&gt;  &lt;p&gt;Yes, you might be wondering what this has to do with software. Well, all that long digression was to show that little data is necessary to infer a lot about the object you’re observing. So code coverage? Sure, it’s just a number, but combined with a few other numbers, it can help get a reliable picture of software quality.&lt;/p&gt;  &lt;p&gt;Another point I’d like to make is that a lot of resistance to software metrics comes from the illusion that we know a lot more about our own code than any tool can tell us. But as anyone who has ever tried to read code he wrote only five years ago knows, that is delusional. What you know about your code is a combination of what you remember and what you &lt;em&gt;intended&lt;/em&gt; to write, neither of which is particularly reliably representative of what your code is doing. Tools give us a much more reliable picture. Sure, it’s a narrow projection of the code and it doesn’t capture its full reality, but that is exactly the point of a measure: to project a complex object along a scale of our choosing. What set of projections you choose to make is what determines their relevance.&lt;/p&gt;  &lt;p&gt;The conclusion of all this is that we should assume that our code is an unknown object that needs to be measured, like that big ball of gas 150 light years away, if we want to get an objective idea of its quality without having our judgment clouded by our own assumptions.&lt;/p&gt;  &lt;p&gt;And probably the best tool you can use to do exactly this by the way is &lt;a href="http://www.ndepend.com/"&gt;NDepend&lt;/a&gt; by &lt;a href="http://codebetter.com/blogs/patricksmacchia/default.aspx"&gt;Patrick Smacchia&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7254161" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Science/default.aspx">Science</category></item><item><title>JavaScript class browser: once again with jQuery</title><link>http://weblogs.asp.net/bleroy/archive/2009/10/30/javascript-class-browser-once-again-with-jquery.aspx</link><pubDate>Fri, 30 Oct 2009 17:43:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7243389</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7243389</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/10/30/javascript-class-browser-once-again-with-jquery.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/bleroy/MercuryWeb_1CBF87AD.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 10px 0px; display: inline; border-top: 0px; border-right: 0px" title="(c) 2004 Bertrand Le Roy" border="0" alt="(c) 2004 Bertrand Le Roy" align="left" src="http://weblogs.asp.net/blogs/bleroy/MercuryWeb_thumb_1373269F.jpg" width="184" height="244" /&gt;&lt;/a&gt; I’ve already posted twice about that little class browser application. The first iteration was mostly declarative and can be found here:    &lt;br /&gt;&lt;a title="http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx" href="http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx"&gt;http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The second one was entirely imperative and can be found here:   &lt;br /&gt;&lt;a title="http://weblogs.asp.net/bleroy/archive/2009/10/15/entirely-unobtrusive-and-imperative-templates-with-microsoft-ajax-4-preview-6.aspx" href="http://weblogs.asp.net/bleroy/archive/2009/10/15/entirely-unobtrusive-and-imperative-templates-with-microsoft-ajax-4-preview-6.aspx"&gt;http://weblogs.asp.net/bleroy/archive/2009/10/15/entirely-unobtrusive-and-imperative-templates-with-microsoft-ajax-4-preview-6.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This new version builds on top of the code for the imperative version and adds the jQuery dependency in an attempt to make the code leaner and simpler. I invite you to refer to the imperative code (included in the &lt;a href="http://weblogs.asp.net/blogs/bleroy/Samples/ClassBrowserWithjQuery.zip"&gt;archive for this post&lt;/a&gt;) and compare it with the jQuery version, which shows a couple of ways the Microsoft Ajax Library lights up when jQuery is present.&lt;/p&gt;  &lt;p&gt;The first thing I want to do here is convert the plain function I was using to build the browser’s namespace and class tree into a jQuery plug-in:&lt;/p&gt;  &lt;pre class="code"&gt;$.fn.classBrowserTreeView = &lt;span style="color: blue"&gt;function &lt;/span&gt;(options) {
  &lt;span style="color: blue"&gt;var &lt;/span&gt;opts = $.extend({},&lt;br /&gt;    $.fn.classBrowserTreeView.defaults,&lt;br /&gt;    options);
  &lt;span style="color: blue"&gt;return this&lt;/span&gt;;
};&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;That plug-in will have two options: the data to render (which will default to the root namespaces in the Microsoft Ajax Library), and the node template selector (which will default to “#nodeTemplate”):&lt;/p&gt;

&lt;pre class="code"&gt;$.fn.classBrowserTreeView.defaults = {
  data: Type.getRootNamespaces(),
  nodeTemplate: &lt;span style="color: maroon"&gt;&amp;quot;#nodeTemplate&amp;quot;
&lt;/span&gt;};&lt;/pre&gt;

&lt;p&gt;For the moment, as you can see, this plug-in does nothing. We want it to create a DataView control on each of the elements of the current wrapped set. We will do this by calling into the dataView plug-in.&lt;/p&gt;

&lt;p&gt;You may be wondering where this plug-in might come from. Well, that’s the first kind of lighting up that the Microsoft Ajax Library’s script loader (start.js) will do in the presence of jQuery: every control and behavior will get surfaced as a jQuery plug-in, and components will get added as methods on the jQuery object. This is similar to what I had shown a while ago in this post, only much easier:
  &lt;br /&gt;&lt;a title="http://weblogs.asp.net/bleroy/archive/2009/05/04/creating-jquery-plug-ins-from-microsoftajax-components.aspx" href="http://weblogs.asp.net/bleroy/archive/2009/05/04/creating-jquery-plug-ins-from-microsoftajax-components.aspx"&gt;http://weblogs.asp.net/bleroy/archive/2009/05/04/creating-jquery-plug-ins-from-microsoftajax-components.aspx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, we can write this in our own plug-in to create DataView components over the current jQuery wrapped set:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;return this&lt;/span&gt;.dataView({
  data: opts.data,
  itemTemplate: opts.nodeTemplate,
});&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Now we can wire up the itemRendered event of the data view and start enriching the markup that the DataView control rendered for each data item. First, let’s get hold of the nodes in the rendered template and wrap them:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;elt = $(args.nodes);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Then, if the current node is representing a namespace, we want to hook up the expansion button’s click event so that it toggles visibility of the list of children, and we want to “unhide” the button itself (it has a “hidden” class in the default markup):&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(Type.isNamespace(args.dataItem)) {
  elt.find(&lt;span style="color: maroon"&gt;&amp;quot;.toggleButton&amp;quot;&lt;/span&gt;).click(&lt;span style="color: blue"&gt;function &lt;/span&gt;(e) {
    e.preventDefault();
    &lt;span style="color: blue"&gt;return &lt;/span&gt;toggleVisibility(&lt;span style="color: blue"&gt;this&lt;/span&gt;);
  }).removeClass(&lt;span style="color: maroon"&gt;&amp;quot;hidden&amp;quot;&lt;/span&gt;);
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;You can see here that we’re taking advantage of chaining.&lt;/p&gt;

&lt;p&gt;Next thing is to set-up the node link itself. We start by inhibiting the link’s default action. Then we set the text for the link, and finally we set the command that will bubble up to the DataView when the link gets clicked:&lt;/p&gt;

&lt;pre class="code"&gt;elt.find(&lt;span style="color: maroon"&gt;&amp;quot;.treeNode&amp;quot;&lt;/span&gt;).click(&lt;br /&gt;  &lt;span style="color: blue"&gt;function &lt;/span&gt;(e) {&lt;br /&gt;    e.preventDefault();&lt;br /&gt;    &lt;span style="color: blue"&gt;return false&lt;/span&gt;;&lt;br /&gt;  })
  .text(getSimpleName(args.dataItem.getName()))
  .setCommand(&lt;span style="color: maroon"&gt;&amp;quot;select&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Here, I’m using a small plug-in to set the command:&lt;/p&gt;

&lt;pre class="code"&gt;$.fn.setCommand = &lt;span style="color: blue"&gt;function &lt;/span&gt;(options) {
  &lt;span style="color: blue"&gt;var &lt;/span&gt;opts = $.extend({},&lt;br /&gt;    $.fn.setCommand.defaults, options);
  &lt;span style="color: blue"&gt;return &lt;/span&gt;$(&lt;span style="color: blue"&gt;this&lt;/span&gt;).each(&lt;span style="color: blue"&gt;function &lt;/span&gt;() {
    $.setCommand(&lt;span style="color: blue"&gt;this&lt;/span&gt;,&lt;br /&gt;      opts.commandName,&lt;br /&gt;      opts.commandArgument,&lt;br /&gt;      opts.commandTarget);
  });
}
$.fn.setCommand.defaults = {
    commandName: &lt;span style="color: maroon"&gt;&amp;quot;select&amp;quot;&lt;/span&gt;,
    commandArgument: &lt;span style="color: blue"&gt;null&lt;/span&gt;,
    commandTarget: &lt;span style="color: blue"&gt;null
&lt;/span&gt;};&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I’m using $.setCommand here, which does get created by the framework for me, but I still need to create that small plug-in to make it work on a wrapped set instead of a static method off jQuery. I’ve sent feedback to the team that setCommand and bind should get created as plug-ins by the framework and hopefully it will happen in a future version.&lt;/p&gt;

&lt;p&gt;The last thing we need to do here is to recursively create the child branches of our tree:&lt;/p&gt;

&lt;pre class="code"&gt;elt.find(&lt;span style="color: maroon"&gt;&amp;quot;ul&amp;quot;&lt;/span&gt;).classBrowserTreeView({
    data: getChildren(args.dataItem)
});&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This just finds the child UL element of the current branch and calls our plug-in on the results with the children namespaces and classes as the data.&lt;/p&gt;

&lt;p&gt;And this is it for the tree, we can now create it with this simple call:&lt;/p&gt;

&lt;pre class="code"&gt;$(&lt;span style="color: maroon"&gt;&amp;quot;#tree&amp;quot;&lt;/span&gt;).classBrowserTreeView();&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The details view rendering will only differ in minor ways from the code we had in our previous imperative version. The only differences is the use of jQuery to traverse and manipulate the DOM instead of the mix of native DOM APIs and Sys.get that we were using before. For example,&lt;/p&gt;

&lt;pre class="code"&gt;args.get(&lt;span style="color: maroon"&gt;&amp;quot;li&amp;quot;&lt;/span&gt;).innerHTML =&lt;br /&gt;  args.dataItem.getName ?&lt;br /&gt;    args.dataItem.getName() :&lt;br /&gt;    args.dataItem.name;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;becomes:&lt;/p&gt;

&lt;pre class="code"&gt;$(args.nodes).filter("li").text(&lt;br /&gt;  args.dataItem.getName ?&lt;br /&gt;    args.dataItem.getName() :&lt;br /&gt;    args.dataItem.name);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Notice how jQuery’s text method makes things a little more secure than the innerHTML we had used before.&lt;/p&gt;

&lt;p&gt;Updating the details view with the data for the item selected in the tree is done by handling the select command of the tree from the following function:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onCommand(sender, args) {
  &lt;span style="color: blue"&gt;if &lt;/span&gt;(args.get_commandName() === &lt;span style="color: maroon"&gt;&amp;quot;select&amp;quot;&lt;/span&gt;) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;dataItem = sender.findContext(&lt;br /&gt;      args.get_commandSource()).dataItem;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;isClass = Type.isClass(dataItem) &amp;amp;&amp;amp;&lt;br /&gt;                 !Type.isNamespace(dataItem);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;childData =&lt;br /&gt;      (isClass ? getMembers : getChildren)(dataItem);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;detailsChild =&lt;br /&gt;      Sys.Application.findComponent(&lt;span style="color: maroon"&gt;&amp;quot;detailsChild&amp;quot;&lt;/span&gt;);
    detailsChild.onItemRendering =&lt;br /&gt;      isClass ?&lt;br /&gt;        onClassMemberRendering :&lt;br /&gt;        onNamespaceChildRendering;
    detailsChild.onItemRendered =&lt;br /&gt;      onDetailsChildRendered;
    detailsChild.set_data(childData);
    $(&lt;span style="color: maroon"&gt;&amp;quot;#detailsTitle&amp;quot;&lt;/span&gt;).text(dataItem.getName());
    $(&lt;span style="color: maroon"&gt;&amp;quot;.namespace&amp;quot;&lt;/span&gt;).css(&lt;br /&gt;      &lt;span style="color: maroon"&gt;&amp;quot;display&amp;quot;&lt;/span&gt;,&lt;br /&gt;      isClass ? &lt;span style="color: maroon"&gt;&amp;quot;none&amp;quot; &lt;/span&gt;: &lt;span style="color: maroon"&gt;&amp;quot;block&amp;quot;&lt;/span&gt;);
    $(&lt;span style="color: maroon"&gt;&amp;quot;.class&amp;quot;&lt;/span&gt;).css(&lt;br /&gt;      &lt;span style="color: maroon"&gt;&amp;quot;display&amp;quot;&lt;/span&gt;,&lt;br /&gt;      isClass ? &lt;span style="color: maroon"&gt;&amp;quot;block&amp;quot; &lt;/span&gt;: &lt;span style="color: maroon"&gt;&amp;quot;none&amp;quot;&lt;/span&gt;);
    $(&lt;span style="color: maroon"&gt;&amp;quot;#details&amp;quot;&lt;/span&gt;).css(&lt;span style="color: maroon"&gt;&amp;quot;display&amp;quot;&lt;/span&gt;, &lt;span style="color: maroon"&gt;&amp;quot;block&amp;quot;&lt;/span&gt;);
  }
}&lt;/pre&gt;

&lt;p&gt;Not much change here from the previous version, again, except for the use of jQuery and some chaining.&lt;/p&gt;

&lt;p&gt;And that is pretty much it. I’ve made other changes in the script to make use of the new script loader in the Microsoft Ajax Library but that will be the subject of a future post.&lt;/p&gt;

&lt;p&gt;Hopefully, this has shown you how the Microsoft Ajax Library can light up with jQuery. The automatic creation of plug-ins feels very much like native jQuery plug-ins and brings all the power of client templates to jQuery. Once we have bind and setCommand plug-ins as well, the Microsoft Ajax Library may become a very useful tool to jQuery programmers just as much as jQuery itself is a very useful tool to Microsoft Ajax programmers.&lt;/p&gt;

&lt;p&gt;The code can be found here:
  &lt;br /&gt;&lt;a title="http://weblogs.asp.net/blogs/bleroy/Samples/ClassBrowserWithjQueryUpdated.zip" href="http://weblogs.asp.net/blogs/bleroy/Samples/ClassBrowserWithjQueryUpdated.zip"&gt;http://weblogs.asp.net/blogs/bleroy/Samples/ClassBrowserWithjQueryUpdated.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; fixed a problem in Firefox &amp; Chrome.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7243389" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>How to render the same template on the server and client with minimal redundancy</title><link>http://weblogs.asp.net/bleroy/archive/2009/10/19/how-to-render-the-same-template-on-the-server-and-client-with-minimal-redundancy.aspx</link><pubDate>Mon, 19 Oct 2009 08:50:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7232857</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7232857</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/10/19/how-to-render-the-same-template-on-the-server-and-client-with-minimal-redundancy.aspx#comments</comments><description>&lt;h4&gt;&lt;img style="border-right-width: 0px; margin: 0px 0px 10px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="(c) 2005 Bertrand Le Roy" border="0" alt="(c) 2005 Bertrand Le Roy" align="right" src="http://weblogs.asp.net/blogs/bleroy/buildingreflection_6007098A.jpg" width="180" height="260" /&gt; &lt;/h4&gt;  &lt;p&gt;Last week, I wrote &lt;a href="http://weblogs.asp.net/bleroy/archive/2009/10/15/entirely-unobtrusive-and-imperative-templates-with-microsoft-ajax-4-preview-6.aspx"&gt;a post about how the new Microsoft Ajax Library Preview 6 made it a lot easier to write unobtrusive and imperative data-driven applications&lt;/a&gt;. Because for the previous preview, I had written a cool little class browser using a declarative style, I thought it would be nice to rewrite this in a completely imperative way. The mistake I made though was to call it unobtrusive. Never mind that ‘unobtrusive’ is a perfectly well-defined word that actually existed way before JavaScript. ‘Unobtrusive JavaScript’ has a very specific meaning that people feel strongly about. To be worthy of that label, an application must basically conform to (at least) those two requirements:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Markup and behavior are strictly separated.&lt;/strong&gt; That means no DOM-0 event handlers, no custom attributes or tags, and even no microformats imo. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Graceful degradation / progressive enhancement.&lt;/strong&gt; This means that the application’s script is only used to improve what would work without script, in other words that the application is entirely usable without script. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;While my little sample strictly conformed to (1), it didn’t conform to (2). Not because I’m too dumb or ignorant, mind you, but because for this application, it didn’t make any sense at all: the application’s whole point is to display client-side script objects. The server does not have the first clue about the data that needs to be rendered. Which makes it impossible for anything to render without script. Which in turn triggered some unpleasant comments on the post: this was not really unobtrusive JavaScript in the full sense of the term. Not the library’s fault though, just my own for using the wrong example.&lt;/p&gt;  &lt;h4&gt;The right example&lt;/h4&gt;  &lt;p&gt;So I thought the best thing to fix this is to provide a more relevant example, one where the server could actually be a fallback scenario.&lt;/p&gt;  &lt;p&gt;The new sample code is a fairly simple master-details view on a silly data set: jedi data. We have a WCF web service that is returning a list of jedis and their associated data, which the application can render on the server-side or on the client-side.&lt;img style="border-bottom: 0px; border-left: 0px; margin: 5px auto; display: block; float: none; border-top: 0px; border-right: 0px" title="Jedis" border="0" alt="Jedis" src="http://weblogs.asp.net/blogs/bleroy/Jedis_0779A810.png" width="413" height="176" /&gt; Once you&amp;#160; have data that is available from both the server and client sides, your best and simplest tool to achieve progressive enhancement is the plain &amp;lt;a&amp;gt; tag. You can build the links in your application so that without script, they do something meaningful:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;?jedi=all&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;expandButton&amp;quot;&amp;gt;&lt;/span&gt;+&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;What you see above is the + link on the top-left of the screen that will expand the list of jedis. To make it work client-side instead of the server-side, you use script to add a click handler that suppresses the default behavior of the link and replaces it with the equivalent client-side action:&lt;/p&gt;

&lt;pre class="code"&gt;Sys.UI.DomEvent.addHandler(&lt;br /&gt;  Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#expandButton&amp;quot;&lt;/span&gt;), &lt;span style="color: maroon"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function&lt;/span&gt;(e) {
    e.preventDefault();
    jediList.fetchData();
    &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
  });&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;That’s fairly easy and has been possible since, well, I’m not sure but it’s been a looong time.&lt;/p&gt;

&lt;p&gt;Now there’s the templated rendering. Rendering the same thing from the server and the client without repeating oneself too much is not as simple. The key to it is to render the server template with an empty data item and then to use the result of that as the client template.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;jediList&amp;quot;&lt;br /&gt;&lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;if (!isDetails) { &lt;span style="background: yellow"&gt;%&amp;gt;&lt;/span&gt; &lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sys-template&amp;quot;&lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt; } &lt;span style="background: yellow"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;jedis = !isDetails ?
    &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Jedi&lt;/span&gt;&amp;gt;() {&lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Jedi&lt;/span&gt;()} :
    &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;JediService&lt;/span&gt;().GetJedis();
  &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;jedi &lt;span style="color: blue"&gt;in &lt;/span&gt;jedis) { &lt;span style="background: yellow"&gt;%&amp;gt;
&lt;/span&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;?&lt;span style="color: red"&gt;jedi&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;jedi.Name &lt;span style="background: yellow"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&amp;gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;jedi.Name&lt;span style="background: yellow"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&lt;br /&gt;      &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;} &lt;span style="background: yellow"&gt;%&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This way, there is only one template, only one version of the markup, that we are using on both the server and client sides. When rendered from the server with the actual data set, we get the list right away, and the browser just displays it (and search engines can see the list as well, something you can’t achieve with pure script). When rendered with the dummy dataset, we get the following:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;jediList&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sys-template&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;  &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;?jedi&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;all&amp;quot;&amp;gt;all&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This markup can be used as a template on the client-side by this code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;jediList = Sys.create.dataView(&lt;span style="color: maroon"&gt;&amp;quot;#jediList&amp;quot;&lt;/span&gt;, {
  dataProvider: &lt;span style="color: maroon"&gt;&amp;quot;JediService.svc&amp;quot;&lt;/span&gt;,
  fetchOperation: &lt;span style="color: maroon"&gt;&amp;quot;GetJedis&amp;quot;&lt;/span&gt;,
  autoFetch: &lt;span style="color: blue"&gt;false&lt;/span&gt;,
  itemRendered: &lt;span style="color: blue"&gt;function&lt;/span&gt;(sender, args) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;link = args.get(&lt;span style="color: maroon"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;dataItem = args.dataItem;
    link.innerHTML = dataItem.Name;
    Sys.UI.DomEvent.addHandler(&lt;br /&gt;      link, &lt;span style="color: maroon"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;function&lt;/span&gt;(e) {
        e.preventDefault();
        details.set_data(dataItem);
        &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
      });
  }
});&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The details view is built on pretty much the same principle. The main difference is that it does have additional markup to delimit the fields that we’ll want to set dynamically. Here’s how it renders with the dummy data:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;details&amp;quot;&lt;/span&gt; &lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sys-template&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;jediName&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;owns a
    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;jediLightSaber&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;lightsaber and is on the
    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;span &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;jediSide&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;span&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &lt;/span&gt;side.
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;All the itemRendered handler has to do then is fill in the blanks:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;details = Sys.create.dataView(&lt;span style="color: maroon"&gt;&amp;quot;#details&amp;quot;&lt;/span&gt;, {
  itemRendered: &lt;span style="color: blue"&gt;function&lt;/span&gt;(sender, args) {
    args.get(&lt;span style="color: maroon"&gt;&amp;quot;#jediName&amp;quot;&lt;/span&gt;).innerHTML =&lt;br /&gt;      args.dataItem.Name;
    args.get(&lt;span style="color: maroon"&gt;&amp;quot;#jediLightSaber&amp;quot;&lt;/span&gt;).innerHTML =&lt;br /&gt;      args.dataItem.LightsaberColor;
    args.get(&lt;span style="color: maroon"&gt;&amp;quot;#jediSide&amp;quot;&lt;/span&gt;).innerHTML =&lt;br /&gt;      args.dataItem.DarkSide ? &lt;span style="color: maroon"&gt;&amp;quot;dark&amp;quot; &lt;/span&gt;: &lt;span style="color: maroon"&gt;&amp;quot;light&amp;quot;&lt;/span&gt;;
  }
});&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;So what do you think?&lt;/p&gt;

&lt;p&gt;Here’s the code (by the way, I’m using the Microsoft CDN in there): 
  &lt;br /&gt;&lt;a title="http://weblogs.asp.net/blogs/bleroy/Samples/ServerClientTemplates.zip" href="http://weblogs.asp.net/blogs/bleroy/Samples/ServerClientTemplates.zip"&gt;http://weblogs.asp.net/blogs/bleroy/Samples/ServerClientTemplate.zip&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7232857" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>Entirely unobtrusive and imperative templates with Microsoft Ajax Library Preview 6</title><link>http://weblogs.asp.net/bleroy/archive/2009/10/15/entirely-unobtrusive-and-imperative-templates-with-microsoft-ajax-4-preview-6.aspx</link><pubDate>Thu, 15 Oct 2009 09:12:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7230434</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7230434</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/10/15/entirely-unobtrusive-and-imperative-templates-with-microsoft-ajax-4-preview-6.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/bleroy/IMG_2305_0DB1EDD9.jpg"&gt;&lt;img style="border-right-width: 0px; margin: 0px 0px 10px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="(c) 2009 Bertrand Le Roy" border="0" alt="(c) 2009 Bertrand Le Roy" align="right" src="http://weblogs.asp.net/blogs/bleroy/IMG_2305_thumb_138C9172.jpg" width="244" height="164" /&gt;&lt;/a&gt; Today is the release of the sixth preview of Microsoft Ajax Library. Don’t get fooled by the somewhat silly and long name: this is a major release in many ways. The scripts have been majorly refactored since preview 5. Check out the other posts out there (links at the bottom of this post) to see just some of the many new features that are in there. Some of my favorite are all the small improvements that have been made to make imperative instantiation of components and templated contents easier than ever. Many of you have told us that you preferred to do things imperatively and this release makes it a lot better.&lt;/p&gt;  &lt;p&gt;When Preview 5 came out, I built a simple class browser using the declarative syntax. The class browser shows the hierarchy of namespaces and classes in a tree view on the left side of the page, and the details of whatever’s selected in the tree on the right side of the page:&lt;a href="http://weblogs.asp.net/blogs/bleroy/ClassBrowser2_36D98617.png"&gt;&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="The JavaScript class browser" border="0" alt="The JavaScript class browser" src="http://weblogs.asp.net/blogs/bleroy/ClassBrowser2_thumb_23B8596B.png" width="504" height="187" /&gt;&lt;/a&gt;&lt;a href="http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx"&gt;http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It still works (and an updated version is attached to this post), but I thought I would demonstrate how you can take that same sample and re-implement it in a completely imperative way. Of course, you never have to go all the way one way or another, and it’s always possible for example to use the nice declarative syntax for bindings but instantiate your components imperatively if you choose to do so. In this post, I’m deliberately going imperative all the way. Just keep in mind this is rather extreme.&lt;/p&gt;  &lt;p&gt;The first thing to notice in the new version is that the markup is perfectly clean and contains no weird extension, namespace or custom binding syntax whatsoever. It’s 100% pure HTML 5. Here is for example the complete markup for the tree view on that page:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;tree&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;tree&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;nodeTemplate&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sys-template&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;toggleButton&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#&amp;quot;&amp;gt;&lt;/span&gt;+&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;treeNode&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The script that builds the dynamic contents is bootstrapped by the following code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: red"&gt;src&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Scripts/start.js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;script &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;
&lt;/span&gt;Sys.loadScripts([&amp;quot;Scr&lt;span style="color: maroon"&gt;ipts/Tree.js&amp;quot;], f&lt;/span&gt;unc&lt;span style="color: blue"&gt;tion() {
  &lt;/span&gt;Sys.require([Sys.components.dataView], function&lt;span style="color: blue"&gt;() {
    &lt;/span&gt;createTreeView(&amp;quot;#tree&amp;quot;,&lt;br /&gt;                   Typ&lt;span style="color: maroon"&gt;e.getRo&lt;/span&gt;otNamespaces(),&lt;br /&gt;                   &amp;quot;#nodeTempla&lt;span style="color: maroon"&gt;te&amp;quot;);
    &lt;/span&gt;Sys.create.dataView(&amp;quot;#detailsChild&amp;quot;, &lt;span style="color: maroon"&gt;{
      &lt;/span&gt;itemRendered: onDetailsChildRendered
    });
  });
});
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;script&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;We’re making use of the new script loader here: we first include the bootstrapper file, start.js, and then we declare that we need one custom script, “tree.js” and everything necessary to instantiate a DataView. The script loader will figure out on its own the set of scripts it needs to download for that. Once those scripts have been downloaded, we call createTreeView, which is custom code that we’ll look at in a moment that creates nested DataView controls over the markup. We also create a second DataView to display the details of what’s selected in the&amp;#160; tree.&lt;/p&gt;

&lt;p&gt;Notice that we set some properties to a selector string here (for example “#nodeTemplate”). This is actually a breaking change from the previous preview, which only understood id strings. Microsoft Ajax does not include a full selector engine but it does understand the most basic of selectors (.class, tagName and #id). But where it gets really interesting is that if you had included jQuery on the page, the framework would detect it and enable you to use full selectors everywhere. Isn’t that sweet?&lt;/p&gt;

&lt;p&gt;So how does the imperative approach compare with the declarative one? Well, for instantiating components, you already have an example above, where we use Sys.create.dataView. But what about wiring up events, setting text contents and attribute values, instantiating components over the markup inside the template?&lt;/p&gt;

&lt;p&gt;All those are done by post-processing the template instances after they’ve been instantiated, by handling the itemRendered event:&lt;/p&gt;

&lt;pre class="code"&gt;itemRendered: &lt;span style="color: blue"&gt;function&lt;/span&gt;(sender, args) {
  &lt;span style="color: #006400"&gt;// do magic
&lt;/span&gt;}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Wiring up events is as simple as getting a reference to an element and calling addHandler:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;toggleButton = args.get(&lt;span style="color: maroon"&gt;&amp;quot;.toggleButton&amp;quot;&lt;/span&gt;);
Sys.UI.DomEvent.addHandler(toggleButton, &lt;span style="color: maroon"&gt;&amp;quot;click&amp;quot;&lt;/span&gt;,&lt;br /&gt;  &lt;span style="color: blue"&gt;function&lt;/span&gt;(e) {
    toggleVisibility(&lt;span style="color: blue"&gt;this&lt;/span&gt;);
  }, &lt;span style="color: blue"&gt;true&lt;/span&gt;);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The args.get function, which you will use a lot, takes a selector and returns the first element that matches it &lt;em&gt;inside the template&lt;/em&gt;. Here, we are looking for an element with class “toggleButton”, but a local id would work just as well.&lt;/p&gt;

&lt;p&gt;To set text contents and attribute values is trivial once you know how to get references to elements from local selectors (remember, jQuery also works here transparently or even explicitly when and if you need it).&lt;/p&gt;

&lt;p&gt;Finally, instantiating components is also quite easy. For example, here is the code that creates an inner DataView for the child nodes of a node in the tree, recursively:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;childView = args.get(&lt;span style="color: maroon"&gt;&amp;quot;ul&amp;quot;&lt;/span&gt;);
createTreeView(childView,&lt;br /&gt;               getChildren(args.dataItem),&lt;br /&gt;               nodeTemplate);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The args.get funtion is used once more to get a reference to the first UL element within the template, and it is then easy to do a recursive call into our tree creation function and build the new branch of the tree.&lt;/p&gt;

&lt;p&gt;The command bubbling feature that makes it so easy to wire up custom commands into a template is still usable in imperative code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;treeNode = args.get(&lt;span style="color: maroon"&gt;&amp;quot;.treeNode&amp;quot;&lt;/span&gt;);
Sys.setCommand(treeNode, &lt;span style="color: maroon"&gt;&amp;quot;select&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Finally, there is one feature that I’m not using in that sample, but that’s immensely useful, and I’m talking of course of live bindings. Those work too, all you have to do is call the Sys.bind function and give it the target object, the name of the target property to bind, the source object and the source property name.&lt;/p&gt;

&lt;p&gt;To render the details view, I decided to not use a single item DataView like I did with the declarative version: since I’m going to use imperative code instead of declarative bindings, it is just as easy to directly manipulate the DOM that already exists, and do some hiding and showing of elements:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onCommand(sender, args) {
  &lt;span style="color: blue"&gt;if &lt;/span&gt;(args.get_commandName() === &lt;span style="color: maroon"&gt;&amp;quot;select&amp;quot;&lt;/span&gt;) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;dataItem = sender.findContext(&lt;br /&gt;      args.get_commandSource()).dataItem;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;isClass = Type.isClass(dataItem) &amp;amp;&amp;amp;&lt;br /&gt;                 !Type.isNamespace(dataItem);
    &lt;span style="color: blue"&gt;var &lt;/span&gt;childData =&lt;br /&gt;      (isClass ? getMembers : getChildren)(dataItem),
      namespaceElementsDisplay = &lt;br /&gt;        isClass ? &lt;span style="color: maroon"&gt;&amp;quot;none&amp;quot; &lt;/span&gt;: &lt;span style="color: maroon"&gt;&amp;quot;block&amp;quot;&lt;/span&gt;,
      classElementsDisplay =&lt;br /&gt;        isClass ? &lt;span style="color: maroon"&gt;&amp;quot;block&amp;quot; &lt;/span&gt;: &lt;span style="color: maroon"&gt;&amp;quot;none&amp;quot;&lt;/span&gt;,
      detailsChild =&lt;br /&gt;        Sys.Application.findComponent(&lt;span style="color: maroon"&gt;&amp;quot;detailsChild&amp;quot;&lt;/span&gt;);
    detailsChild.onItemRendering =&lt;br /&gt;      isClass ?&lt;br /&gt;        onClassMemberRendering :&lt;br /&gt;        onNamespaceChildRendering;
    detailsChild.set_data(childData);
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#detailsTitle&amp;quot;&lt;/span&gt;).innerHTML =&lt;br /&gt;      dataItem.getName();
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#namespacesColumn&amp;quot;&lt;/span&gt;).style.display =
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#classesColumn&amp;quot;&lt;/span&gt;).style.display =&lt;br /&gt;      namespaceElementsDisplay;
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#propertiesColumn&amp;quot;&lt;/span&gt;).style.display =
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#eventsColumn&amp;quot;&lt;/span&gt;).style.display =
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#methodsColumn&amp;quot;&lt;/span&gt;).style.display =
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#staticMethodsColumn&amp;quot;&lt;/span&gt;).style.display =&lt;br /&gt;      classElementsDisplay;
    Sys.get(&lt;span style="color: maroon"&gt;&amp;quot;#details&amp;quot;&lt;/span&gt;).style.display = &lt;span style="color: maroon"&gt;&amp;quot;block&amp;quot;&lt;/span&gt;;
  }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;We do have a DataView to render the contents of the currently selected object though. The nice trick we used with the declarative version to dynamically switch the target place holder where the template gets rendered is still there, which enables a single DataView control to dispatch the data into two to four separate lists (or however much you want for that matter):&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onNamespaceChildRendering(args) {
    args.set_itemPlaceholder(
        Type.isClass(args.get_dataItem()) ?
            &lt;span style="color: maroon"&gt;&amp;quot;#classPlaceHolder&amp;quot; &lt;/span&gt;:
            &lt;span style="color: maroon"&gt;&amp;quot;#namespacePlaceHolder&amp;quot;
    &lt;/span&gt;);
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;I think all this is pretty cool and I hope the comparison between the declarative version and the imperative version of this little application gives you a sense of the flexibility that the Microsoft Ajax library now offers, and of how much you can choose your own development style and do pretty much anything with the same ease.&lt;/p&gt;

&lt;p&gt;Download the code for this post here: 
  &lt;br /&gt;&lt;a title="http://weblogs.asp.net/blogs/bleroy/Samples/Preview6ClassBrowser.zip" href="http://weblogs.asp.net/blogs/bleroy/Samples/Preview6ClassBrowser.zip"&gt;http://weblogs.asp.net/blogs/bleroy/Samples/Preview6ClassBrowser.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Microsoft Ajax Library Preview 6 can be downloaded from here:
  &lt;br /&gt;&lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=34488"&gt;http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=34488&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are a few links about this release:
 &lt;br/&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2009/10/15/announcing-microsoft-ajax-library-preview-6-and-the-microsoft-ajax-minifier.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2009/10/15/announcing-microsoft-ajax-library-preview-6-and-the-microsoft-ajax-minifier.aspx&lt;/a&gt;
  &lt;br /&gt;&lt;a href="http://channel9.msdn.com/posts/jsenior/Announcing-Microsoft-Ajax-Library-Preview-6/"&gt;http://channel9.msdn.com/posts/jsenior/Announcing-Microsoft-Ajax-Library-Preview-6/&lt;/a&gt;

  &lt;br /&gt;&lt;a href="http://www.jamessenior.com/post/How-the-Script-Loader-in-the-Microsoft-Ajax-Library-will-make-your-life-wonderful.aspx"&gt;http://www.jamessenior.com/post/How-the-Script-Loader-in-the-Microsoft-Ajax-Library-will-make-your-life-wonderful.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7230434" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>HTML now a data format</title><link>http://weblogs.asp.net/bleroy/archive/2009/10/09/html-now-a-data-format.aspx</link><pubDate>Sat, 10 Oct 2009 06:54:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7226613</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7226613</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/10/09/html-now-a-data-format.aspx#comments</comments><description>&lt;p&gt;About a year ago, I asked the question on this blog whether HTML could and should be used as a data format:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/bleroy/archive/2008/11/26/should-html-be-considered-as-a-data-format.aspx"&gt;http://weblogs.asp.net/bleroy/archive/2008/11/26/should-html-be-considered-as-a-data-format.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;After all, it actually already has semantic constructs appropriate for tabular data, for collections, for hierarchical data and for object graphs of any kind.&lt;/p&gt;  &lt;p&gt;Well, apparently I wasn’t the only one to think that (not that I expected I was):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/microdata.html"&gt;http://www.whatwg.org/specs/web-apps/current-work/multipage/microdata.html&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7226613" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>Ajax Control Toolkit: new controls, bug fixes</title><link>http://weblogs.asp.net/bleroy/archive/2009/09/30/ajax-control-toolkit-new-controls-bug-fixes.aspx</link><pubDate>Thu, 01 Oct 2009 00:28:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7220674</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>15</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7220674</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/09/30/ajax-control-toolkit-new-controls-bug-fixes.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-right-width: 0px; margin: 0px 0px 10px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="(c) Bertrand Le Roy 2006" border="0" alt="(c) Bertrand Le Roy 2006" align="right" src="http://weblogs.asp.net/blogs/bleroy/101327811_c6608a9e1b_b_31770601.jpg" width="244" height="164" /&gt; And we have a new release of Ajax Control Toolkit. I didn’t work on this one but there are some nice things in there nonetheless :)&lt;/p&gt;  &lt;p&gt;First, new controls!&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;a href="http://www.asp.net/ajax/ajaxcontroltoolkit/Samples/Seadragon/Seadragon.aspx"&gt;SeaDragon&lt;/a&gt;&lt;/strong&gt;: I’ve &lt;a href="http://weblogs.asp.net/bleroy/archive/2008/11/20/deep-zoom-without-silverlight.aspx"&gt;blogged&lt;/a&gt; &lt;a href="http://weblogs.asp.net/bleroy/archive/2009/02/13/virtualalbion-using-deep-zoom-and-seadragon-ajax.aspx"&gt;before&lt;/a&gt; about &lt;a href="http://seadragon.com/"&gt;Seadragon&lt;/a&gt;, the JavaScript-only way to do &lt;a href="http://msdn.microsoft.com/en-us/library/cc645050(VS.95).aspx"&gt;Deep Zoom&lt;/a&gt;. It became a lot easier to use a few month ago when the need for tools disappeared and you can just &lt;a href="http://seadragon.com/create/"&gt;point to any image on the web&lt;/a&gt; and immediately get the &lt;a href="http://seadragon.com/view/bqy"&gt;URL&lt;/a&gt; and script tag to put on your page:&lt;/p&gt; &lt;script src="http://seadragon.com/embed/bqy.js?width=auto&amp;amp;height=400px"&gt;&lt;/script&gt;  &lt;p&gt;Now with this release of Ajax Control Toolkit, &lt;a href="http://www.asp.net/ajax/ajaxcontroltoolkit/Samples/Seadragon/Seadragon.aspx"&gt;including and controlling Deep Zoom from an ASP.NET page is also very easy&lt;/a&gt;:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ajaxToolkit&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;Seadragon &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Seadragon&amp;quot;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: red"&gt;CssClass&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;seadragon&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: red"&gt;SourceUrl&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sample.xml&amp;quot;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;James Senior just released a &lt;a href="http://channel9.msdn.com/posts/jsenior/Seadragon-Ajax-Control-Quick-Start-Guide/"&gt;screencast&lt;/a&gt; on how to create Deep Zoom contents for the new Seadragon control:

  &lt;br /&gt;&lt;a href="http://channel9.msdn.com/posts/jsenior/Seadragon-Ajax-Control-Quick-Start-Guide/"&gt;http://channel9.msdn.com/posts/jsenior/Seadragon-Ajax-Control-Quick-Start-Guide/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.asp.net/ajax/ajaxcontroltoolkit/Samples/AsyncFileUpload/AsyncFileUpload.aspx"&gt;AsyncFileUpload&lt;/a&gt;&lt;/strong&gt;: This is by far one of the most requested controls for ACT. File upload fields, while a part of HTML, do not work with Ajax/XHR requests (for security reasons, JavaScript can’t access the contents of the field). The only way to use them is to get the browser to do a real form post.&lt;/p&gt;

&lt;p&gt;This new control makes it a lot easier to handle file uploads from your Ajax applications by providing an abstraction on top of the form posting:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ajaxToolkit&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;AsyncFileUpload
    &lt;/span&gt;&lt;span style="color: red"&gt;OnClientUploadError&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;uploadError&amp;quot;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: red"&gt;OnClientUploadComplete&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;uploadComplete&amp;quot; 
    &lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;ID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;AsyncFileUpload1&amp;quot;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: red"&gt;Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;400px&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;UploaderStyle&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Modern&amp;quot; 
    &lt;/span&gt;&lt;span style="color: red"&gt;UploadingBackColor&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#CCFFFF&amp;quot;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: red"&gt;ThrobberID&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;myThrobber&amp;quot;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;It works pretty much as advertised: just drop the control on the page, and you can upload files without a full postback. It looks just like Ajax and requires no plug-in of any kind.&lt;img style="border-right-width: 0px; margin: 10px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="AsyncFileUpload" border="0" alt="AsyncFileUpload" src="http://weblogs.asp.net/blogs/bleroy/AsyncFileUpload_6D7321E9.png" width="519" height="262" /&gt; &lt;/p&gt;

&lt;p&gt;The control has client and server-side events that get triggered when the file has been uploaded. On the server-side, you have access to the uploaded file’s byte stream, which you can save to disk (or database, or whatever).&lt;/p&gt;

&lt;p&gt;Bug fixes: This release also has some new bug fixes (courtesy of &lt;a href="http://obout.com/"&gt;Obout&lt;/a&gt;) for some of the &lt;a title="Click on &amp;quot;Votes&amp;quot; on the right-side of the page to sort by votes." href="http://ajaxcontroltoolkit.codeplex.com/WorkItem/List.aspx"&gt;top-voted issues&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Download the new release here: 
  &lt;br /&gt;&lt;a href="http://ajaxcontroltoolkit.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=33804"&gt;http://ajaxcontroltoolkit.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=33804&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try the live demos here: 
  &lt;br /&gt;&lt;a href="http://www.asp.net/ajax/ajaxcontroltoolkit/samples/"&gt;http://www.asp.net/ajax/ajaxcontroltoolkit/samples/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stephen's in-depth post about this release:
&lt;br/&gt;&lt;a href="http://stephenwalther.com/blog/archive/2009/10/01/new-ajax-control-toolkit-release.aspx"&gt;http://stephenwalther.com/blog/archive/2009/10/01/new-ajax-control-toolkit-release.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7220674" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/Ajax+Control+Toolkit/default.aspx">Ajax Control Toolkit</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/CodePlex/default.aspx">CodePlex</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Deep+Zoom/default.aspx">Deep Zoom</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category></item><item><title>Fun with C# 4.0’s dynamic</title><link>http://weblogs.asp.net/bleroy/archive/2009/09/17/fun-with-c-4-0-s-dynamic.aspx</link><pubDate>Thu, 17 Sep 2009 07:50:29 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7209018</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7209018</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/09/17/fun-with-c-4-0-s-dynamic.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-right-width: 0px; margin: 0px 0px 10px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="(c) Bertrand Le Roy 2003" border="0" alt="(c) Bertrand Le Roy 2003" align="right" src="http://weblogs.asp.net/blogs/bleroy/DSCN2236Touched_14096A29.jpg" width="244" height="184" /&gt;There’s been &lt;a href="http://haacked.com/archive/2009/08/26/method-missing-csharp-4.aspx"&gt;some&lt;/a&gt; &lt;a href="http://haacked.com/archive/2009/08/31/7-stages-of-language-keyword-grief.aspx"&gt;debate&lt;/a&gt; &lt;a href="http://blog.wekeroad.com/blog/magical-dynamic-mystery-tour/"&gt;recently&lt;/a&gt; on &lt;a href="http://msdn.microsoft.com/en-us/library/dd264736(VS.100).aspx"&gt;the new “dynamic” keyword in C# 4.0&lt;/a&gt;. As has been the case with many features before it, some love it, some hate it, some say it bloats the language, yadda yadda yadda. People said that about lambdas. Me, I’ll just use it where I see a use case, thank you very much.&lt;/p&gt;  &lt;p&gt;In the case of dynamic, another frequent comment is that a statically-typed language should not try to look like a dynamic language. Well, I just don’t believe in that distinction.&lt;/p&gt;  &lt;p&gt;Being dynamic is a &lt;em&gt;trait&lt;/em&gt; that a language can have, and some have it more than others. But as soon as a language has a dictionary type or indexers, and most modern languages do, it starts having dynamicity. What people call a dynamic language is just one where it’s the only available type.&lt;/p&gt;  &lt;p&gt;Now there is type safety of course, but to me that’s a different feature that is not as coupled with “statically-typed-ness” as we usually tend to think. Case in point, many modern JavaScript engines analyze the code in order to apply many of the optimization techniques that static languages have been applying at compile-time.&lt;/p&gt;  &lt;p&gt;So just how dynamic was C# before 4.0? Well, there are dictionaries and indexers, as I’ve said, but there are also other interesting and less known features such as &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.customtypedescriptor.aspx"&gt;custom type descriptors&lt;/a&gt;. Go &lt;a href="http://msdn.microsoft.com/en-us/library/ms171819.aspx"&gt;look them up&lt;/a&gt; if you don’t know about them. Type descriptors are for example used to provide a level of indirection between a design surface and the components being edited.&lt;/p&gt;  &lt;p&gt;But type descriptors can also be built completely dynamically and decide to expose a completely virtual object model that is entirely built at runtime. Of course, the client code for that object has to go through the right APIs to make use of that quasi-dynamic model. And of course those APIs are not simple. Implementing a custom type descriptor in itself is not exactly trivial.&lt;/p&gt;  &lt;p&gt;If anything, the dynamic keyword is going to provide a friendlier syntax for this sort of thing. One problem is that it has no relationship whatsoever with custom type descriptors.&lt;/p&gt;  &lt;p&gt;So I thought I’d try to bridge that gap. How can we take a type that exposes a custom type descriptor, such as &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.datarowview.aspx"&gt;DataRowView&lt;/a&gt;, and transform that into something that plays nice with the dynamic keyword? What we want to be able to write is something like the following:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;table = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataTable&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;People&amp;quot;&lt;/span&gt;);
table.Columns.Add(&lt;span style="color: #a31515"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;));
table.Columns.Add(&lt;span style="color: #a31515"&gt;&amp;quot;LastName&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;));
table.Columns.Add(&lt;span style="color: #a31515"&gt;&amp;quot;Children&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;int&lt;/span&gt;));
table.LoadDataRow(&lt;br /&gt;    &lt;span style="color: blue"&gt;new object&lt;/span&gt;[] {&lt;span style="color: #a31515"&gt;&amp;quot;Bertrand&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;Le Roy&amp;quot;&lt;/span&gt;, 2},&lt;br /&gt;    &lt;span style="color: #2b91af"&gt;LoadOption&lt;/span&gt;.OverwriteChanges);
&lt;span style="color: blue"&gt;var &lt;/span&gt;tableView = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DataView&lt;/span&gt;(table);&lt;br /&gt;
&lt;span style="color: blue"&gt;dynamic &lt;/span&gt;dynRecord = &lt;br /&gt;    &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;TypeDescriptorDynamicWrapper&lt;/span&gt;(tableView[0]);&lt;span style="color: #2b91af"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;{0} {1} has {2} children.&amp;quot;&lt;/span&gt;, 
    dynRecord.FirstName, 
    dynRecord.LastName, 
    dynRecord.Children);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;To do that, I built the TypeDescriptorDynamicWrapper that you see being used above. What is does is pretty simple, as it just inherits from DynamicObject and implements TryGetMember as follows:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public override bool &lt;/span&gt;TryGetMember(&lt;br /&gt;    &lt;span style="color: #2b91af"&gt;GetMemberBinder &lt;/span&gt;binder, &lt;span style="color: blue"&gt;out object &lt;/span&gt;result) {&lt;br /&gt;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;name = binder.Name;
    &lt;span style="color: blue"&gt;var &lt;/span&gt;property = _properties.Find(
        p =&amp;gt; p.Name.Equals(name,
            binder.IgnoreCase ?
            &lt;span style="color: #2b91af"&gt;StringComparison&lt;/span&gt;.OrdinalIgnoreCase :
            &lt;span style="color: #2b91af"&gt;StringComparison&lt;/span&gt;.Ordinal));
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(property == &lt;span style="color: blue"&gt;null&lt;/span&gt;) {
        result = &lt;span style="color: blue"&gt;null&lt;/span&gt;;
        &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
    }
    result = property.GetValue(&lt;br /&gt;        _descriptor.GetPropertyOwner(&lt;span style="color: blue"&gt;null&lt;/span&gt;));
    &lt;span style="color: blue"&gt;return true&lt;/span&gt;;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;As you can see, the method just finds the right property on the type descriptor and delegates to it if it finds it. I didn’t implement the setting of properties but it would be fairly easy to do so.&lt;/p&gt;

&lt;p&gt;Using that simple wrapper, the program above just works and displays:&lt;/p&gt;

&lt;p style="background-color: black; font-family: courier; color: white"&gt;Bertrand Le Roy has 2 children.&lt;/p&gt;

&lt;p&gt;That was easy. Now what about the reverse, getting any dynamic object to expose a custom type descriptor?&lt;/p&gt;

&lt;p&gt;Well, that’s where things get tricky.&lt;/p&gt;

&lt;p&gt;The dynamic capabilities of C# 4.0 are targeted at two things:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Providing syntactic sugar for getting to dynamic members that looks like accessing statically-defined ones.&lt;/li&gt;

  &lt;li&gt;An easy way to create dynamic types by implementing a form of method_missing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But there is one thing that exists in &lt;a href="http://dlr.codeplex.com/"&gt;DLR&lt;/a&gt; but didn’t make it to C# yet, which is the ability to easily reflect on dynamic objects (other than by using the #1 syntactic sugar above).&lt;/p&gt;

&lt;p&gt;For example, in JavaScript, a.foo and a[“foo”] are exactly the same thing, which enables easy reflection: you can enumerate the members of an arbitrary object and do stuff like a[someStringVariable].&lt;/p&gt;

&lt;p&gt;Doing the same thing with C# on dynamic objects is much more difficult. The equivalent of a.foo is easy, but not the equivalent of a[someStringVariable].&lt;/p&gt;

&lt;p&gt;Forget about using reflection, it doesn’t work on dynamic objects because &lt;em&gt;dynamic really is a compiler trick&lt;/em&gt;. There is no such thing as a “dynamic” type to reflect on. It’s a keyword that tells the compiler to relax type-checking and generate code to access those dynamic members at runtime. If you try to reflect on an instance of one of the dynamic-friendly type, such as ExpandoObject, you’ll see the statically-defined members of that type, but not the dynamic ones. In a way, you’re looking at the messenger instead of the message.&lt;/p&gt;

&lt;p&gt;This is a problem because in order to wrap an arbitrary dynamic object into a custom type descriptor, we need to be able to reflect on the dynamic members of that object.&lt;/p&gt;

&lt;p&gt;To solve the problem, and with some help from the nice folks who are building the DLR, I compiled a simple program that sets and gets a property on a dynamic object, an then I looked at the generated code from Reflector (“luckily”, Reflector is not yet aware of dynamic and shows the generated code instead of something closer to the actual code you wrote).&lt;/p&gt;

&lt;p&gt;I was then able to refactor that code and replace the string constants for the accessed member with a method parameter, thus creating a generic way to access dynamic object properties:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public static object &lt;/span&gt;GetValue(&lt;br /&gt;    &lt;span style="color: blue"&gt;object &lt;/span&gt;dyn, &lt;span style="color: blue"&gt;string &lt;/span&gt;propName) {&lt;br /&gt;
    &lt;span style="color: green"&gt;// Warning: this is rather expensive,&lt;br /&gt;    // and should be cached in a real app
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;GetterSite = &lt;br /&gt;        &lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;&lt;br /&gt;        .Create(
          &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CSharpGetMemberBinder&lt;/span&gt;(propName,
            dyn.GetType(),
            &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CSharpArgumentInfo&lt;/span&gt;[] {
              &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CSharpArgumentInfo&lt;/span&gt;(&lt;br /&gt;                  &lt;span style="color: #2b91af"&gt;CSharpArgumentInfoFlags&lt;/span&gt;.None, &lt;span style="color: blue"&gt;null&lt;/span&gt;)
            }));
    &lt;span style="color: blue"&gt;return &lt;/span&gt;GetterSite.Target(GetterSite, dyn);
}

&lt;span style="color: blue"&gt;public static void &lt;/span&gt;SetValue(&lt;br /&gt;    &lt;span style="color: blue"&gt;object &lt;/span&gt;dyn, &lt;span style="color: blue"&gt;string &lt;/span&gt;propName, &lt;span style="color: blue"&gt;object &lt;/span&gt;val) {&lt;br /&gt;
    &lt;span style="color: green"&gt;// Warning: this is rather expensive,&lt;br /&gt;    // and should be cached in a real app
    &lt;/span&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;SetterSite = &lt;br /&gt;      &lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;CallSite&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;&lt;br /&gt;      .Create(
        &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CSharpSetMemberBinder&lt;/span&gt;(propName,
          dyn.GetType(),
          &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CSharpArgumentInfo&lt;/span&gt;[] {
            &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CSharpArgumentInfo&lt;/span&gt;(&lt;br /&gt;              &lt;span style="color: #2b91af"&gt;CSharpArgumentInfoFlags&lt;/span&gt;.None, &lt;span style="color: blue"&gt;null&lt;/span&gt;),
            &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CSharpArgumentInfo&lt;/span&gt;(&lt;br /&gt;              &lt;span style="color: #2b91af"&gt;CSharpArgumentInfoFlags&lt;/span&gt;.LiteralConstant |
              &lt;span style="color: #2b91af"&gt;CSharpArgumentInfoFlags&lt;/span&gt;.UseCompileTimeType,&lt;br /&gt;              &lt;span style="color: blue"&gt;null&lt;/span&gt;)
          }));
    SetterSite.Target(SetterSite, dyn, val);
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Once we have that, implementing the custom type provider is relatively straightforward. The only part that is not immediately obvious is how to enumerate the properties of the dynamic object.&lt;/p&gt;

&lt;p&gt;This is done as follows. Dynamic objects implement &lt;a href="http://msdn.microsoft.com/en-us/library/system.dynamic.idynamicmetaobjectprovider(VS.100).aspx"&gt;IDynamicMetaObjetProvider&lt;/a&gt;, which has a &lt;a href="http://msdn.microsoft.com/en-us/library/system.dynamic.idynamicmetaobjectprovider.getmetaobject(VS.100).aspx"&gt;GetMetaObject&lt;/a&gt; method, which returns a &lt;a href="http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicmetaobject(VS.100).aspx"&gt;DynamicMetaObject&lt;/a&gt; object on which you can call &lt;a href="http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicmetaobject.getdynamicmembernames(VS.100).aspx"&gt;GetDynamicMemberNames&lt;/a&gt; to get the list of members.&lt;/p&gt;

&lt;p&gt;We can now take any dynamic object and for example present it in a property grid, which is one of those components that know how to handle custom type descriptors but not the new dynamic objects:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;dynamic &lt;/span&gt;person = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ExpandoObject&lt;/span&gt;();
person.FirstName = &lt;span style="color: #a31515"&gt;&amp;quot;Bertrand&amp;quot;&lt;/span&gt;;
person.LastName = &lt;span style="color: #a31515"&gt;&amp;quot;Le Roy&amp;quot;&lt;/span&gt;;
person.Children = 2;
propertyGrid1.SelectedObject = &lt;br /&gt;    &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DynamicTypeDescriptorWrapper&lt;/span&gt;(person);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;And here’s what the results look like:&lt;img style="border-bottom: 0px; border-left: 0px; margin: 10px auto; display: block; float: none; border-top: 0px; border-right: 0px" title="PropertyGrid displaying a dynamic object." border="0" alt="PropertyGrid displaying a dynamic object." src="http://weblogs.asp.net/blogs/bleroy/DynamicPropertyGrid_5E24750E.png" width="304" height="207" /&gt; &lt;/p&gt;

&lt;p&gt;In conclusion, I’d say that although we are having a healthy debate on the dynamic keyword (and we should have that debate), I’m confident that in one or two years, we’ll have some incredibly imaginative uses of the feature that will simply blow us away and will make the current conversation a little sillier than it seems today. The feature itself is also in its infancy and not only will the use cases emerge way beyond what even its designers envisioned, it will also grow and become more usable with future versions of the language, as is made clear by the gap in functionality that still exists today with the full DLR project.&lt;/p&gt;

&lt;p&gt;You can download the code for this article here:
  &lt;br /&gt;&lt;a title="http://weblogs.asp.net/blogs/bleroy/Samples/Bleroy.Sample.Dynamic.zip" href="http://weblogs.asp.net/blogs/bleroy/Samples/Bleroy.Sample.Dynamic.zip"&gt;http://weblogs.asp.net/blogs/bleroy/Samples/Bleroy.Sample.Dynamic.zip&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7209018" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/.NET/default.aspx">.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Dynamic+languages/default.aspx">Dynamic languages</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category></item><item><title>Building a class browser with Microsoft Ajax 4.0 Preview 5</title><link>http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx</link><pubDate>Mon, 14 Sep 2009 07:29:37 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7204694</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7204694</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/09/14/building-a-class-browser-with-microsoft-ajax-4-0-preview-5.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 10px 10px; display: inline; border-top: 0px; border-right: 0px" title="(c) 2004 Bertrand Le Roy" border="0" alt="(c) 2004 Bertrand Le Roy" align="right" src="http://weblogs.asp.net/blogs/bleroy/DSCN3593_4CCCACF9.jpg" width="184" height="244" /&gt; The Microsoft Ajax Library 4.0 Preview 5 is the first release of Microsoft Ajax that I didn’t participate in: I left the team a few months ago. But that doesn’t mean I don’t love what’s in there, and I really do. And by the way I’ve also seen what’s in Preview 6 too and man that will seriously rock.&lt;/p&gt;  &lt;p&gt;So I thought I’d write a little something to celebrate the new preview. The new features include recursive templates, which is pretty much begging us to implement a treeview with it, and we’ll do just that in this post.&lt;/p&gt;  &lt;p&gt;There is also an intriguing capability, which enables you to dynamically set what template to render for each data item, and where to render it. At first, this doesn’t look like the most useful thing in the world, but it actually opens up some very interesting possibilities, which we’ll also show in this post.&lt;/p&gt;  &lt;p&gt;The sample code that I’m going to write for this post is a rudimentary class browser. It will render a treeview representing the hierarchical structure of namespaces and classes in Microsoft Ajax, and clicking one of the tree nodes will render a details view for it: a list of classes and subnamespaces for namespaces, and a grouped list of members for classes.&lt;/p&gt;  &lt;p&gt;Let’s start with the tree. It will be rendered as nested unordered lists by a simple recursive DataView:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;tree&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;tree&amp;quot;
    &lt;/span&gt;&lt;span style="color: red"&gt;sys&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;attach&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;dataview&amp;quot;
    &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;data&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{{ Type.getRootNamespaces() }}&amp;quot;
    &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;itemtemplate&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;nodeTemplate&amp;quot;
    &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;oncommand&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{{ onCommand }}&amp;quot;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;nodeTemplate&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sys-template&amp;quot;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;onclick&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;return false;&amp;quot;
       &lt;/span&gt;&lt;span style="color: red"&gt;sys&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;command&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;select&amp;quot;&amp;gt;
      &lt;/span&gt;{{ getSimpleName($dataItem.getName()) }}
    &lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;sys&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;attach&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;dataview&amp;quot;
        &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;data&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{{ getChildren($dataItem) }}&amp;quot;
        &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;itemtemplate&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;nodeTemplate&amp;quot;
        &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;oncommand&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{{ onCommand }}&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;On the first UL, which is the outer DataView for the tree, you can see that we set the data property to Type.getRootNamespaces(), which returns the set of root namespaces currently defined.&lt;/p&gt;

&lt;p&gt;We also set the template to point to the “nodeTemplate” element, which has to be outside the DataView itself when doing recursive templates. Note that the outer node of the template, the UL, won’t actually get rendered into the target ul (tree). It is only a container.&lt;/p&gt;

&lt;p&gt;The command event of the DataView is hooked to the onCommand function, and we’ll get back to that when we couple the tree with the detail view.&lt;/p&gt;

&lt;p&gt;In the template itself, you can see we have a link with the select command so that clicking it will trigger the nearest onCommand event up the DOM.&lt;/p&gt;

&lt;p&gt;The text of that link is the results of a call to getSimpleName, which will extract the last part of the fully-qualified name of the namespace or class.&lt;/p&gt;

&lt;p&gt;After that link, we find another DataView control. The data property of that control points to an array of namespaces and classes under the current object. But the nice part here is that the template property points to “nodeTemplate”, its own parent, enabling the recursive nature of the tree.&lt;/p&gt;

&lt;p&gt;In other words, we’ve morphed a simple DataView control into a tree, with minimal effort and code.&lt;/p&gt;

&lt;p&gt;There is just one thing missing to the tree, and that is the +/- buttons that will collapse and expand the tree nodes. This is actually very easy to set-up using CSS and some simple script. First, let’s collapse the tree by default. This is done by defining the style of the tree as follows in our stylesheet:&lt;/p&gt;

&lt;pre class="code"&gt;.tree ul 
{
    padding: 0;
    display:none;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This has the effect of collapsing all unordered list nodes under the tree.&lt;/p&gt;

&lt;p&gt;The +/- button is created by adding the following to the template, right before the existing link:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;a &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;toggleButton&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;#&amp;quot;
   &lt;/span&gt;&lt;span style="color: red"&gt;sys&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;if&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;Type.isNamespace($dataItem)&amp;quot; 
   &lt;/span&gt;&lt;span style="color: red"&gt;onclick&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;return toggleVisibility(this);&amp;quot;&amp;gt;&lt;/span&gt;+&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The button is a simple link whose rendering is conditioned by whether the current data item is a namespace: only namespaces can be expanded, classes are leaf nodes.&lt;/p&gt;

&lt;p&gt;The toggling function itself is fairly simple:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;toggleVisibility(element) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;childList = element.parentNode&lt;br /&gt;                     .getElementsByTagName(&lt;span style="color: maroon"&gt;&amp;quot;ul&amp;quot;&lt;/span&gt;)[0],
        isClosed = element.innerHTML === &lt;span style="color: maroon"&gt;&amp;quot;+&amp;quot;&lt;/span&gt;;
    childList.style.display =&lt;br /&gt;        isClosed ? &lt;span style="color: maroon"&gt;&amp;quot;block&amp;quot; &lt;/span&gt;: &lt;span style="color: maroon"&gt;&amp;quot;none&amp;quot;&lt;/span&gt;;
    element.innerHTML = isClosed ? &lt;span style="color: maroon"&gt;&amp;quot;-&amp;quot; &lt;/span&gt;: &lt;span style="color: maroon"&gt;&amp;quot;+&amp;quot;&lt;/span&gt;;
    &lt;span style="color: blue"&gt;return false&lt;/span&gt;;
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This just toggles the display style of the first child UL between none and block, and the text of the link between + and –.&lt;/p&gt;

&lt;p&gt;So there it is, we have built a simple tree by simply making use of the recursive capabilities of DataView and some very simple script.&lt;/p&gt;

&lt;p&gt;Before we look at the details view, let’s look at the code that gets called when the user selects a node in the tree:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onCommand(sender, args) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;dataItem = sender.findContext(&lt;br /&gt;        args.get_commandSource()).dataItem;
    $find(&lt;span style="color: maroon"&gt;&amp;quot;details&amp;quot;&lt;/span&gt;).set_data(dataItem);
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;That code gets a reference to the data item for the selected node from the template context that we can get from the sender of the event (the inner DataView that contains the selected node) using the command source as provided by the event arguments (that source is the element that triggered the command). We can then set the data of the details DataView to that data item, which will trigger that view to re-render.&lt;/p&gt;

&lt;p&gt;Now let’s build the details view. The details view will display the child namespaces and classes if a namespace is selected in the tree, and the properties, events and methods (instance and static) in the case of a class.&lt;/p&gt;

&lt;p&gt;For each case, we’ll use a different template: “namespaceTemplate” for namespaces, and “classTemplate” for classes,&amp;#160; but we’ll do so from the same DataView. This dynamic template switching is done by handling the onItemRendering event of the DataView:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onDetailsRendering(sender, args) {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;dataItem = args.get_dataItem();
    args.set_itemTemplate(Type.isNamespace(dataItem) ?
        &lt;span style="color: maroon"&gt;&amp;quot;namespaceTemplate&amp;quot;&lt;/span&gt; : &lt;span style="color: maroon"&gt;&amp;quot;classTemplate&amp;quot;&lt;/span&gt;);
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This code gets the data item from the event arguments and sets the itemTemplate property depending on its type.&lt;/p&gt;

&lt;p&gt;Each of these two templates will have to display the contents of the selected object. But, and that will be the tricky part, we want all those to be neatly grouped into separated lists.&lt;/p&gt;

&lt;p&gt;One way to do that would be to have one DataView per list but where would the fun be in that? Here, we are going to enumerate only once through the data items to display and dispatch them dynamically to this or that placeholder depending on their nature.&lt;/p&gt;

&lt;p&gt;Once more, the key to doing that will be handling the onItemRendering event:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;function &lt;/span&gt;onNamespaceChildRendering(sender, args) {
    &lt;span style="color: blue"&gt;if &lt;/span&gt;(Type.isClass(args.get_dataItem())) {
        args.set_itemPlaceholder(&lt;span style="color: maroon"&gt;&amp;quot;classPlaceHolder&amp;quot;&lt;/span&gt;);
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This code is simply changing the rendering place holder for the curent item from the default (the DataView’s element) to “classPlaceHolder” if the current data item is a class (instead of a namespace). The template itself looks like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;namespaceTemplate&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sys-template&amp;quot;&amp;gt;
   &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;{{ $dataItem.getName() }}&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;h1&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
   &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;column&amp;quot;&amp;gt;
     &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;h2&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Namespaces:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;h2&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
     &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;sys&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;namespacePlaceHolder&amp;quot;
         &lt;/span&gt;&lt;span style="color: red"&gt;sys&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;attach&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;dataview&amp;quot;
         &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;data&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{{ getChildren($dataItem) }}&amp;quot;
         &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;itemtemplate&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;namespaceChildTemplate&amp;quot;
         &lt;/span&gt;&lt;span style="color: red"&gt;dataview&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;onitemrendering&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;br /&gt;           &amp;quot;{{ onNamespaceChildRendering }}&amp;quot;&amp;gt;
     &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
   &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
   &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;div &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;column&amp;quot;&amp;gt;
   &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;h2&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Classes:&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;h2&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
     &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li &lt;/span&gt;&lt;span style="color: red"&gt;sys&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;classPlaceHolder&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
   &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;div&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;ul &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;namespaceChildTemplate&amp;quot; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;sys-template&amp;quot;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;{{ $dataItem.getName() }}&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;li&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;ul&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;As you can see, there really is only one DataView in there, and thanks to the code above, it can dispatch its rendering to different places if necessary. The template for the items of that DataView happens to be the same in all cases (namespaceChildTemplate) but it could be easily different, as it was for the parent details view.&lt;/p&gt;

&lt;p&gt;The template for displaying classes is essentially the same thing, but with four placeholders instead of two.&lt;/p&gt;

&lt;p&gt;So here’s what it looks like in the end:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/bleroy/ClassBrowser_5CC62533.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="Class Browser" border="0" alt="Class Browser" src="http://weblogs.asp.net/blogs/bleroy/ClassBrowser_thumb_70730EC7.png" width="504" height="172" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key takeaways&lt;/strong&gt; of this post are that it’s now super-easy to render hierarchical data structures with DataView, and that you can do some interesting grouping of data on the fly by handling the item rendering event.&lt;/p&gt;

&lt;p&gt;You can play with the class browser live here:
  &lt;br /&gt;&lt;a href="http://boudin.vndv.com/AjaxPreview5Tree/default.htm"&gt;http://boudin.vndv.com/AjaxPreview5Tree/default.htm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And you can download the code here:
  &lt;br /&gt;&lt;a title="http://weblogs.asp.net/blogs/bleroy/Samples/AjaxPreview5Tree.zip" href="http://weblogs.asp.net/blogs/bleroy/Samples/AjaxPreview5Tree.zip"&gt;http://weblogs.asp.net/blogs/bleroy/Samples/AjaxPreview5Tree.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Microsoft Ajax 4.0 Preview 5:
  &lt;br /&gt;&lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=32770"&gt;http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=32770&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Jim and Dave’s posts on Preview 5:
  &lt;br /&gt;&lt;a href="http://weblogs.asp.net/jimwang/archive/2009/09/11/asp-net-ajax-preview-5-and-updatepanel.aspx"&gt;http://weblogs.asp.net/jimwang/archive/2009/09/11/asp-net-ajax-preview-5-and-updatepanel.aspx&lt;/a&gt;

  &lt;br /&gt;&lt;a href="http://weblogs.asp.net/infinitiesloop/archive/2009/09/10/microsoft-ajax-4-preview-5-the-dataview-control.aspx"&gt;http://weblogs.asp.net/infinitiesloop/archive/2009/09/10/microsoft-ajax-4-preview-5-the-dataview-control.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7204694" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category></item><item><title>querySelectorAll on old IE versions: something that doesn’t work</title><link>http://weblogs.asp.net/bleroy/archive/2009/08/31/queryselectorall-on-old-ie-versions-something-that-doesn-t-work.aspx</link><pubDate>Tue, 01 Sep 2009 01:03:13 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7187174</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7187174</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/08/31/queryselectorall-on-old-ie-versions-something-that-doesn-t-work.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 10px 10px; display: inline; border-top: 0px; border-right: 0px" title="(c) Bertrand Le Roy 2005" border="0" alt="(c) Bertrand Le Roy 2005" align="right" src="http://weblogs.asp.net/blogs/bleroy/WallDoor_7CF5A223.jpg" width="224" height="244" /&gt; In today’s post, I’m going to show an interesting technique to solve a problem and then I will tear it to pieces and explain why it is actually useless. I believe that negative results should also be published so that we can save other people from wasting time trying the same thing. So here goes…&lt;/p&gt;  &lt;p&gt;A few days ago, &lt;a href="http://ajaxian.com/archives/creating-a-queryselector-for-ie-that-runs-at-native-speed"&gt;a post on Ajaxian&lt;/a&gt; proposed a new version of a somewhat old technique to implement &lt;a href="http://www.w3.org/TR/2007/WD-selectors-api-20071221/"&gt;querySelectorAll&lt;/a&gt; on old versions of IE, using the browser’s native CSS engine. That sounds like a great idea at first, and the hack is quite clever. The idea is to dynamically add a CSS rule to the document that has the selector that you want to evaluate, and an expression that adds the matched elements to a global array.&lt;/p&gt;  &lt;p&gt;When I read this, it reminded me of a similar approach that I had tried a few years ago. At the time, we were considering implementing our own selector engine (we had not yet decided to integrate jQuery to our Ajax offerings, which in the end made the whole effort moot) so we explored a number of approaches.&lt;/p&gt;  &lt;p&gt;My idea was different in that it doesn’t use expressions at all. It does dynamically create a style rule, but instead of an expression, it just sets a non-existing “foo” style property to the equally arbitrary value of “bar”. It then scans the whole document (using the much decried and IE-specific but very fast document.all) and gets the computed style for each of the elements. We then look for the foo property on the resulting object and check whether it evaluates as “bar”. For each element that matches, we add to an array.&lt;/p&gt;  &lt;p&gt;Here’s the code:&lt;/p&gt;  &lt;pre class="code"&gt;(&lt;span style="color: blue"&gt;function&lt;/span&gt;() {
    &lt;span style="color: blue"&gt;var &lt;/span&gt;style = document.styleSheets[0] ||&lt;br /&gt;                document.createStyleSheet();
    window.select = &lt;span style="color: blue"&gt;function&lt;/span&gt;(selector) {
        style.addRule(selector, &lt;span style="color: #a31515"&gt;&amp;quot;foo:bar&amp;quot;&lt;/span&gt;);
        &lt;span style="color: blue"&gt;var &lt;/span&gt;all = document.all, resultSet = [];
        &lt;span style="color: blue"&gt;for &lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;i = 0, l = all.length; i &amp;lt; l; i++) {
            &lt;span style="color: blue"&gt;if &lt;/span&gt;(all[i].currentStyle.foo === &lt;span style="color: #a31515"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;) {
                resultSet[resultSet.length] = all[i];
            }
        }
        style.removeRule(0);
        &lt;span style="color: blue"&gt;return &lt;/span&gt;resultSet;
    }
})();&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;or, in minimized form:&lt;/p&gt;

&lt;pre class="code"&gt;(&lt;span style="color: blue"&gt;function&lt;/span&gt;(){&lt;span style="color: blue"&gt;var &lt;/span&gt;d=document;&lt;span style="color: blue"&gt;var &lt;/span&gt;a=d.styleSheets[0]||&lt;br /&gt;d.createStyleSheet();window.select=&lt;span style="color: blue"&gt;function&lt;/span&gt;(e){&lt;br /&gt;a.addRule(e,&lt;span style="color: #a31515"&gt;&amp;quot;f:b&amp;quot;&lt;/span&gt;);&lt;span style="color: blue"&gt;var &lt;/span&gt;l=d.all,c=[];&lt;br /&gt;&lt;span style="color: blue"&gt;for&lt;/span&gt;(&lt;span style="color: blue"&gt;var &lt;/span&gt;b=0,f=l.length;b&amp;lt;f;b++)&lt;span style="color: blue"&gt;if&lt;/span&gt;(l[b].currentStyle.f)&lt;br /&gt;c[c.length]=l[b];a.removeRule(0);&lt;span style="color: blue"&gt;return &lt;/span&gt;c}})()&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;That’s 235 characters, which is not too bad (although not quite #twitcode small).&lt;/p&gt;

&lt;p&gt;The first problem with that approach though is that because it’s using the native CSS selection engine in IE, it has the same limitations and quirks. That means no fancy CSS 3 (or even 2) selectors. It also means any IE bug will surface into the result set.&lt;/p&gt;

&lt;p&gt;In other words, if you want more selectors than that, you will need to parse the selector string and branch off the code to another, more complete engine whenever something not supported is used. It also means that you need to know what is supported and what isn’t. That could be done through some dynamic discovery but doing so, we are getting into much complexity.&lt;/p&gt;

&lt;p&gt;So limited as it is, how does it perform?&lt;/p&gt;

&lt;p&gt;I ran the code in a &lt;a href="http://code.google.com/p/slickspeed/"&gt;SlickSpeed&lt;/a&gt; test (where I removed the selectors that it couldn’t handle) on IE6 and the good news is that despite the document.all scan and the current style computation, it’s more than three times faster than &lt;a href="http://ajaxian.com/archives/creating-a-queryselector-for-ie-that-runs-at-native-speed"&gt;Paul Young’s implementation that got featured on Ajaxian&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But the bad news is that it’s also &lt;strong&gt;six times slower than jQuery:&lt;img style="border-bottom: 0px; border-left: 0px; margin: 5px auto; display: block; float: none; border-top: 0px; border-right: 0px" title="SlickSpeedResults" border="0" alt="SlickSpeedResults" src="http://weblogs.asp.net/blogs/bleroy/SlickSpeedResults_62B538FF.png" width="540" height="484" /&gt; &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I’m afraid a hack to use the native CSS selection engine of the browser is always going to be slower than an optimized pure JavaScript implementation (to be clear, I’m not talking about native implementations of querySelectorAll, but about hacks such as this which try to surface the feature on older IE versions that don’t have querySelectorAll). Somewhat counter-intuitive, but true.&lt;/p&gt;

&lt;p&gt;End of story. Just use jQuery. :)&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7187174" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/CSS/default.aspx">CSS</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/TwitCode/default.aspx">TwitCode</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Internet+Explorer/default.aspx">Internet Explorer</category></item><item><title>How to install and configure Visual Studio Team Explorer</title><link>http://weblogs.asp.net/bleroy/archive/2009/08/28/how-to-install-and-configure-visual-studio-team-explorer.aspx</link><pubDate>Fri, 28 Aug 2009 21:24:04 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7184437</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7184437</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/08/28/how-to-install-and-configure-visual-studio-team-explorer.aspx#comments</comments><description>&lt;p&gt;One of the challenging aspects of working with TFS as your source control system is very unfortunately the installation of the client software.&lt;/p&gt;  &lt;p&gt;Over the past few years, I’ve been managing a number of &lt;a href="http://photohandler.codeplex.com/"&gt;small&lt;/a&gt; and &lt;a href="http://ajaxcontroltoolkit.codeplex.com/"&gt;large&lt;/a&gt; projects on CodePlex, and while the &lt;a href="http://codeplex.codeplex.com/Wiki/View.aspx?title=Using%20TortoiseSVN%20with%20CodePlex&amp;amp;referringTitle=Source%20control%20clients"&gt;Subversion bridge&lt;/a&gt; has provided a much needed simple choice of client software, &lt;a href="http://codeplex.codeplex.com/Wiki/View.aspx?title=Obtaining%20the%20Team%20Explorer%20Client&amp;amp;referringTitle=CodePlex%20FAQ"&gt;TFS remains its native protocol&lt;/a&gt;, which makes it still very much relevant to people who do a lot of work there.&lt;/p&gt;  &lt;p&gt;But as I said, &lt;a href="http://codeplex.codeplex.com/Wiki/View.aspx?title=Installing%20Team%20Explorer&amp;amp;referringTitle=Source%20control%20clients"&gt;installing the client software may be challenging&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The first and main problem here is that Team Explorer, while free, comes in a very unfriendly format: an ISO image of the DVD. I asked the team why they made that weird and less than optimal choice, and apparently there are some technical reasons why a simple msi wouldn’t work. I wasn’t completely satisfied with the explanation (it’s still a bad customer experience) but at least there is hope as the plan is to make it a lot smoother with Visual Studio 2010.&lt;/p&gt;  &lt;p&gt;So let’s download that thing. It can be found here:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=0ed12659-3d41-4420-bbb0-a46e51bfca86&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?familyid=0ed12659-3d41-4420-bbb0-a46e51bfca86&amp;amp;displaylang=en&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Just click on the “Download” button and store the file in a local temporary folder. At 387.4 MB it’s a pretty big download (especially when compared with &lt;a href="http://tortoisesvn.net/downloads"&gt;this&lt;/a&gt;) but it does contain the Visual Studio shell, which explains it, kind of. So you probably have time for a cup of coffee or two, trip to Seattle’s Best included.&lt;/p&gt;  &lt;p&gt;Oh, by the way, to be clear, you do &lt;strong&gt;*not*&lt;/strong&gt; need a version of Visual Studio on the box to install Team Explorer, it is a standalone application, but if you do have one, it will integrate with it.&lt;/p&gt;  &lt;p&gt;Now that you have the IMG file, we can extract it. There are several options to extract or burn an ISO, but I’ll use a free one here. We won’t burn the image to a DVD (the only reason I could see why you’d want to do that is if you want to make multiple installs, but you might as well extract the ISO to a network share).&lt;/p&gt;  &lt;p&gt;The free option I’ve selected is ExtractNow, which you can download from here:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.extractnow.com/"&gt;http://www.extractnow.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Click on the “Download ExtractNow!” link on the bottom of the page and run the installer. When it asks you if you want to run it, say yes. The UI is a little weird: what you need to do now is right click on the white surface on the ExtractNow window and select “Add archive”:&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ExtractNow Add Archive" border="0" alt="ExtractNow Add Archive" src="http://weblogs.asp.net/blogs/bleroy/ExtractNowAddArchive_27011293.png" width="423" height="381" /&gt;Then, navigate to wherever you downloaded the VS2008TeamExplorer.iso file, select it and click the “Open” button. Now click the “Extract” button and wait for the extraction to complete. You should now have a VS2008TeamExplorer folder next to the iso file. You can close ExtractNow and maybe even uninstall it until the next time you need it…&lt;/p&gt;  &lt;p&gt;Open that folder and double-click “Setup”. Follow the instructions (the default settings should be fine) and wait for the install to complete. Fortunately, it doesn’t take nearly as long as installing the full VS.&lt;/p&gt;  &lt;p&gt;Once this is done, you should be up and running. Let’s launch the shell and connect to a CodePlex project. From the Team Explorer window, click the “Add existing team project button:&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Team Explorer Add Existing Project" border="0" alt="Team Explorer Add Existing Project" src="http://weblogs.asp.net/blogs/bleroy/TeamExplorerAdd_51F90098.png" width="139" height="114" /&gt; &lt;/p&gt;  &lt;p&gt;Click on the “Servers” button and then on the “Add” button to add the relevant CodePlex server. The data that you need to enter there can be found on the “Source Code” tab of your project’s site on CodePlex by clicking on Source Control Setup / Visual Studio Team Explorer (right side of the page).&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="CodePlex Project Setup" border="0" alt="CodePlex Project Setup" src="http://weblogs.asp.net/blogs/bleroy/CodePlexProjectSetup_51209AAE.png" width="481" height="149" /&gt; &lt;/p&gt;  &lt;p&gt;You can copy the server, port and protocol information into the Team Explorer add server window:&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Team Explorer Add Server" border="0" alt="Team Explorer Add Server" src="http://weblogs.asp.net/blogs/bleroy/TFSProjectSetup_54528296.png" width="509" height="312" /&gt; &lt;/p&gt;  &lt;p&gt;You can now close that window by clicking OK. You will then get prompted for your username and password. CodePlex also gave you that (notice the “snd\” domain prefix and “_cp” postfix) but let’s make sure that we only have to do this once. To that effect, let’s cancel and go to the Windows user account control panel and click on “Manage your credentials”:&lt;img style="border-bottom: 0px; border-left: 0px; margin: 5px auto; display: block; float: none; border-top: 0px; border-right: 0px" title="User Account Control Panel" border="0" alt="User Account Control Panel" src="http://weblogs.asp.net/blogs/bleroy/ManageYourCredentials_4F039BE5.png" width="509" height="198" /&gt; &lt;/p&gt;  &lt;p&gt;Then click on “Add a Windows Credential”. Copy there the server name, your username and your password:&lt;img style="border-bottom: 0px; border-left: 0px; margin: 5px auto; display: block; float: none; border-top: 0px; border-right: 0px" title="Windows New Credentials" border="0" alt="Windows New Credentials" src="http://weblogs.asp.net/blogs/bleroy/WindowsNewCredentials_1193375E.png" width="509" height="269" /&gt; &lt;/p&gt;  &lt;p&gt;Click OK, then switch back to Visual Studio and click OK again. This time, you shouldn’t be prompted for credentials unless you made a typo in the above dialog. You may now click close and then select any number of projects you want to work with:&lt;img style="border-bottom: 0px; border-left: 0px; margin: 5px auto; display: block; float: none; border-top: 0px; border-right: 0px" title="TFS Select Projects" border="0" alt="TFS Select Projects" src="http://weblogs.asp.net/blogs/bleroy/TfsSelectProjects_6BBD10FA.png" width="509" height="480" /&gt; &lt;/p&gt;  &lt;p&gt;The team explorer window now shows the available projects:&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Team Explorer Window" border="0" alt="Team Explorer Window" src="http://weblogs.asp.net/blogs/bleroy/TeamExplorerWindow_0DC56CC1.png" width="206" height="324" /&gt; &lt;/p&gt;  &lt;p&gt;If you then double-click “Source Control” under any of the projects, you can explore the contents of the project and map them to a local folder. To do that, first create the target directory from Windows Explorer, then right click a project in the Visual Studio Source Control Explorer and select “Get Latest Version”:&lt;img style="border-right-width: 0px; margin: 5px auto; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Getting Latest Version" border="0" alt="Getting Latest Version" src="http://weblogs.asp.net/blogs/bleroy/GettingLatestVersion_4CB6ED5C.png" width="484" height="321" /&gt; &lt;/p&gt;  &lt;p&gt;You will then be prompted for a local directory to which you want to map the source-controlled remote directory. Select the directory that you just created and click OK.&lt;/p&gt;  &lt;p&gt;And… that’s it, you’re all set. You can now open any file or project from the locally mapped folder, check out code, modify it and then check it back in using the Pending Changes window.&lt;/p&gt;  &lt;p&gt;I hope this helps.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7184437" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/CodePlex/default.aspx">CodePlex</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/TFS/default.aspx">TFS</category></item><item><title>Walking the tight rope</title><link>http://weblogs.asp.net/bleroy/archive/2009/08/27/walking-the-tight-rope.aspx</link><pubDate>Thu, 27 Aug 2009 22:40:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7183436</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7183436</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/08/27/walking-the-tight-rope.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 10px 10px 0px; display: inline; border-top: 0px; border-right: 0px" title="(c) Bertrand Le Roy 2004" border="0" alt="(c) Bertrand Le Roy 2004" align="left" src="http://weblogs.asp.net/blogs/bleroy/MaxetGogo010_15869DD0.jpg" width="244" height="184" /&gt; I think today is an appropriate time to write this post, as &lt;a href="http://blog.wekeroad.com/"&gt;Rob Conery&lt;/a&gt; is &lt;a href="http://blog.wekeroad.com/blog/temet-nosce/"&gt;leaving Microsoft tomorrow&lt;/a&gt;. “Who?”, you might ask. Rob is the author of the excellent &lt;a href="http://blog.wekeroad.com/category/mvc-storefront/"&gt;MVC Storefront&lt;/a&gt; and &lt;a href="http://blog.wekeroad.com/category/kona/"&gt;Kona&lt;/a&gt; series where he explored the challenges in building an MVC-bound storefront application. I’ve been working with Rob for a few months on the continuation of that, which will be the subject of this post.&lt;/p&gt;  &lt;p&gt;This is challenging for a number of reasons.&lt;/p&gt;  &lt;p&gt;First, Rob’s are large shoes to fill (he’s a 12, I’m an 11). That’s fine, I’m just going to do things my way and try to have as much fun as possible (and communicate that if I can).&lt;/p&gt;  &lt;p&gt;Second, the focus of the application has changed and that is a much more important challenge. Rob built this as a learning tool, as much for him as for his readers.&lt;/p&gt;  &lt;p&gt;In the team that I’m now a part of, we have taken that Kona code as the basis to build something that will hopefully be more like a real world application. We are still very much in an exploratory mode (hence our attempts at &lt;a href="http://weblogs.asp.net/bleroy/archive/tags/NHibernate/default.aspx"&gt;migrating the application to NHibernate&lt;/a&gt; and SQLite) but our ultimate goal is to provide an application that people can download and build a business on, with a &lt;a href="http://blog.wekeroad.com/mvc-storefront/kona-1/"&gt;focus on simplicity and extensibility&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Fine, you may say, but why build something new instead of contributing to existing applications? Well, the very short answer is that we are also going to do that. One of the things we are already doing is to work with various application developers on reusing things like the plug-in engine and what sharing opportunities that brings.&lt;/p&gt;  &lt;p&gt;But I can already hear some of you saying “oh so you’re not just building an application, what you’re really doing is building yet another framework”. To which I’m tempted to answer with another question: what do you mean “another”? Where is my Django-style application-level framework for ASP.NET? But that may sound like I’m downplaying the great efforts that many people are putting towards exactly that. I clearly am not. Actually, if you are working on something like that and we’re not already talking, I would love to know about it. I want to know how we can help.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7183436" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Kona/default.aspx">Kona</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/MVC/default.aspx">MVC</category></item><item><title>A total n00b’s guide to migrating from a custom data layer to Nhibernate: so many choices</title><link>http://weblogs.asp.net/bleroy/archive/2009/08/20/a-total-n00b-s-guide-to-migrating-from-a-custom-data-layer-to-nhibernate-so-many-choices.aspx</link><pubDate>Thu, 20 Aug 2009 21:05:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7175560</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=7175560</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/08/20/a-total-n00b-s-guide-to-migrating-from-a-custom-data-layer-to-nhibernate-so-many-choices.aspx#comments</comments><description>&lt;P&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; MARGIN: 0px 10px 10px 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title="(c) Bertrand Le Roy 2005" border=0 alt="(c) Bertrand Le Roy 2005" align=left src="http://weblogs.asp.net/blogs/bleroy/IMG_0629_057E9F8C.jpg" width=204 height=343 mce_src="http://weblogs.asp.net/blogs/bleroy/IMG_0629_057E9F8C.jpg"&gt; One of the great things about NHibernate is its vibrant community and ecosystem. So many people are using it or building other libraries on top of it that you can be pretty sure that there is always a reasonable solution to any problem you might face. Or several.&lt;/P&gt;
&lt;P&gt;This means of course that there are lots of choices you can make about how you use NHibernate. While this is essentially a good thing, too many choices can be intimidating when starting to use a technology.&lt;/P&gt;
&lt;P&gt;In this post, I’ll present some of the first choices you are going to have to make for your NHibernate code. I’ll explain the choices that our team made for our own migration and an attempt at explaining why you would make different choices depending on the particular context of your application.&lt;/P&gt;
&lt;H4&gt;1. Database first or object first?&lt;/H4&gt;
&lt;P&gt;That’s an easy one.&lt;/P&gt;
&lt;P&gt;If you already have a database, it’s database first.&lt;/P&gt;
&lt;P&gt;If you already have both, all you have to do is build the mappings.&lt;/P&gt;
&lt;P&gt;If you already have an object model, it depends how much you care about the shape of your database. NHibernate has reasonable defaults so you might be able to get away with object first and reasonably fuzzy mappings (or even a &lt;A href="http://nhforge.org/doc/nh/en/index.html#toolsetguide-s3" mce_href="http://nhforge.org/doc/nh/en/index.html#toolsetguide-s3"&gt;generated mapping&lt;/A&gt;). The obvious advantage of that approach is that you’ll be able to easily move database engines without having to rewrite anything but your web.config.&lt;/P&gt;
&lt;P&gt;If you need more control over the shape of the database, you might be able to achieve just that by making your mappings more explicit but still keep generation of the database from NHibernate.&lt;/P&gt;
&lt;P&gt;If that’s still not enough control, just don’t generate the database, and instead manually maintain database, objects and mappings.&lt;/P&gt;
&lt;P&gt;In our own project, we had the database already, but we want to abstract ourselves of a particular engine eventually, so we are moving from a database first approach to an object first approach. Extensions to the application will have to work independently of the database engine (because the app itself is), so it will have to be object first for them.&lt;/P&gt;
&lt;H4&gt;2. To lazy-load or not to lazy-load?&lt;/H4&gt;
&lt;P&gt;&lt;A href="http://en.wikipedia.org/wiki/Lazy_loading" mce_href="http://en.wikipedia.org/wiki/Lazy_loading"&gt;Lazy loading is the practice of delaying the loading of an object&lt;/A&gt; until the moment when it is actually used for the first time. If you have a collection of blog post objects for example, and those objects each have a property that is their collection of comments, you won’t want those comments to be queried from the database unless you are actually going to use them.&lt;/P&gt;
&lt;P&gt;Lazy loading is obviously a good thing, but you also must know that &lt;A href="http://ayende.com/Blog/archive/2006/05/02/CombatingTheSelectN1ProblemInNHibernate.aspx" mce_href="http://ayende.com/Blog/archive/2006/05/02/CombatingTheSelectN1ProblemInNHibernate.aspx"&gt;it can get you in trouble&lt;/A&gt;. So it can be a dangerous tool, but its usefulness far outweighs the danger.&lt;/P&gt;
&lt;P&gt;I’ve also mentioned in the &lt;A href="http://weblogs.asp.net/bleroy/archive/2009/08/17/a-total-n00b-s-guide-to-migrating-from-a-custom-data-layer-to-nhibernate-getting-started.aspx" mce_href="http://weblogs.asp.net/bleroy/archive/2009/08/17/a-total-n00b-s-guide-to-migrating-from-a-custom-data-layer-to-nhibernate-getting-started.aspx"&gt;previous post&lt;/A&gt; that lazy loading requires the use of dynamic proxies and that these in turn require that you run in higher trust than medium. Well, several commenters pointed out that this isn’t exactly true.&lt;/P&gt;
&lt;P&gt;Lazy loading of collection properties does not require the generation of dynamic proxies at all because NHibernate can set the value of those properties directly to a list type that already implements lazy loading. It is only in the case of lazy loading of properties or 1-1 associations that the proxy generation will be necessary. In other words, if your database schema only has 1-N and N-N associations or if you don’t mind eager loading on your 1-1’s, NHibernate can run in medium trust with no problem. This is the approach we are currently using in our application. We will revise it if necessary.&lt;/P&gt;
&lt;P&gt;The first way to achieve medium trust lazy-loading is to &lt;A href="http://nhforge.org/wikis/howtonh/pre-generate-lazy-loading-proxies.aspx" mce_href="http://nhforge.org/wikis/howtonh/pre-generate-lazy-loading-proxies.aspx"&gt;generate the proxies at build-time&lt;/A&gt; instead of dynamically at runtime. Caveat with this approach is that the generated proxies will be specialized to a dialect, which might or might not be a problem. You may be able to mitigate that problem by building dialect-specific versions for all databases that you target, but this is definitely less convenient than the entirely dynamic approach.&lt;/P&gt;
&lt;P&gt;The second approach is to &lt;A href="http://blogs.taiga.nl/martijn/2009/06/24/new-adventures-under-medium-trust/" mce_href="http://blogs.taiga.nl/martijn/2009/06/24/new-adventures-under-medium-trust/"&gt;fix the code of the proxy factory that you are using to work in medium trust&lt;/A&gt;, which is entirely achievable but clearly not for n00bs. Apparently patches are on their way here and this could make the whole problem go away in the near future.&lt;/P&gt;
&lt;P&gt;And the last and lamest approach is to &lt;A href="http://nhforge.org/wikis/howtonh/run-in-medium-trust.aspx" mce_href="http://nhforge.org/wikis/howtonh/run-in-medium-trust.aspx"&gt;disable lazy loading entirely&lt;/A&gt;.&lt;/P&gt;
&lt;H4&gt;3. What dynamic proxy factory to use?&lt;/H4&gt;
&lt;P&gt;Once you’ve decided that you’re going to use lazy loading and are going to need dynamic proxies, you still have to decide which proxy factory you’re going to use. &lt;A href="http://nhforge.org/blogs/nhibernate/archive/2008/11/09/nh2-1-0-bytecode-providers.aspx" mce_href="http://nhforge.org/blogs/nhibernate/archive/2008/11/09/nh2-1-0-bytecode-providers.aspx"&gt;Three choices are available&lt;/A&gt; out of the box: Castle, LinFu and Spring.&lt;/P&gt;
&lt;P&gt;If you want to work with &lt;A href="http://www.castleproject.org/activerecord/index.html" mce_href="http://www.castleproject.org/activerecord/index.html"&gt;Castle.ActiveRecord&lt;/A&gt; or &lt;A href="http://www.castleproject.org/container/index.html" mce_href="http://www.castleproject.org/container/index.html"&gt;Castle.Windsor&lt;/A&gt;, Castle is the obvious choice.&lt;/P&gt;
&lt;P&gt;If you want to work with &lt;A href="http://springframework.net/overview.html" mce_href="http://springframework.net/overview.html"&gt;Spring&lt;/A&gt;, Spring is obviously what you should use.&lt;/P&gt;
&lt;P&gt;If you are not using Castle or Spring, or have no idea what you want, &lt;A href="http://www.codeproject.com/info/search.aspx?artkw=LinFu&amp;amp;sbo=kw" mce_href="http://www.codeproject.com/info/search.aspx?artkw=LinFu&amp;amp;sbo=kw"&gt;LinFu&lt;/A&gt; can be a reasonable default.&lt;/P&gt;
&lt;P&gt;In our application, because we don’t need dynamic proxies for the moment, we haven’t had to choose.&lt;/P&gt;
&lt;H4&gt;3. XML, attributes or fluent mappings?&lt;/H4&gt;
&lt;H5&gt;XML&lt;/H5&gt;
&lt;P&gt;&lt;A href="http://nhforge.org/doc/nh/en/index.html#mapping-declaration" mce_href="http://nhforge.org/doc/nh/en/index.html#mapping-declaration"&gt;XML mappings&lt;/A&gt; are the default but some people dislike XML’s verbosity. There is also a fair amount of repetition and magic strings involved. Refactoring won’t propagate automatically to the mapping files. Advantages include that it’s the most mature approach and that it doesn’t require any additional dependency.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;?&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;xml &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;version&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;1.0&lt;/SPAN&gt;" &lt;SPAN style="COLOR: red"&gt;encoding&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;utf-8&lt;/SPAN&gt;" &lt;SPAN style="COLOR: blue"&gt;?&amp;gt;
&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;hibernate-mapping &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;xmlns&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;urn:nhibernate-mapping-2.2&lt;/SPAN&gt;"
    &lt;SPAN style="COLOR: red"&gt;namespace&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;Nhib.Models&lt;/SPAN&gt;" &lt;SPAN style="COLOR: red"&gt;assembly&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;Nhib&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;&amp;gt;

  &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;class &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;Product&lt;/SPAN&gt;" &lt;SPAN style="COLOR: red"&gt;table&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;Products&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;id &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;SKU&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
      &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;generator &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;class&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;uuid.hex&lt;/SPAN&gt;" &lt;SPAN style="COLOR: blue"&gt;/&amp;gt;
    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;id&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;property &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;ProductName&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;property &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;BasePrice&lt;/SPAN&gt;" &lt;SPAN style="COLOR: blue"&gt;/&amp;gt;
  &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;class&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;

&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;hibernate-mapping&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;H5&gt;Attributes&lt;/H5&gt;
&lt;P&gt;It is possible to use &lt;A href="http://www.castleproject.org/activerecord/documentation/v1rc1/manual/attributedocs/index.html" mce_href="http://www.castleproject.org/activerecord/documentation/v1rc1/manual/attributedocs/index.html"&gt;attributes through Castle&lt;/A&gt; to specify the mappings instead. This is very easy, involves minimal repetition and a less magic strings than XML. On the other hand, doing the mapping on the objects themselves means less separation of concerns as the objects and the mappings are in the same place. It also means buying into the whole active record approach and giving up POCOs.&lt;/P&gt;&lt;PRE class=code&gt;[&lt;SPAN style="COLOR: #2b91af"&gt;ActiveRecord&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Products"&lt;/SPAN&gt;)]
&lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Product &lt;/SPAN&gt;: &lt;SPAN style="COLOR: #2b91af"&gt;ActiveRecordBase &lt;/SPAN&gt;{
    [&lt;SPAN style="COLOR: #2b91af"&gt;PrimaryKey&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;PrimaryKeyType&lt;/SPAN&gt;.UuidHex)]
    &lt;SPAN style="COLOR: blue"&gt;public string &lt;/SPAN&gt;SKU { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }
    [&lt;SPAN style="COLOR: #2b91af"&gt;Property&lt;/SPAN&gt;]
    &lt;SPAN style="COLOR: blue"&gt;public string &lt;/SPAN&gt;ProductName { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }
    [&lt;SPAN style="COLOR: #2b91af"&gt;Property&lt;/SPAN&gt;]
    &lt;SPAN style="COLOR: blue"&gt;public double &lt;/SPAN&gt;Price { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }
}&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;STRONG&gt;Update:&lt;/STRONG&gt; Gauthier Segay pointed out that it's not exactly true that you have buy into the whole Castle active record approach. More info here: &lt;P&gt;&lt;A href="http://www.castleproject.org/activerecord/documentation/trunk/advanced/mediator.html"&gt;http://www.castleproject.org/activerecord/documentation/trunk/advanced/mediator.html&lt;/A&gt;&lt;/P&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;H5&gt;Fluent&lt;/H5&gt;
&lt;P&gt;Finally, the favorite approach &lt;EM&gt;du jour&lt;/EM&gt; is &lt;A href="http://fluentnhibernate.org/" mce_href="http://fluentnhibernate.org/"&gt;Fluent NHibernate&lt;/A&gt;. That approach still keeps mappings nicely separated but has several other advantages.&lt;/P&gt;
&lt;P&gt;First, it’s code, which opens up a lot of dynamic scenarios.&lt;/P&gt;
&lt;P&gt;Second, it’s strongly-typed. That means that refactoring will work, that you will get compile-time checks and IntelliSense.&lt;/P&gt;
&lt;P&gt;Third, it uses &lt;A href="http://msdn.microsoft.com/en-us/library/bb397687.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb397687.aspx"&gt;Lambdas&lt;/A&gt; and a &lt;A href="http://en.wikipedia.org/wiki/Fluent_interface" mce_href="http://en.wikipedia.org/wiki/Fluent_interface"&gt;fluent interface&lt;/A&gt;, and &lt;A href="http://weblogs.asp.net/bleroy/archive/2009/06/15/mocking-indexer-setters-with-moq.aspx" mce_href="http://weblogs.asp.net/bleroy/archive/2009/06/15/mocking-indexer-setters-with-moq.aspx"&gt;those are so cute&lt;/A&gt;… On the other hand, if you find those alien, it might not be such a win. On the other other hand, it’s a good occasion to learn something new and cool.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ProductMap &lt;/SPAN&gt;: &lt;SPAN style="COLOR: #2b91af"&gt;ClassMap&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Product&lt;/SPAN&gt;&amp;gt; {
    &lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;ProductMap() {
        Id(p =&amp;gt; p.SKU).GeneratedBy.UuidHex(&lt;SPAN style="COLOR: #a31515"&gt;"B"&lt;/SPAN&gt;);
        Map(p =&amp;gt; p.ProductName);
        Map(p =&amp;gt; p.Price);
    }
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;In our application, we have chosen XML mappings for now to minimize the number of dependencies and because choosing the most mature approach also means learning is more incremental. We might revise that decision if and when the disadvantages become too much of a problem and as we learn more.&lt;/P&gt;
&lt;H4&gt;4. HQL, criteria, lambdas, ActiveRecord or Linq?&lt;/H4&gt;
&lt;H5&gt;HQL&lt;/H5&gt;
&lt;P&gt;&lt;A href="http://nhforge.org/doc/nh/en/index.html#queryhql" mce_href="http://nhforge.org/doc/nh/en/index.html#queryhql"&gt;HQL is the Hibernate Query Language&lt;/A&gt; and is the default way of querying in NHibernate. It works and is mature but it is a text format, which means no static verification, refactoring or IntelliSense.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: #a31515"&gt;“select p from Product as p where p.ProductName like 'boot%'”&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;There are a few alternatives to HQL though. Let’s first talk about native SQL. It is possible to send native SQL from NHibernate but you should really only do that if you need to use a specific native feature of your database. While the possibility exists, it is not a relevant choice here.&lt;/P&gt;
&lt;H5&gt;CreateCriteria&lt;/H5&gt;
&lt;P&gt;The NHibernate session object has a CreateCriteria method that exposes a fluent querying interface. You can use it &lt;A href="http://knol.google.com/k/fabio-maulo/nhibernate-chapter-13/1nr4enxv3dpeq/16#" mce_href="http://knol.google.com/k/fabio-maulo/nhibernate-chapter-13/1nr4enxv3dpeq/16#"&gt;with expressions&lt;/A&gt;, but this is deprecated, or you can use it &lt;A href="http://ayende.com/Blog/archive/2009/05/19/nhibernate-queries-examples.aspx" mce_href="http://ayende.com/Blog/archive/2009/05/19/nhibernate-queries-examples.aspx"&gt;with restrictions&lt;/A&gt;, which are very similar but more current.&lt;/P&gt;&lt;PRE class=code&gt;session.CreateCriteria&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Product&lt;/SPAN&gt;&amp;gt;()&lt;BR&gt;    .Add(&lt;SPAN style="COLOR: #2b91af"&gt;Restrictions&lt;/SPAN&gt;.Like(&lt;SPAN style="COLOR: #a31515"&gt;"ProductName"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"boot%"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;This API tends to be relatively verbose and is not completely strongly typed but it may be more appropriate than HQL for simple queries.&lt;/P&gt;
&lt;H5&gt;Lambdas&lt;/H5&gt;
&lt;P&gt;The &lt;A href="http://code.google.com/p/nhlambdaextensions/" mce_href="http://code.google.com/p/nhlambdaextensions/"&gt;nhlambdaextensions project&lt;/A&gt; provides a strongly-typed alternative to the restrictions described above through the use of Lambda expressions. This is a strong choice that comes close to Linq but it does require yet another dependency.&lt;/P&gt;&lt;PRE class=code&gt;session.CreateCriteria&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Product&lt;/SPAN&gt;&amp;gt;()&lt;BR&gt;    .Add&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Product&lt;/SPAN&gt;&amp;gt;(p =&amp;gt;&lt;BR&gt;        p.ProductName.StartsWith(&lt;SPAN style="COLOR: #a31515"&gt;"boot"&lt;/SPAN&gt;,&lt;BR&gt;        &lt;SPAN style="COLOR: #2b91af"&gt;StringComparison&lt;/SPAN&gt;.CurrentCultureIgnoreCase));&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;H5&gt;ActiveRecord&lt;/H5&gt;
&lt;P&gt;If you chose to use Castle ActiveRecord, you can still query using HQL, but you also get &lt;A href="http://www.castleproject.org/activerecord/documentation/v1rc1/manual/aroperationsdocs/index.html" mce_href="http://www.castleproject.org/activerecord/documentation/v1rc1/manual/aroperationsdocs/index.html"&gt;basic repository-like operations&lt;/A&gt; directly on your data classes out of the box.&lt;/P&gt;&lt;PRE class=code&gt;FindAll(&lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;Product&lt;/SPAN&gt;), &lt;SPAN style="COLOR: #2b91af"&gt;Restrictions&lt;/SPAN&gt;.Like(&lt;SPAN style="COLOR: #a31515"&gt;"ProductName"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"boot%"&lt;/SPAN&gt;));&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;H5&gt;Linq&lt;/H5&gt;
&lt;P&gt;Finally, you can use an implementation of &lt;A href="http://en.wikipedia.org/wiki/Language_Integrated_Query" mce_href="http://en.wikipedia.org/wiki/Language_Integrated_Query"&gt;Linq&lt;/A&gt; to query NHibernate. This is Linq, for NHibernate. In other words, pure, distilled WIN: strong typing, compile-time checks, etc. The problem is that it is still a work in progress (and an additional dependency).&lt;/P&gt;&lt;PRE class=code&gt;&lt;FONT color=#0000ff&gt;from&lt;/FONT&gt; product &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;session.Linq&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Product&lt;/SPAN&gt;&amp;gt;()
    &lt;FONT color=#0000ff&gt;where&lt;/FONT&gt; product.startsWith(&lt;SPAN style="COLOR: #a31515"&gt;"boot"&lt;/SPAN&gt;,&lt;BR&gt;        &lt;SPAN style="COLOR: #2b91af"&gt;StringComparison&lt;/SPAN&gt;.CurrentCultureIgnoreCase)
    &lt;FONT color=#0000ff&gt;select&lt;/FONT&gt; product;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Linq to NHibernate can be obtained from &lt;A href="http://sourceforge.net/projects/nhcontrib/" mce_href="http://sourceforge.net/projects/nhcontrib/"&gt;NHibernate Contrib&lt;/A&gt; or as part of &lt;A href="http://fluentnhibernate.org/" mce_href="http://fluentnhibernate.org/"&gt;Fluent NHibernate&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;For the moment, our application uses CreateCriteria with restrictions for simple queries, and HQL in places. Again, the motivation here is to minimize the dependencies.&lt;/P&gt;
&lt;H4&gt;Conclusion&lt;/H4&gt;
&lt;P&gt;I hope this post will be helpful for NHibernate beginners such as myself to make the right first choices.&lt;/P&gt;
&lt;P&gt;Next time, we’ll really start digging into our transition from our old custom data layer.&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7175560" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/NHibernate/default.aspx">NHibernate</category></item></channel></rss>