<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" version="2.0">
    <channel>
        <title>you've been HAACKED</title>
        <link>http://haacked.com/Default.aspx</link>
        <description>...and you like it.</description>
        <language>en-US</language>
        <copyright>Haacked</copyright>
        <generator>Subtext Version 2.0.1.2</generator>
        <image>
            <title>you've been HAACKED</title>
            <url>http://haacked.com/images/RSS2Image.gif</url>
            <link>http://haacked.com/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <geo:lat>34.03056</geo:lat><geo:long>-118.398043</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/haacked" type="application/rss+xml" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">haacked</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
            <title>Interface Inheritance Esoterica</title>
            <category>ASP.NET</category>
            <category>ASP.NET MVC</category>
            <category>Software Development</category>
            <link>http://haacked.com/archive/2009/11/10/interface-inheritance-esoterica.aspx</link>
            <description>&lt;p&gt;I learned something new yesterday about interface inheritance in .NET as compared to implementation inheritance. To illustrate this difference, here’s a simple demonstration.&lt;/p&gt;  &lt;p&gt;I’ll start with two concrete classes, one which inherits from the other. Each class defines a property. In this case, we’re dealing with &lt;em&gt;implementation inheritance&lt;/em&gt;.&lt;/p&gt;  &lt;div class="dropshadow code"&gt;   &lt;div class="innerbox"&gt;     &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Person {
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name { get; set; }
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SuperHero : Person {
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Alias { get; set; }
}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;We can now use two different techniques to print out the properties of the &lt;code&gt;SuperHero&lt;/code&gt; type: type descriptors and reflection. Here’s a little console app that does this. Note the code I’m showing below doesn’t include a few &lt;code&gt;Console.WriteLine&lt;/code&gt; calls that I have in the actual app.&lt;/p&gt;

&lt;div class="dropshadow code"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args) {
  &lt;span class="rem"&gt;// type descriptor&lt;/span&gt;
  var properties = TypeDescriptor.GetProperties(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(SuperHero));
  &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (PropertyDescriptor property &lt;span class="kwrd"&gt;in&lt;/span&gt; properties) {
    Console.WriteLine(property.Name);
  }

  &lt;span class="rem"&gt;// reflection&lt;/span&gt;
  var reflectedProperties = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(SuperHero).GetProperties();
  &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var property &lt;span class="kwrd"&gt;in&lt;/span&gt; reflectedProperties) {
    Console.WriteLine(property.Name);
  }
}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;Let’s look at the output of this code.&lt;/p&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="impl-inheritance" border="0" alt="impl-inheritance" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/InterfaceInheritanceEsoterica_8E49/impl-inheritance_3.png" width="477" height="271" /&gt; &lt;/p&gt;

&lt;p&gt;No surprises there.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;SuperHero&lt;/code&gt; type has two properties, &lt;code&gt;Alias&lt;/code&gt; defined on &lt;code&gt;SuperHero&lt;/code&gt; and the &lt;code&gt;Name&lt;/code&gt; property inherited from its base type.&lt;/p&gt;

&lt;p&gt;But now, let’s change these classes into interfaces so that we’re now dealing with &lt;em&gt;interface inheritance&lt;/em&gt;. Notice that &lt;code&gt;ISupeHero&lt;/code&gt; now derives from &lt;code&gt;IPerson&lt;/code&gt;.&lt;/p&gt;

&lt;div class="dropshadow code"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IPerson {
  &lt;span class="kwrd"&gt;string&lt;/span&gt; Name { get; set; }
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; ISuperHero : IPerson {
  &lt;span class="kwrd"&gt;string&lt;/span&gt; Alias { get; set; }
}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;I’ve also made the corresponding changes to the console app.&lt;/p&gt;

&lt;div class="dropshadow code"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;var properties = TypeDescriptor.GetProperties(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;strong&gt;ISuperHero&lt;/strong&gt;));
&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (PropertyDescriptor property &lt;span class="kwrd"&gt;in&lt;/span&gt; properties) {
  Console.WriteLine(property.Name);
}

&lt;span class="rem"&gt;// reflection&lt;/span&gt;
var reflectedProperties = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;strong&gt;ISuperHero&lt;/strong&gt;).GetProperties();
&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var property &lt;span class="kwrd"&gt;in&lt;/span&gt; reflectedProperties) {
  Console.WriteLine(property.Name);
}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;Before looking at the next screenshot, take a moment to answer the question, what is the output of the program now?&lt;/p&gt;

&lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/InterfaceInheritanceEsoterica_8E49/interface-inheritance_2.png" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="interface-inheritance" border="0" alt="interface-inheritance" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/InterfaceInheritanceEsoterica_8E49/interface-inheritance_thumb.png" width="373" height="235" /&gt;&lt;/a&gt; Well it should be obvious that the output is different otherwise I wouldn’t be writing this blog post in the first place, right?&lt;/p&gt;

&lt;p&gt;When I first tried this out, I found the behavior surprising. However, it’s probably not surprising to anyone who has an encyclopedic knowledge of the &lt;a title="Ecma-335 spec" href="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-335.pdf"&gt;ECMA-335 Common Language Infrastructure specification (PDF)&lt;/a&gt; such as Levi, one of the ASP.NET MVC developers who pointed me to section 8.9.11 of the spec when I asked about this behavior:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;8.9.11 Interface type derivation&lt;/strong&gt; Interface types can require the implementation of one or more other interfaces. Any type that implements support for an interface type shall also implement support for any required interfaces specified by that interface. This is different from object type inheritance in two ways:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;Object types form a single inheritance tree; interface types do not. &lt;/li&gt;

    &lt;li&gt;Object type inheritance specifies how implementations are inherited; required interfaces do not, since interfaces do not define implementation. Required interfaces specify additional contracts that an implementing object type shall support. &lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;To highlight the last difference, consider an interface, &lt;code&gt;IFoo&lt;/code&gt;, that has a single method. An interface, &lt;code&gt;IBar&lt;/code&gt;, which derives from it, is requiring that any object type that supports &lt;code&gt;IBar&lt;/code&gt; also support IFoo. It does not say anything about which methods &lt;code&gt;IBar&lt;/code&gt; itself will have.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The last paragraph provides a great example of why the code I wrote behaves as it does. The fact that &lt;code&gt;ISuperHero&lt;/code&gt; inherits from &lt;code&gt;IPerson&lt;/code&gt; doesn’t mean the &lt;code&gt;ISuperHero&lt;/code&gt; interface type inherits the properties of &lt;code&gt;IPerson &lt;/code&gt;because interfaces do not define implementation.&lt;/p&gt;

&lt;p&gt;Rather, what it means is that any class that implements &lt;code&gt;ISuperHero&lt;/code&gt; must also implement the &lt;code&gt;IPerson&lt;/code&gt; interface. Thus if I wrote an implementation of &lt;code&gt;ISuperHero&lt;/code&gt; such as:&lt;/p&gt;

&lt;div class="dropshadow code"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Groo : ISuperHero {
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name {get; set;}
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Alias {get; set;}
}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;The &lt;code&gt;Groo&lt;/code&gt; type must implement both &lt;code&gt;ISuperHero&lt;/code&gt; and &lt;code&gt;IPerson&lt;/code&gt; and iterating over its properties would show both properties.&lt;/p&gt;

&lt;h3&gt;Implications for ASP.NET MVC Model Binding&lt;/h3&gt;

&lt;p&gt;You probably could have guessed this part was coming. Let’s say you’re trying to use model binding to bind the &lt;code&gt;Name&lt;/code&gt; property of an &lt;code&gt;ISuperHero&lt;/code&gt;. Since our model binder uses type descriptors under the hood, we won’t be able to bind that property for the reasons stated above.&lt;/p&gt;

&lt;p&gt;I learned of this detail investigating a &lt;a title="Debugging Model Binding Issues" href="http://stackoverflow.com/questions/1676731/asp-net-mvc-v2-debugging-model-binding-issues"&gt;bug reported in StackOverflow&lt;/a&gt;. It turns out this behavior is by design. In the context of sending a view model to the view, that view model should be a simple carrier of data. Thus it makes sense to use concrete types on your view model, in contrast to your domain models which will more likely be interface based.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:dd2e9fd1-f6b5-44f8-9dea-c357e9bb4759" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://haacked.com/tags/aspnetmvc/default.aspx" rel="tag"&gt;aspnetmvc&lt;/a&gt;, &lt;a href="http://haacked.com/tags/interfaces/default.aspx" rel="tag"&gt;interfaces&lt;/a&gt;, &lt;a href="http://haacked.com/tags/cli/default.aspx" rel="tag"&gt;cli&lt;/a&gt;, &lt;a href="http://haacked.com/tags/model+binding/default.aspx" rel="tag"&gt;model binding&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18658.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=THUNZi4lYk4:i9X59eLEJQ8:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=THUNZi4lYk4:i9X59eLEJQ8:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=THUNZi4lYk4:i9X59eLEJQ8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=THUNZi4lYk4:i9X59eLEJQ8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=THUNZi4lYk4:i9X59eLEJQ8:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/11/10/interface-inheritance-esoterica.aspx</guid>
            <pubDate>Tue, 10 Nov 2009 18:43:13 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18658.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/11/10/interface-inheritance-esoterica.aspx#feedback</comments>
            <slash:comments>24</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18658.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Neat VS10 Feature: Pinning A Debugger Watch</title>
            <category>Software Development</category>
            <link>http://haacked.com/archive/2009/11/06/pinning-a-debugger-watch.aspx</link>
            <description>&lt;p&gt;I was stepping through some code in a debugger today and noticed a neat little feature of Visual Studio 2010 that I hadn’t noticed before.&lt;/p&gt;  &lt;p&gt;When debugging, you can easily examine the value of a variably by highlighting it with your mouse. Nothing new there. But then I noticed a little pin next to it, which I’ve never seen before.&lt;/p&gt;  &lt;p&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="debugger-value" border="0" alt="debugger-value" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/NeatVS10FeaturePinningADebuggerWatch_EB08/debugger-value_3.png" width="553" height="263" /&gt; &lt;/p&gt;  &lt;p&gt;So what do you see when you see a pin? You click on it!&lt;/p&gt;  &lt;p&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="pinned-quick-watch" border="0" alt="pinned-quick-watch" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/NeatVS10FeaturePinningADebuggerWatch_EB08/pinned-quick-watch_3.png" width="540" height="226" /&gt; &lt;/p&gt;  &lt;p&gt;As you might expect, that pins the quick watch in place. So now I hit the play button, continue running my app in the debugger, and the next time I hit that breakpoint:&lt;/p&gt;  &lt;p&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="pinne-watch-changed" border="0" alt="pinne-watch-changed" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/NeatVS10FeaturePinningADebuggerWatch_EB08/pinne-watch-changed_3.png" width="540" height="249" /&gt; &lt;/p&gt;  &lt;p&gt;I can clearly see the value changed since the last time. I think this may come in useful when walking through code as a way of seeing the value of important variables right next to where they are declared. I thought that was pretty neat.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:f222a346-08e0-4344-9cd2-fe251ec2ea90" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://haacked.com/tags/vs2010/default.aspx" rel="tag"&gt;vs2010&lt;/a&gt;, &lt;a href="http://haacked.com/tags/visual+studio/default.aspx" rel="tag"&gt;visual studio&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18657.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=QbX-5gbXYIQ:LTSfTpVSg84:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=QbX-5gbXYIQ:LTSfTpVSg84:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=QbX-5gbXYIQ:LTSfTpVSg84:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=QbX-5gbXYIQ:LTSfTpVSg84:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=QbX-5gbXYIQ:LTSfTpVSg84:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/11/06/pinning-a-debugger-watch.aspx</guid>
            <pubDate>Sat, 07 Nov 2009 00:42:53 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18657.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/11/06/pinning-a-debugger-watch.aspx#feedback</comments>
            <slash:comments>13</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18657.aspx</wfw:commentRss>
        </item>
        <item>
            <title>A RouteHandler for IHttpHandlers</title>
            <category>ASP.NET</category>
            <category>Software Development</category>
            <link>http://haacked.com/archive/2009/11/04/routehandler-for-http-handlers.aspx</link>
            <description>&lt;p&gt;I saw a &lt;a title="Change PageRouteHandler to handle IHttpHandler as well as Page" href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=507180&amp;amp;wa=wsignin1.0"&gt;bug on Connect&lt;/a&gt; today in which someone offers the suggestion that the &lt;code&gt;PageRouteHandler&lt;/code&gt; (new in ASP.NET 4) should handle &lt;code&gt;IHttpHandler&lt;/code&gt; as well as &lt;code&gt;Page&lt;/code&gt;.&lt;/p&gt;  &lt;p&gt;I don’t really agree with the suggestion because while a &lt;code&gt;Page&lt;/code&gt; is an &lt;code&gt;IHttpHandler&lt;/code&gt;, an &lt;code&gt;IHttpHandler&lt;/code&gt; is not a &lt;code&gt;Page&lt;/code&gt;. What I this person really wants is a new handler specifically for http handlers. Let’s give it the tongue twisting name: &lt;code&gt;IHttpHandlerRouteHandler&lt;/code&gt;.&lt;/p&gt;  &lt;p&gt;Unfortunately, it’s too late to add this for ASP.NET 4, but it turns out such a thing is trivially easy to write. In fact, here it is.&lt;/p&gt;  &lt;div class="dropshadow code"&gt;   &lt;div class="innerbox"&gt;     &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; HttpHandlerRouteHandler&amp;lt;THandler&amp;gt; 
    : IRouteHandler &lt;span class="kwrd"&gt;where&lt;/span&gt; THandler : IHttpHandler, &lt;span class="kwrd"&gt;new&lt;/span&gt;() {
  &lt;span class="kwrd"&gt;public&lt;/span&gt; IHttpHandler GetHttpHandler(RequestContext requestContext) {
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; THandler();
  }
}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;Of course, by itself it’s not all that useful. We need extension methods to make it really easy to register routes for http handlers. I wrote a set of those, but will only post two examples here on my blog. To get the full set download the sample project at the very end of this post.&lt;/p&gt;

&lt;div class="dropshadow code"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; HttpHandlerExtensions {
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; MapHttpHandler&amp;lt;THandler&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; RouteCollection routes, &lt;br /&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; url) &lt;span class="kwrd"&gt;where&lt;/span&gt; THandler : IHttpHandler, &lt;span class="kwrd"&gt;new&lt;/span&gt;() {
    routes.MapHttpHandler&amp;lt;THandler&amp;gt;(&lt;span class="kwrd"&gt;null&lt;/span&gt;, url, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;);
  }
  &lt;span class="rem"&gt;//...&lt;/span&gt;
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; MapHttpHandler&amp;lt;THandler&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; RouteCollection routes, 
      &lt;span class="kwrd"&gt;string&lt;/span&gt; name, &lt;span class="kwrd"&gt;string&lt;/span&gt; url, &lt;span class="kwrd"&gt;object&lt;/span&gt; defaults, &lt;span class="kwrd"&gt;object&lt;/span&gt; constraints) 
      &lt;span class="kwrd"&gt;where&lt;/span&gt; THandler : IHttpHandler, &lt;span class="kwrd"&gt;new&lt;/span&gt;() { 
    var route = &lt;span class="kwrd"&gt;new&lt;/span&gt; Route(url, &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpHandlerRouteHandler&amp;lt;THandler&amp;gt;());
    route.Defaults = &lt;span class="kwrd"&gt;new&lt;/span&gt; RouteValueDictionary(defaults);
    route.Constraints = &lt;span class="kwrd"&gt;new&lt;/span&gt; RouteValueDictionary(constraints);
    routes.Add(name, route);
  }
}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;This now allows me to register a route which is handled by an &lt;code&gt;IHttpHandler&lt;/code&gt; very easily. In this case, I’m registering a route that will use my &lt;code&gt;SimpleHttpHandler&lt;/code&gt; to handle any two segment URL.&lt;/p&gt;

&lt;div class="dropshadow code"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; RegisterRoutes(RouteCollection routes) {
    routes.MapHttpHandler&amp;lt;SampleHttpHandler&amp;gt;(&lt;span class="str"&gt;"{foo}/{bar}"&lt;/span&gt;);
}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;And here’s the code for &lt;code&gt;SampleHttpHandler&lt;/code&gt; for completeness. All it does is print out the route values.&lt;/p&gt;

&lt;div class="dropshadow code"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SampleHttpHandler : IHttpHandler {
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsReusable {
    get { &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;; }
  }

  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ProcessRequest(HttpContext context) {
    var routeValues = context.Request.RequestContext.RouteData.Values;
    &lt;span class="kwrd"&gt;string&lt;/span&gt; message = &lt;span class="str"&gt;"I saw foo='{0}' and bar='{1}'"&lt;/span&gt;;
    message = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(message, routeValues[&lt;span class="str"&gt;"foo"&lt;/span&gt;], routeValues[&lt;span class="str"&gt;"bar"&lt;/span&gt;]);

    context.Response.Write(message);
  }
}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;When I make a request for &lt;code&gt;/testing/yo&lt;/code&gt; I’ll see the message&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I saw foo='testing' and bar='yo'&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;in my browser. Very cool.&lt;/p&gt;

&lt;h3&gt;Limitation&lt;/h3&gt;

&lt;p&gt;One limitation here is that my http handler has to have a parameterless constructor. That’s not really that bad of a limitation since to register an HTTP Handler in the old way you had to make sure that the handler had an empty constructor.&lt;/p&gt;

&lt;p&gt;However, this code that I wrote for this blog post is based on code that I added to &lt;a title="Subtext" href="http://subtextproject.com/"&gt;Subtext&lt;/a&gt;. In &lt;a title="HttpRouteHandler" href="http://code.google.com/p/subtext/source/browse/trunk/SubtextSolution/Subtext.Framework/Routing/HttpRouteHandler.cs?spec=svn3553&amp;amp;r=3553"&gt;that code&lt;/a&gt;, I am passing an &lt;code&gt;IKernel&lt;/code&gt; (I’m using &lt;a title="Ninject" href="http://ninject.org/"&gt;Ninject&lt;/a&gt;) to my &lt;code&gt;HttpRouteHandler&lt;/code&gt;. That way, my route handler will use Ninject to instantiate the http handler and thus my http handlers aren’t required to have a parameterless constructor.&lt;/p&gt;

&lt;h3&gt;Try it out!&lt;/h3&gt;

&lt;p&gt;I’ve uploaded a &lt;strong&gt;&lt;a title="Sample project" href="http://haacked.com/code/HttpHandlerRouteHandlerDemo.zip"&gt;sample project&lt;/a&gt;&lt;/strong&gt; to my blog that requires Visual Studio 2010 Beta 2 and ASP.NET 4 Beta 2 to run. However, all the code will work against ASP.NET 3.5 SP 1 except for the &lt;code&gt;SimpleHttpHandler&lt;/code&gt;. The &lt;code&gt;RequestContext&lt;/code&gt; property of &lt;code&gt;HttpContext&lt;/code&gt; is new in ASP.NET 4.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:bca5ee9a-6e6a-4f96-a02c-9fb622b27941" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://haacked.com/tags/asp.net+4/default.aspx" rel="tag"&gt;asp.net 4&lt;/a&gt;, &lt;a href="http://haacked.com/tags/routing/default.aspx" rel="tag"&gt;routing&lt;/a&gt;, &lt;a href="http://haacked.com/tags/IHttpHandler/default.aspx" rel="tag"&gt;IHttpHandler&lt;/a&gt;, &lt;a href="http://haacked.com/tags/PageRouteHandler/default.aspx" rel="tag"&gt;PageRouteHandler&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18656.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=cfBLcowbReg:18ytos91goQ:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=cfBLcowbReg:18ytos91goQ:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=cfBLcowbReg:18ytos91goQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=cfBLcowbReg:18ytos91goQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=cfBLcowbReg:18ytos91goQ:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/11/04/routehandler-for-http-handlers.aspx</guid>
            <pubDate>Thu, 05 Nov 2009 00:18:30 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18656.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/11/04/routehandler-for-http-handlers.aspx#feedback</comments>
            <slash:comments>10</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18656.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Html Encoding Nuggets With ASP.NET MVC 2</title>
            <category>ASP.NET MVC</category>
            <category>ASP.NET</category>
            <link>http://haacked.com/archive/2009/11/03/html-encoding-nuggets-aspnetmvc2.aspx</link>
            <description>&lt;p&gt;In a recent blog post, I introduced &lt;a title="Html Encoding Code Blocks" href="http://haacked.com/archive/2009/09/25/html-encoding-code-nuggets.aspx"&gt;ASP.NET 4’s new HTML Encoding code block syntax&lt;/a&gt; as well as the corresponding &lt;code&gt;IHtmlString&lt;/code&gt; interface and &lt;code&gt;HtmlString&lt;/code&gt; class. I also mentioned that ASP.NET MVC 2 would support this new syntax &lt;em&gt;&lt;strong&gt;when running on ASP.NET 4&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;In fact, you can &lt;a title="VS10 Beta 2 from an ASP.NET MVC perspective" href="http://haacked.com/archive/2009/10/20/vs10beta2-and-aspnetmvc.aspx"&gt;try it out now&lt;/a&gt; by downloading and installing Visual Studio 2010 Beta 2.&lt;/p&gt;  &lt;p&gt;I’ve also mentioned in the past that we are not conditionally compiling ASP.NET MVC 2 for each platform. Instead, we’re building &lt;code&gt;System.Web.Mvc.dll&lt;/code&gt; against ASP.NET 3.5 SP1 and simply including that one in VS08 and VS10. Thus when you’re running ASP.NET MVC 2 on ASP.NET 4, it’s the same byte for byte assembly as the same one you would run on ASP.NET 3.5 SP1.&lt;/p&gt;  &lt;p&gt;This fact ought to raise a question in your mind. If ASP.NET MVC 2 is built against ASP.NET 3.5 SP1, &lt;strong&gt;how the heck does it take advantage of the new HTML encoding blocks which require that you implement an interface introduced in ASP.NET 4?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The answer involves a tiny bit of voodoo black magic we’re doing in ASP.NET MVC 2.&lt;a title="Voodoo by sloopjohnb" href="http://www.sxc.hu/photo/1196752"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="voodoo" border="0" alt="voodoo" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/HtmlEncodingNuggetsWithASP.NETMVC2_13929/voodoo_3.jpg" width="311" height="480" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We introduced a new type &lt;code&gt;MvcHtmlString&lt;/code&gt; which is created via a factory method, &lt;code&gt;MvcHtmlString.Create&lt;/code&gt;. When this method determines that it is being called from an ASP.NET 4 application, it uses Reflection.Emit to dynamically generate a derived type which implements &lt;code&gt;IHtmlString&lt;/code&gt;.&lt;/p&gt;  &lt;p&gt;If you look at the source code for ASP.NET MVC 2 Preview 2, you’ll see the following method call when we are instantiating an &lt;code&gt;MvcHtmlString&lt;/code&gt;:&lt;/p&gt;  &lt;div class="dropshadow code"&gt;   &lt;div class="innerbox"&gt;     &lt;pre class="csharpcode"&gt;Type dynamicType = DynamicTypeGenerator.
  GenerateType(&lt;span class="str"&gt;"DynamicMvcHtmlString"&lt;/span&gt;, 
    &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(MvcHtmlString), &lt;span class="kwrd"&gt;new&lt;/span&gt; Type[] {&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;Note that we’re using a new internal class, &lt;code&gt;DynamicTypeGenerator&lt;/code&gt;, to generate a brand new type named &lt;code&gt;DynamicMvcHtmlString&lt;/code&gt;. This type derives from &lt;code&gt;MvcHtmlString&lt;/code&gt; and implements &lt;code&gt;IHtmlString&lt;/code&gt;. We’ll return this instance instead of a standard MvcHtmlString when running on ASP.NET 4.&lt;/p&gt;

&lt;p class="clear"&gt;When running on ASP.NET 3.5 SP1, we simply new up an &lt;code&gt;MvcHtmlString&lt;/code&gt; and return that, completely bypassing the Reflection.Emit logic. Note that we only generate this type once per AppDomain so you only pay the Reflection Emit cost once.&lt;/p&gt;

&lt;p&gt;The code in &lt;code&gt;DynamicTypeGenerater&lt;/code&gt; is standard Reflection.Emit stuff which at runtime creates an assembly at runtime, adds this new type to it, and returns a lambda used to instantiate the new type. If you’ve never seen Reflection.Emit code, it’s worth a look.&lt;/p&gt;

&lt;p&gt;In general, we really frown on this sort of “tricky” code as it’s often hard to maintain and a potential bug magnet. For example, since &lt;code&gt;System.Web.Mvc.dll&lt;/code&gt; is security transparent, we needed to make sure that the assembly we generate is marked with the &lt;code&gt;SecurityTransparentAttribute&lt;/code&gt;. This is something that would be easy to overlook until you start testing in medium trust scenarios.&lt;/p&gt;

&lt;p&gt;However, in this case, the type we’re generating is very small and very simple. Not only that, we only need to keep this code for one version of ASP.NET MVC. ASP.NET MVC 3 will be compiled against ASP.NET 4 only (no support for ASP.NET 3.5 planned) and we’ll be able to remove this “clever” code and have much more straightforward code. I’m looking forward to that. :)&lt;/p&gt;

&lt;p&gt;In any case, the point of this post was to fulfill a promise I made in an earlier post where I said I’d give some more details on how ASP.NET MVC 2 works with the new Html encoding block feature.&lt;/p&gt;

&lt;p&gt;This is all behind-the-scenes detail that’s not necessary to understand to use ASP.NET MVC, but might be interesting to some of you. Especially those who ever find themselves in a situation where you need to support forward compatibility.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:509c7372-df19-4a8b-ac50-32d9909cddcb" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://haacked.com/tags/aspnetmvc/default.aspx" rel="tag"&gt;aspnetmvc&lt;/a&gt;, &lt;a href="http://haacked.com/tags/reflection+emit/default.aspx" rel="tag"&gt;reflection emit&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18655.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=P177HHXQCxE:8fIC8LNtnjo:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=P177HHXQCxE:8fIC8LNtnjo:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=P177HHXQCxE:8fIC8LNtnjo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=P177HHXQCxE:8fIC8LNtnjo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=P177HHXQCxE:8fIC8LNtnjo:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/11/03/html-encoding-nuggets-aspnetmvc2.aspx</guid>
            <pubDate>Wed, 04 Nov 2009 05:56:49 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18655.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/11/03/html-encoding-nuggets-aspnetmvc2.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18655.aspx</wfw:commentRss>
        </item>
        <item>
            <title>ASP.NET 4 Web Server Here Shell Extension</title>
            <category>ASP.NET</category>
            <link>http://haacked.com/archive/2009/10/27/aspnet4-webserver-here-shell-extension.aspx</link>
            <description>&lt;p&gt;Have you ever needed to quickly spawn a web server against a local folder to preview a web application? If not, &lt;a title="What would you say, you do here?" href="http://www.youtube.com/watch?v=iKa68kWkP48&amp;amp;feature=related"&gt;what would you say you do here&lt;/a&gt;?&lt;/p&gt;  &lt;p&gt;This is actually quite common for me since I receive a lot of zip files containing web applications which reproduce a bug. After I unzip the repro, I need a way to quickly point a web server at the folder and run the web site.&lt;/p&gt;  &lt;p&gt;A while back I wrote about &lt;a title="VS2008 Web Server Here Shell Extension" href="http://haacked.com/archive/2008/06/24/vs2008-web-server-here-shell-extension.aspx"&gt;a useful registry hack&lt;/a&gt; to do just this. It adds a right click menu to start a web server (Cassini) pointing to any folder. This was based on a &lt;a title="ASP.NET 2.0 Web Server Here" href="http://weblogs.asp.net/rmclaws/archive/2005/10/25/428422.aspx"&gt;shell extension by Robert McLaws&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Well that was soooo 2008. It’s almost 2010 and Visual Studio 2010 Beta 2 is out which means it’s time to update this shell extension to run an ASP.NET 4 web server.&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="add-web-server-here" border="0" alt="add-web-server-here" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/ASP.NET4WebServerHereShellExtension_91C4/add-web-server-here_3.png" width="348" height="176" /&gt; &lt;/p&gt;  &lt;p&gt;Obviously this is not rocket science as I merely copied my old settings and updated the paths. But if you’re too lazy to look up the new file paths, you can just copy these settings (changes are in bold).&lt;/p&gt;  &lt;h3&gt;32 bit (x86)&lt;/h3&gt;  &lt;pre&gt;Windows Registry Editor Version 5.00
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell\&lt;strong&gt;VS2010 &lt;/strong&gt;WebServer]
@="ASP.NET &lt;strong&gt;4&lt;/strong&gt; Web Server Here"
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell\&lt;strong&gt;VS2010&lt;/strong&gt; WebServer\command]
@="C:\\Program Files\\Common Files\\microsoft shared\\DevServer
\\&lt;strong&gt;10&lt;/strong&gt;.0\\Webdev.WebServer&lt;strong&gt;40&lt;/strong&gt;.exe /port:808&lt;strong&gt;1&lt;/strong&gt; /path:\"%1\""&lt;/pre&gt;

&lt;h3&gt;64 bit (x64)&lt;/h3&gt;

&lt;pre&gt;Windows Registry Editor Version 5.00
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell\&lt;strong&gt;VS2010 &lt;/strong&gt;WebServer]
@="ASP.NET &lt;strong&gt;4&lt;/strong&gt; Web Server Here"
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell\&lt;strong&gt;VS2010&lt;/strong&gt; WebServer\command]
@="C:\\Program Files (x86)\\Common Files\\microsoft shared\\DevServer
\\&lt;strong&gt;10&lt;/strong&gt;.0\\Webdev.WebServer&lt;strong&gt;40&lt;/strong&gt;.exe /port:808&lt;strong&gt;1&lt;/strong&gt; /path:\"%1\""&lt;/pre&gt;

&lt;p&gt;I chose a different port and name for this shell extension so that it lives side-by-side with my other one.&lt;/p&gt;

&lt;p&gt;Of course, I wouldn’t even bother trying to copy these settings from this blog post since I conveniently &lt;strong&gt;&lt;a title="ASP.NET 4 Webserver Here" href="http://haacked.com/code/AspNet4WebServerHereRegistry.zip"&gt;zipped up .reg files you can run&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:d7abe494-0fc8-4523-b797-043bc128a3cf" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://haacked.com/tags/asp.net/default.aspx" rel="tag"&gt;asp.net&lt;/a&gt;, &lt;a href="http://haacked.com/tags/asp.net+4/default.aspx" rel="tag"&gt;asp.net 4&lt;/a&gt;, &lt;a href="http://haacked.com/tags/cassini/default.aspx" rel="tag"&gt;cassini&lt;/a&gt;, &lt;a href="http://haacked.com/tags/webdev.webserver/default.aspx" rel="tag"&gt;webdev.webserver&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18652.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=63bhXpZ8W_s:tVeUxxeFl8M:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=63bhXpZ8W_s:tVeUxxeFl8M:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=63bhXpZ8W_s:tVeUxxeFl8M:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=63bhXpZ8W_s:tVeUxxeFl8M:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=63bhXpZ8W_s:tVeUxxeFl8M:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/10/27/aspnet4-webserver-here-shell-extension.aspx</guid>
            <pubDate>Wed, 28 Oct 2009 04:52:17 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18652.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/10/27/aspnet4-webserver-here-shell-extension.aspx#feedback</comments>
            <slash:comments>14</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18652.aspx</wfw:commentRss>
        </item>
        <item>
            <title>VS10 Beta 2 From an ASP.NET MVC Perspective</title>
            <category>ASP.NET MVC</category>
            <category>ASP.NET</category>
            <link>http://haacked.com/archive/2009/10/20/vs10beta2-and-aspnetmvc.aspx</link>
            <description>&lt;p&gt;You probably don’t need me to tell you that &lt;a title="VS 2010 and .NET 4.0 Beta 2" href="http://weblogs.asp.net/scottgu/archive/2009/10/19/vs-2010-and-net-4-0-beta-2.aspx"&gt;Visual Studio 2010 Beta 2 has been released&lt;/a&gt; as it’s been blogged to death all over the place. Definitely check out the many blog posts out there if you want more details on what’s included.&lt;/p&gt;  &lt;p&gt;This post will focus more on what Visual Studio 2010 means to ASP.NET MVC and vice versa.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Important: If you installed ASP.NET MVC for Visual Studio 2010 Beta 1, make sure to uninstall it (and VS10 Beta 1) before installing Beta 2.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h3&gt;In the box baby!&lt;/h3&gt;  &lt;p&gt;Well one of the first things you’ll notice is that &lt;a title="ASP.NET MVC 2 Preview 2" href="http://haacked.com/archive/2009/10/01/asp.net-mvc-preview-2-released.aspx"&gt;ASP.NET MVC 2 Preview 2&lt;/a&gt; is included in VS10 Beta 2. When you select the File | New menu option, you’ll be greeted with an ASP.NET MVC 2 project template option under the Web node.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/WhatVisualStudio2010Beta2Meansfor.NETMVC_12658/New%20Project_4.png" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="New Project" border="0" alt="New Project" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/WhatVisualStudio2010Beta2Meansfor.NETMVC_12658/New%20Project_thumb_1.png" width="524" height="276" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Note that when you create your ASP.NET MVC 2 project with Visual Studio 2010, you can choose whether you wish to target ASP.NET 3.5 or ASP.NET 4.&lt;/p&gt;  &lt;p&gt;&lt;img title="multi-target" border="0" alt="multi-target" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/WhatVisualStudio2010Beta2Meansfor.NETMVC_12658/multi-target_3.png" width="412" height="247" /&gt; &lt;/p&gt;  &lt;p&gt;If you choose to target ASP.NET 4, you’ll be able to take advantage of the new &lt;a title="HTML Encoding Code Blocks" href="http://haacked.com/archive/2009/09/25/html-encoding-code-nuggets.aspx"&gt;HTML encoding code blocks&lt;/a&gt; with ASP.NET MVC which I wrote about earlier.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;As an aside, you might find it interesting that the &lt;code&gt;System.Web.Mvc.dll&lt;/code&gt; assembly we shipped in VS10 is the exact same binary we shipped out-of-band for VS2008 and .NET 3.5. How then does that assembly implement an interface that is new in ASP.NET 4? That’s a subject for another blog post.&lt;/em&gt;&lt;/p&gt;  &lt;h3&gt;What about ASP.NET MVC 1.0?&lt;/h3&gt;  &lt;p&gt;Unfortunately, we have no plans to support ASP.NET MVC 1.0 tooling in Visual Studio 2010. When we were going through planning, we realized it would’ve taken a lot of work to update our 1.0 project templates. We felt that time would be better spent focused on ASP.NET MVC 2.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;However, that doesn’t mean you can’t develop an ASP.NET MVC 1.0 application with Visual Studio 2010!&lt;/em&gt; All it means is you’ll have to do so without the nice ASP.NET MVC specific tooling such as the &lt;em&gt;add controller &lt;/em&gt;and&lt;em&gt; add view &lt;/em&gt;dialogs. After all, at it’s core, an ASP.NET MVC project is a Web Application Project.&lt;/p&gt;  &lt;p&gt;&lt;a title="Eilon Lipton's Blog" href="http://weblogs.asp.net/leftslipper/" rel="friend met co-worker"&gt;Eilon Lipton&lt;/a&gt;, the lead dev for ASP.NET MVC, wrote a blog post a while back describing &lt;a title="Opening ASP.NET MVC project" href="http://weblogs.asp.net/leftslipper/archive/2009/01/20/opening-an-asp-net-mvc-project-without-having-asp-net-mvc-installed-the-project-type-is-not-supported-by-this-installation.aspx"&gt;how to open an ASP.NET MVC project without having ASP.NET MVC installed&lt;/a&gt;. All it requires is for you to edit the .csproj file and remove the following GUID from the &lt;code&gt;&amp;lt;ProjectTypeGuids&amp;gt;&lt;/code&gt; element.&lt;/p&gt;  &lt;p&gt;&lt;code&gt;{603c0e0b-db56-11dc-be95-000d561079b0};&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;Once you do that, you’ll be able to open, code, and debug your project from VS10.&lt;/p&gt;  &lt;h3&gt;Upgrading ASP.NET MVC 1.0 to ASP.NET MVC 2&lt;/h3&gt;  &lt;p&gt;Another option is to upgrade your ASP.NET MVC 1.0 application to ASP.NET MVC 2 and then open the upgraded project with Visual Studio 2010 Beta 2.&lt;/p&gt;  &lt;p&gt;Eilon has your back again as he’s written a handy little &lt;a title="Migrating ASP.NET MVC 1.0 applications to ASP.NET MVC 2" href="http://weblogs.asp.net/leftslipper/archive/2009/10/19/migrating-asp-net-mvc-1-0-applications-to-asp-net-mvc-2.aspx"&gt;tool for upgrading existing ASP.NET MVC 1.0 applications to version 2&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;After using this tool, your project will still be a Visual Studio 2008 project. But you can then open it with VS10 and it knows how to open and upgrade the project to be a VS10 project.&lt;/p&gt;  &lt;h3&gt;What about automatic upgrades?&lt;/h3&gt;  &lt;p&gt;We are investigating implementing a more automatic process for upgrading ASP.NET MVC 1.0 applications to ASP.NET MVC 2 when you try to open the existing project in Visual Studio 2010. We plan to have something in place by the RTM of VS10.&lt;/p&gt;  &lt;p&gt;Ideally, when you try to open an ASP.NET MVC 1.0 project, instead of showing an error dialog, VS10 will provide a wizard to upgrade the project which will be somewhat based on the sample Eilon provided. So be sure to supply feedback on his wizard soon!&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:d9ea3060-3eb5-4495-a514-697080ed93e4" class="wlWriterSmartContent"&gt;Tags: &lt;a href="http://haacked.com/tags/aspnetmvc/default.aspx" rel="tag"&gt;aspnetmvc&lt;/a&gt;, &lt;a href="http://haacked.com/tags/asp.net/default.aspx" rel="tag"&gt;asp.net&lt;/a&gt;, &lt;a href="http://haacked.com/tags/visual+studio+2010/default.aspx" rel="tag"&gt;visual studio 2010&lt;/a&gt;, &lt;a href="http://haacked.com/tags/visual+studio/default.aspx" rel="tag"&gt;visual studio&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18651.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=mtpn1TfZhrg:Rj903ZACNr8:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=mtpn1TfZhrg:Rj903ZACNr8:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=mtpn1TfZhrg:Rj903ZACNr8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=mtpn1TfZhrg:Rj903ZACNr8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=mtpn1TfZhrg:Rj903ZACNr8:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/10/20/vs10beta2-and-aspnetmvc.aspx</guid>
            <pubDate>Wed, 21 Oct 2009 04:30:10 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18651.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/10/20/vs10beta2-and-aspnetmvc.aspx#feedback</comments>
            <slash:comments>21</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18651.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Announcing Let Me Bing That For You</title>
            <category>Humor</category>
            <category>Personal</category>
            <link>http://haacked.com/archive/2009/10/16/announcing-let-me-bing-that-for-you.aspx</link>
            <description>&lt;p&gt;Despite what your well intentioned elementary school teachers would have liked you to believe, &lt;strong&gt;there &lt;em&gt;is&lt;/em&gt; such a thing as a stupid question&lt;/strong&gt;, and you probably get them all the time via email or IM.&lt;/p&gt;  &lt;p&gt;You also know that in half the time it takes to type the question, the person pestering you could have typed the query in their favorite search engine and received an answer immediately.&lt;/p&gt;  &lt;p&gt;&lt;a title="Let Me Google That For You" href="http://lmgtfy.com/"&gt;Let me Google that for you&lt;/a&gt; addressed this little annoyance by providing a passive aggressive means to tell annoying question askers to bugger off while at the same time teaching them the power of using a search engine to help themselves.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/AnnouncingLetMeBingThatForYou_D717/lmbtfy_6.png" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Let Me Bing That For You" border="0" alt="Let Me Bing That For You" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/AnnouncingLetMeBingThatForYou_D717/lmbtfy_thumb_2.png" width="520" height="405" /&gt;&lt;/a&gt;When I first heard about the Microsoft’s new search engine, &lt;a title="Bing" href="http://bing.com/"&gt;Bing&lt;/a&gt;, I jumped at purchasing the domain name &lt;a title="Let Me Bing That For You" href="http://letmebingthatforyou.com/"&gt;http://letmebingthatforyou.com/&lt;/a&gt; (&lt;em&gt;though I was remiss in not also registering lmbtfy.com as well. If you own that domain, may I buy it off of you?&lt;/em&gt;)&lt;/p&gt;  &lt;p&gt;Unfortunately, being way too busy caused me to leave the domain name unused gathering dust until I put out a call on Twitter for help. Not long after &lt;a title="Maarten's Blog" href="http://blog.maartenballiauw.be/"&gt;Maarten Balliauw&lt;/a&gt; and &lt;a title="JHannsen's blog" href="http://hanssens.org/"&gt;Juliën Hanssens&lt;/a&gt; answered the call and put together the bulk of this ASP.NET MVC application using jQuery and jQuery UI.&lt;/p&gt;  &lt;p&gt;I really like what they did in that the background image for &lt;a title="Let Me Bing That For You" href="http://letmebingthatforyou.com/"&gt;http://letmebingthatforyou.com/&lt;/a&gt; changes daily to match the one on bing.com. I finally found some time to review the code, do a bit of clean-up, fix some minor issues, and test it so I am now ready to deploy it.&lt;/p&gt;  &lt;p&gt;Keep in mind that even though I’m employed by Microsoft, this site is a pet project I’m doing on the side in collaboration with Maarten and Juliën and is in not associated with Microsoft nor Bing in any official capacity. We’re just some folks doing this for fun.&lt;/p&gt;  &lt;p&gt;Now &lt;a title="Let Me Bing That For You" href="http://letmebingthatforyou.com/"&gt;&lt;strong&gt;go try it out&lt;/strong&gt;&lt;/a&gt; and release your inner snarkiness.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:6f0a5b21-e310-45e0-b3de-b4136367b22c" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://haacked.com/tags/bing/default.aspx" rel="tag"&gt;bing&lt;/a&gt;, &lt;a href="http://haacked.com/tags/fun/default.aspx" rel="tag"&gt;fun&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18650.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=phrj1K0pqV4:urxQ1RtDyMM:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=phrj1K0pqV4:urxQ1RtDyMM:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=phrj1K0pqV4:urxQ1RtDyMM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=phrj1K0pqV4:urxQ1RtDyMM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=phrj1K0pqV4:urxQ1RtDyMM:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/10/16/announcing-let-me-bing-that-for-you.aspx</guid>
            <pubDate>Sat, 17 Oct 2009 03:51:07 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18650.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/10/16/announcing-let-me-bing-that-for-you.aspx#feedback</comments>
            <slash:comments>37</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18650.aspx</wfw:commentRss>
        </item>
        <item>
            <title>ASP.NET MVC 1.0 Scripts Available on Microsoft CDN</title>
            <category>ASP.NET MVC</category>
            <category>ASP.NET</category>
            <link>http://haacked.com/archive/2009/10/15/aspnetmvc-cdn-hosted-scripts.aspx</link>
            <description>&lt;p&gt;A little while ago, Scott Guthrie announced &lt;a title="Microsoft Ajax CDN" href="http://weblogs.asp.net/scottgu/archive/2009/09/15/announcing-the-microsoft-ajax-cdn.aspx"&gt;the launch of the Microsoft Ajax CDN&lt;/a&gt;. In his post he talked about how ASP.NET 4 will have support for the CDN as well as the list of scripts that are included.&lt;/p&gt;  &lt;p&gt;The good news today is due to the hard work of &lt;a title="Stephen Walther" href="http://stephenwalther.com/blog/archive/2009/09/16/microsoft-ajax-cdn-and-the-jquery-validation-library.aspx"&gt;Stephen Walther and the ASP.NET Ajax team&lt;/a&gt;, they’ve added a couple of new scripts to the CDN which are near and dear to my heart, the ASP.NET MVC 1.0 scripts. The following code snippet shows how you can start using them today. &lt;/p&gt;  &lt;div class="dropshadow code"&gt;   &lt;div class="innerbox"&gt;     &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;="http://ajax.microsoft.com/ajax/3.5/MicrosoftAjax.js"&lt;/span&gt;
 &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="text/javascript"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;="http://ajax.microsoft.com/ajax/mvc/1.0/MicrosoftMvcAjax.js"&lt;/span&gt;
 &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="text/javascript"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;Debug versions are also available on the CDN.&lt;/p&gt;

&lt;div class="dropshadow code"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;="http://ajax.microsoft.com/ajax/3.5/MicrosoftAjax.debug.js"&lt;/span&gt;
 &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="text/javascript"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;="http://ajax.microsoft.com/ajax/mvc/1.0/MicrosoftMvcAjax.debug.js"&lt;/span&gt;
 &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="text/javascript"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;As ScottGu wrote,&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p class="clear"&gt;The Microsoft AJAX CDN makes it really easy to add the jQuery and ASP.NET AJAX script libraries to your web sites, and have them be automatically served from one of our thousands of geo-located edge-cache servers around the world.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We currently don’t have the ASP.NET MVC 2 scripts available on the CDN, but that’s something we can consider as we get closer and closer to RTM.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:2b986baf-4dab-4f55-b9f3-fd63ce2b81e1" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://haacked.com/tags/aspnetmvc/default.aspx" rel="tag"&gt;aspnetmvc&lt;/a&gt;, &lt;a href="http://haacked.com/tags/ajax/default.aspx" rel="tag"&gt;ajax&lt;/a&gt;, &lt;a href="http://haacked.com/tags/cdn/default.aspx" rel="tag"&gt;cdn&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18649.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=3rDvus_hums:aGvCdboJNJ8:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=3rDvus_hums:aGvCdboJNJ8:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=3rDvus_hums:aGvCdboJNJ8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=3rDvus_hums:aGvCdboJNJ8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=3rDvus_hums:aGvCdboJNJ8:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/10/15/aspnetmvc-cdn-hosted-scripts.aspx</guid>
            <pubDate>Fri, 16 Oct 2009 03:56:02 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18649.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/10/15/aspnetmvc-cdn-hosted-scripts.aspx#feedback</comments>
            <slash:comments>18</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18649.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Software Externalities</title>
            <category>Software Development</category>
            <link>http://haacked.com/archive/2009/10/13/software-externalities.aspx</link>
            <description>&lt;p&gt;If you’re a manufacturing plant, one way to maximize profit is to keep costs as low as possible. One way to do that is to cut corners. Go ahead and dump that toxic waste into the river and pollute the heck out of the air with your smoke stacks. These options are much cheaper than installing smoke scrubbers or trucking waste to proper disposal sites.&lt;/p&gt;  &lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="pollutions" border="0" alt="pollutions" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/SoftwareExternalities_80FB/pollutions_3.jpg" width="524" height="350" /&gt; &lt;/p&gt;  &lt;p&gt;Of course, economists have long known that this does not paint the entire picture. Taking these shortcuts incur other costs, it’s just that these costs are not borne by the manufacturing plant. The term &lt;a title="Externalities on Wikipedia" href="http://en.wikipedia.org/wiki/Externality"&gt;externalities&lt;/a&gt; describes such spillover costs.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;In economics an externality or spillover of an economic transaction is an impact on a party that is not directly involved in the transaction. In such a case, prices do not reflect the full costs or benefits in production or consumption of a product or service.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Thus the full cost of manufacturing includes the hospital bills of those who get sick by drinking the tainted water, the cost of the crops damaged by the acid rain, etc.&lt;/p&gt;  &lt;p&gt;Software is the same way. I got to thinking about this after reading Ted’s latest post that &lt;a title="Ted's blog post" href="http://blogs.tedneward.com/CommentView,guid,53f9b658-3b27-4f1a-b93e-14d3a57a8ec1.aspx#commentstart"&gt;Agile is treating the symptoms not the disease&lt;/a&gt; where the complexity that Agile introduces is disparaged and Access is held up as one example of a great “simple” way to develop applications.&lt;/p&gt;  &lt;p&gt;I agree that Access is great when you’re building a little database to track Billy’s baseball cards. However, the real world doesn’t stay that simple. As the &lt;a title="Second Law of Thermodynamics" href="http://blogs.tedneward.com/CommentView,guid,53f9b658-3b27-4f1a-b93e-14d3a57a8ec1.aspx#commentstart"&gt;second law of thermodynamics&lt;/a&gt; states (paraphrasing here), &lt;strong&gt;entropy tends to increase over time&lt;/strong&gt;, which is something that Ted doesn’t address in his discussion.&lt;/p&gt;  &lt;p&gt;I’m all for simplicity in our tools and methodologies as I think we still have a lot of room for improvement in reducing &lt;a title="Accidental Complexit in Wikipedia" href="http://en.wikipedia.org/wiki/Accidental_complexity"&gt;accidental complexity&lt;/a&gt;. Unfortunately, the business processes for which we build software are not simple at all and full of &lt;a title="Inherent Complexity" href="http://en.wikipedia.org/wiki/Essential_complexity"&gt;inherent complexity&lt;/a&gt;. Oh sure, they may start off as a simple Access database, but they never stay that simple. Every business I’ve ever interacted had very complex sets of business processes, some seemingly &lt;a title="Cargo Cult" href="http://en.wikipedia.org/wiki/Cargo_cult"&gt;cargo cultish&lt;/a&gt; in origin, which led to major complexity in business processes.&lt;/p&gt;  &lt;p&gt;Ted mentions friends of his who’ve made a healthy living using simple tools to build simple line-of-business apps for customers. And I’m sure they did a fine job of it. But I also made a healthy living in the past coming in to clean up the externalities left by such applications.&lt;/p&gt;  &lt;p&gt;I remember one rescue operation for a company drowning in the complexity of a “simple” Access application they used to run their business. It was simple until they started adding new business processes they needed to track. It was simple until they started &lt;em&gt;emailing copies around &lt;/em&gt;and were unsure which was the “master copy”. Not to mention all the data integrity issues and difficulty in changing the monolithic procedural application code.&lt;/p&gt;  &lt;p&gt;I also remember helping a teachers union who started off with a simple attendance tracker style app (to use an example Ted mentions) and just scaled it up to an atrociously complex Access database with stranded data and manual processes where they printed excel spreadsheets to paper, then manually entered it into another application. &lt;em&gt;I have to wonder, why is that little school district in western Pennsylvania engaging in custom software development in the first place? I don’t engage in developing custom school curricula. An even simpler option is to buy some off the shelf software or simply use a Wiki, but I digress.&lt;/em&gt; &lt;/p&gt;  &lt;p&gt;These were apps that would make The Daily WTF look like paragons of good software development in comparison.&lt;/p&gt;  &lt;p&gt;The core problem here is that while it’s fine to push for simpler tools to reduce accidental complexity, at one point or another we are going to have to deal with inherent complexity caused by entropy. Business processes are inherently complex, usually more than they need to be, and &lt;strong&gt;this is not a problem that will be solved by any software&lt;/strong&gt;. Most are not only inherently complex, but chock-full of accidental complexity as well. Your line of business app won’t solve that. It takes systemic change in the organization to make that happen.&lt;/p&gt;  &lt;p&gt;Not only that, but business processes get more complex over time as entropy sets in. The applications I mentioned dealt with this entropy and reached a point where the current solution could not scale to meet that new level of complexity (a different sort of scaling up), so they started to drown in it, the original authors of the applications long gone off to create new apps with new externalities.&lt;/p&gt;  &lt;p&gt;Fortunately, the externalities of these applications didn’t cause cancer, but rather kept guys like me employed. Of course, it was a negative externality for the company who kept pumping cash to fix these applications.&lt;/p&gt;  &lt;p&gt;Ted paraphrases Billy suggesting that Agile requires even more complex tools, story cards, continuous integration servers, etc. This is an unfair characterization and misses the point of Agile. &lt;strong&gt;Agile is less about managing the complexity of an application itself and more about managing the complexity of building an application&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;A higher principle of agile is YAGNI (You ain’t gonna need it) until you need it. For example, the 1 to 2 guys in a garage probably don’t need a continuous integration server, stand up meetings, etc and any real agilist worth his or her salt would recognize that and not try to force unnecessary procedures on a team that didn’t need it.&lt;/p&gt;  &lt;p&gt;However, as the two garage dwellers start to grow the business and need to coordinate with more developers, such tools come in handy. As you grow a team beyond two people, the lines of communication start to grow exponentially, thus creating inherent complexity.  Looking at the cost of developing and maintaining an application over time is where you start to get a full picture of the true cost of building an application.&lt;/p&gt;  &lt;p&gt;As Robert Glass pointed out in &lt;a title="Facts and Fallacies of Software Engineering at Amazon" href="http://www.amazon.com/gp/product/0321117425?ie=UTF8&amp;amp;tag=youvebeenhaac-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0321117425"&gt;Facts and Fallacies of Software Engineering&lt;/a&gt;, research shows that &lt;strong&gt;maintenance typically consumes from 40 to 80 percent of software costs&lt;/strong&gt;, typically making it &lt;a title="Writing Maintainable Code" href="http://haacked.com/archive/2007/01/09/writing_maintainable_code.aspx"&gt;the dominant life cycle phase of a software project&lt;/a&gt;. Thus these so called “simple” solutions need to factor that in, or the customers will continually be left with the clean-up duty while the polluters have long since moved on.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:31beb348-7d9e-4957-82c5-8958fabe1b07" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://haacked.com/tags/software+development/default.aspx" rel="tag"&gt;software development&lt;/a&gt;, &lt;a href="http://haacked.com/tags/agile/default.aspx" rel="tag"&gt;agile&lt;/a&gt;, &lt;a href="http://haacked.com/tags/entropy/default.aspx" rel="tag"&gt;entropy&lt;/a&gt;, &lt;a href="http://haacked.com/tags/externalities/default.aspx" rel="tag"&gt;externalities&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18648.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=DEAut29DPDQ:bWSMtUngQIA:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=DEAut29DPDQ:bWSMtUngQIA:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=DEAut29DPDQ:bWSMtUngQIA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=DEAut29DPDQ:bWSMtUngQIA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=DEAut29DPDQ:bWSMtUngQIA:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/10/13/software-externalities.aspx</guid>
            <pubDate>Tue, 13 Oct 2009 18:19:14 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18648.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/10/13/software-externalities.aspx#feedback</comments>
            <slash:comments>23</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18648.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Introducing Mia Yokoyama Haack</title>
            <category>Personal</category>
            <link>http://haacked.com/archive/2009/10/07/introducing-mia.aspx</link>
            <description>&lt;p&gt;This morning at 3:17 AM, Mia Yokoyama Haack was born weighing in at 7lb 8.5 oz. Now my &lt;a title="World Domination Backup" href="http://haacked.com/archive/2009/04/07/my-little-world-domination-backup.aspx"&gt;world domination crew&lt;/a&gt; is complete!&lt;/p&gt;  &lt;p&gt; &lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/IntroducingMiaYokoyamaHaack_61E3/DSC_0013.jpg" rel="lightbox"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DSC_0013" border="0" alt="DSC_0013" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/IntroducingMiaYokoyamaHaack_61E3/DSC_0013_thumb.jpg" width="524" height="367" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Mia is a fast little one as labor started around 11 PM and she was delivered only four hours later!&lt;/p&gt;  &lt;p&gt;This time around, we did a water birth at a birthing center which involves the momma sitting in a big tub for the last part of labor and delivery, which made for a much more comfortable experience than last time. I think she’d definitely recommend it.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/IntroducingMiaYokoyamaHaack_61E3/DSC_0015.jpg" rel="lightbox"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DSC_0015" border="0" alt="DSC_0015" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/IntroducingMiaYokoyamaHaack_61E3/DSC_0015_thumb.jpg" width="514" height="772" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We were back home by 6:30 AM which just amazes me. Momma and Baby are doing well. I’m still getting over my cold, but I think the adrenaline of the whole experience helped a lot. :)&lt;/p&gt;&lt;img src="http://haacked.com/aggbug/18647.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=Bph3nTDVdpk:CXfzXNN3v3g:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=Bph3nTDVdpk:CXfzXNN3v3g:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=Bph3nTDVdpk:CXfzXNN3v3g:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=Bph3nTDVdpk:CXfzXNN3v3g:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=Bph3nTDVdpk:CXfzXNN3v3g:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/10/07/introducing-mia.aspx</guid>
            <pubDate>Wed, 07 Oct 2009 13:57:50 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18647.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/10/07/introducing-mia.aspx#feedback</comments>
            <slash:comments>99</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18647.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>
