<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/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>Delay's Blog</title><link>http://blogs.msdn.com/b/delay/</link><description>Silverlight, WPF, Windows Phone, Web Platform, .NET, and more...</description><dc:language>en</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>Happy Birthday, FeedWorm! [A simple, efficient (free!) Google Reader client for keeping up with RSS feeds on Windows Phone]</title><link>http://blogs.msdn.com/b/delay/archive/2012/06/25/happy-birthday-feedworm-a-simple-efficient-free-google-reader-client-for-keeping-up-with-rss-feeds-on-windows-phone.aspx</link><pubDate>Mon, 25 Jun 2012 19:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10323710</guid><dc:creator>David Anson</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10323710</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2012/06/25/happy-birthday-feedworm-a-simple-efficient-free-google-reader-client-for-keeping-up-with-rss-feeds-on-windows-phone.aspx#comments</comments><description>&lt;div class="delay"&gt;&lt;img style="border: 1px solid black; float: right; margin-left: 6px;" title="FeedWorm feed view" alt="FeedWorm feed view" src="http://dlaa.me/FeedWorm/FeedWorm-Feed-Portrait-Half.png" width="240" height="400" /&gt;
&lt;p&gt;A little over a year ago, I got tired of searching for a &lt;a href="http://www.google.com/reader/"&gt;Google Reader&lt;/a&gt; client on &lt;a href="http://www.microsoft.com/windowsphone/"&gt;Windows Phone&lt;/a&gt; that worked exactly how I wanted. So I started writing one myself. My plan was to create a simple, efficient app that began by doing as little as possible - and gradually add more advanced features as time allowed. My goal was to understand the complete end-to-end experience of writing and publishing an application in the phone ecosystem.&lt;/p&gt;
&lt;p&gt;I released the first version of &lt;a href="http://dlaa.me/FeedWorm/"&gt;FeedWorm&lt;/a&gt; one year ago &lt;strong&gt;today&lt;/strong&gt;. It was free then; it remains free now. And while FeedWorm has &lt;a href="http://twitter.com/#!/FeedWorm"&gt;a few more features&lt;/a&gt; today than when it started, it's still very much an exercise in minimalism (which helps keep it fast!).&lt;/p&gt;
&lt;p&gt;To be clear, there are plenty of good Google Reader clients in the Marketplace and if one of them already meets your needs, there's little reason to switch. But if you're looking for something different - and aren't very demanding - FeedWorm might right for you. &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;a href="http://dlaa.me/FeedWorm/"&gt;[Click here to learn more about FeedWorm]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p style="clear: both;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10323710" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Windows+Phone/">Windows Phone</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/FeedWorm/">FeedWorm</category></item><item><title>"If I have seen further, it is by standing on the shoulders of giants" [An alternate implementation of HTTP gzip decompression for Windows Phone]</title><link>http://blogs.msdn.com/b/delay/archive/2012/04/19/quot-if-i-have-seen-further-it-is-by-standing-on-the-shoulders-of-giants-quot-an-alternate-implementation-of-http-gzip-decompression-for-windows-phone.aspx</link><pubDate>Thu, 19 Apr 2012 16:56:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10295435</guid><dc:creator>David Anson</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10295435</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2012/04/19/quot-if-i-have-seen-further-it-is-by-standing-on-the-shoulders-of-giants-quot-an-alternate-implementation-of-http-gzip-decompression-for-windows-phone.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;The &lt;a href="http://en.wikipedia.org/wiki/HTTP"&gt;HTTP protocol&lt;/a&gt; supports &lt;a href="http://en.wikipedia.org/wiki/Data_compression"&gt;data compression&lt;/a&gt; of network traffic via the &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11"&gt;Content-Encoding header&lt;/a&gt;. Compressing network traffic is beneficial because it reduces the amount of data that needs to be transmitted over the network - and sending fewer bytes obviously takes less time! The tradeoff is that it takes a bit of extra work to &lt;em&gt;de&lt;/em&gt;compress the data, but because the bottleneck is nearly always network, HTTP compression should be a win pretty much every time. And when you're dealing with comparatively slow, unreliable networks like the ones used by cell phones, the advantages of compression are even more significant.&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: Because most networks are lossy and transfer data in &lt;a href="http://en.wikipedia.org/wiki/Packet_(information_technology)"&gt;packets&lt;/a&gt;, sending just &lt;em&gt;one&lt;/em&gt; fewer byte can be meaningful if it reduces the number of packets.&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You might reasonably expect that enabling compression for Windows Phone web requests is as simple as setting the &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.automaticdecompression.aspx"&gt;HttpWebRequest.AutomaticDecompression property&lt;/a&gt; available since .NET 2.0. Unfortunately, this property is &lt;strong&gt;not&lt;/strong&gt; supported by current versions of the Windows Phone platform, so it's up to application developers to add HTTP compression support themselves. Consequently, a number of home-grown solutions have cropped up.&lt;/p&gt;
&lt;p&gt;One popular example is &lt;a href="http://www.sharpgis.net/post/2011/05/29/GZIP-Compressed-Web-Requests-in-WP7.aspx"&gt;Morten Nielsen's GZipWebClient&lt;/a&gt;. Naturally, Morten didn't want to implement his own compression library, so he's using &lt;a href="http://sharpziplib.com/"&gt;SharpZipLib&lt;/a&gt; to do the heavy lifting. This is a great example of reuse, but it's important to note that SharpZipLib is licensed under the &lt;a href="http://en.wikipedia.org/wiki/Gpl"&gt;GNU General Public License (GPL)&lt;/a&gt; and some developers won't be comfortable with the implications of using GPL code in their own project. (For more on what those implications are, the &lt;a href="http://en.wikipedia.org/wiki/Gpl"&gt;Wikipedia article for GPL&lt;/a&gt; has a fairly detailed overview which includes mention of ambiguities around the definition of "derivative works".)&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: Of course, there are other options. Another popular library is &lt;a href="http://dotnetzip.codeplex.com/"&gt;DotNetZip&lt;/a&gt; which claims to be under the &lt;a href="http://opensource.org/licenses/ms-pl.html"&gt;MS-PL (Microsoft Public License)&lt;/a&gt;, the same permissive "do pretty much whatever you want with the code" license I use for this blog. However, a brief look at the license files it comes with suggests &lt;a href="http://dotnetzip.codeplex.com/SourceControl/changeset/view/81674#1579682"&gt;maybe that's&lt;/a&gt; not &lt;a href="http://dotnetzip.codeplex.com/SourceControl/changeset/view/81674#1638503"&gt;the whole story&lt;/a&gt; because there are at least four &lt;em&gt;other&lt;/em&gt; licenses called out there.&lt;/blockquote&gt;
&lt;p&gt;As you can probably tell, I'm not the biggest fan of lawyers, ambiguity, or unnecessary risk [ &lt;nobr&gt;:)&lt;/nobr&gt; ], so I'm always happy to have a simple, "no restrictions" solution - even if that means I have to create one myself. In this case, what I wanted was a way to decompress gzip data on Windows Phone &lt;em&gt;without&lt;/em&gt; needing a separate library. That's when I remembered &lt;strong&gt;another&lt;/strong&gt; of Morten's posts, this one &lt;a href="http://www.sharpgis.net/post/2009/04/22/REALLY-small-unzip-utility-for-Silverlight.aspx"&gt;about unzipping files under Silverlight&lt;/a&gt;. I figured that maybe if I &lt;a href="http://en.wikipedia.org/wiki/Reese%27s_Peanut_Butter_Cups"&gt;put the chocolate in the peanut butter&lt;/a&gt;, I could come up with a simple, dependency-free solution to the gzip problem on Windows Phone!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The basic idea is to create a bit of code that customizes the user's &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.webclient(v=vs.95).aspx"&gt;WebClient&lt;/a&gt;/&lt;a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest(v=vs.95).aspx"&gt;HttpWebRequest&lt;/a&gt; to add the &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3"&gt;Accept-Encoding&lt;/a&gt; header. Once that's in place, servers that support gzip automatically compress their response bodies. To decompress the downloaded response on the phone, another bit of code is used to wrap the compressed response stream in a &lt;a href="http://en.wikipedia.org/wiki/ZIP_(file_format)"&gt;ZIP archive&lt;/a&gt; and hand it off to &lt;a href="http://msdn.microsoft.com/en-us/library/cc190632(v=VS.95).aspx"&gt;Application.GetResourceStream&lt;/a&gt; which does the heavy lifting and provides access to the decompressed response stream. What's nice about this technique is that the decompression implementation is part of the Silverlight framework - meaning applications don't need to pull in a bunch of external code &lt;strong&gt;or&lt;/strong&gt; increase their size!&lt;/p&gt;
&lt;p&gt;I wanted this to be easy, so I've created a &lt;code&gt;WebClient&lt;/code&gt; subclass and all you have to do is change this:&lt;/p&gt;
&lt;pre style="color: #000000;"&gt;client = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; WebClient&lt;/span&gt;();&lt;/pre&gt;
&lt;p&gt;Into this:&lt;/p&gt;
&lt;pre style="color: #000000;"&gt;client = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; &lt;span style="background-color: yellow;"&gt;Gzip&lt;/span&gt;WebClient&lt;/span&gt;();&lt;/pre&gt;
&lt;p&gt;After which your application's HTTP requests will &lt;strong&gt;automatically&lt;/strong&gt; benefit from gzip compression!&lt;/p&gt;
&lt;p&gt;Of course, some people like to work a little closer to the metal and I've done a similar thing for the &lt;code&gt;HttpWebRequest&lt;/code&gt;/&lt;code&gt;HttpWebResponse&lt;/code&gt; crowd. Change this:&lt;/p&gt;
&lt;pre style="color: #000000;"&gt;request = &lt;span style="color: #2b91af;"&gt;WebRequest&lt;/span&gt;.CreateHttp(_uri);
request.BeginGetResponse(callback, request);
&lt;span style="color: #008000;"&gt;// ... &lt;/span&gt;response = (&lt;span style="color: #2b91af;"&gt;HttpWebResponse&lt;/span&gt;)request.EndGetResponse(result);
stream = response.GetResponseStream();
&lt;span style="color: #008000;"&gt;// ...&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Into this:&lt;/p&gt;
&lt;pre style="color: #000000;"&gt;request = &lt;span style="color: #2b91af;"&gt;WebRequest&lt;/span&gt;.CreateHttp(_uri);
request.BeginGet&lt;span style="background-color: yellow;"&gt;Compressed&lt;/span&gt;Response(callback, request);
&lt;span style="color: #008000;"&gt;// ... &lt;/span&gt;response = (&lt;span style="color: #2b91af;"&gt;HttpWebResponse&lt;/span&gt;)request.EndGetResponse(result);
stream = response.Get&lt;span style="background-color: yellow;"&gt;Compressed&lt;/span&gt;ResponseStream();
&lt;span style="color: #008000;"&gt;// ...&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;And you're set!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Great, that's all well and good, but &lt;em&gt;does any of this really matter&lt;/em&gt;? &lt;a href="http://en.wikipedia.org/wiki/Minimalism"&gt;Less is clearly more&lt;/a&gt;, but is there actually a noticeable difference when using gzip? I wanted to answer that question for myself, so the sample application for this post not only exercises the code I've written, it also acts as a simple, real-time performance report! The sample makes continuous requests for &lt;a href="http://microsoft.com/"&gt;http://microsoft.com/&lt;/a&gt; using &lt;code&gt;WebClient&lt;/code&gt;, standard &lt;code&gt;HttpWebRequest&lt;/code&gt;/&lt;code&gt;HttpWebResponse&lt;/code&gt;, my custom &lt;code&gt;GzipWebClient&lt;/code&gt;, my &lt;code&gt;Compressed&lt;/code&gt; helpers for &lt;code&gt;HttpWebRequest&lt;/code&gt;/&lt;code&gt;HttpWebResponse&lt;/code&gt;, and (optionally) Morten's &lt;code&gt;GZipWebClient&lt;/code&gt; (for comparison purposes). As the data is collected, it's charted via the &lt;a href="http://cesso.org/r/DVLinks"&gt;Silverlight Toolkit's Data Visualization library&lt;/a&gt; (&lt;a href="http://blogs.msdn.com/b/delay/archive/2010/08/04/why-didn-t-i-think-of-that-in-the-first-place-windows-phone-7-charting-example-updated-to-include-reusable-platform-consistent-style-and-templates.aspx"&gt;which I've previously shown running on Windows Phone&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Here's what it looks like running in the emulator using a wired connection:&lt;/p&gt;
&lt;img title="GzipDemo on Windows Phone" alt="GzipDemo on Windows Phone" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/5658.GzipDemo_2D00_Emulator.png" width="400" height="240" /&gt;
&lt;p&gt;In the chart above, you can clearly see which requests are using gzip and which aren't! Not only are the gzip-enabled requests noticeably faster &lt;em&gt;on average&lt;/em&gt;, they're nearly &lt;strong&gt;always&lt;/strong&gt; faster even in the worst case. What's more, while there's variability for both kinds of requests (that's part of how the internet works), the delta between best/worst times of gzip-compressed requests is smaller (i.e., they're more consistent).&lt;/p&gt;
&lt;p&gt;That's pretty compelling data, but the &lt;strong&gt;real&lt;/strong&gt; benefit comes when the phone's data connection is used. Here's the output from the same app using the cell network (via Excel this time):&lt;/p&gt;
&lt;img title="HTTP Request Performance" alt="HTTP Request Performance" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/0572.GzipDemo_2D00_Performance.png" width="554" height="315" /&gt;
&lt;p&gt;All our previous observations remain true - and are even more pronounced in this scenario. Gzip-compressed HTTP requests are &lt;em&gt;significantly&lt;/em&gt; faster (taking less than half the time) and more predictable than traditional requests for the same data.&lt;/p&gt;
&lt;p&gt;Awesome!&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: Based on the chart above, it seems reasonable to claim all three gzip solutions are equivalent. That said, if you squint just right, it looks like using &lt;code&gt;HttpWebRequest&lt;/code&gt; is - on average - marginally quicker than using &lt;code&gt;WebClient&lt;/code&gt; (as you'd expect; &lt;code&gt;WebClient&lt;/code&gt; calls &lt;code&gt;HttpWebRequest&lt;/code&gt; under the covers). Additionally, &lt;code&gt;SharpGIS.GZipWebClient&lt;/code&gt; appears to be - on average - very &lt;em&gt;slightly&lt;/em&gt; quicker than &lt;code&gt;Delay.GzipWebClient&lt;/code&gt; (which is also not surprising when you consider the hoops my code jumps through to avoid the external dependency). Bear in mind, though, that these differences only really show up at the millisecond level, and seem unlikely to be significant for most real-world scenarios.&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;a href="http://cesso.org/Samples/GzipDemo/GzipDemo.zip"&gt;[Click here to download the source code for the gzip helper classes and the sample application shown above]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;OR&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;a href="http://nuget.org/packages/Delay.GzipWebClient"&gt;[Click here to visit the NuGet gallery page for &lt;code&gt;Delay.GzipWebClient&lt;/code&gt; which contains the code for both gzip helper classes]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Using the code I've authored is quite easy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If you want to use &lt;code&gt;GzipWebClient&lt;/code&gt;, simply add the &lt;code&gt;GzipWebClient.cs&lt;/code&gt; and &lt;code&gt;GzipExtensions.cs&lt;/code&gt; files to your project, reference the &lt;code&gt;Delay&lt;/code&gt; namespace, and replace any instances of &lt;code&gt;WebClient&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you're a &lt;code&gt;HttpWebRequest&lt;/code&gt;/&lt;code&gt;HttpWebResponse&lt;/code&gt; fan, you only need to add &lt;code&gt;GzipExtensions.cs&lt;/code&gt; to your project, reference the &lt;code&gt;Delay&lt;/code&gt; namespace, and invoke the extension methods &lt;code&gt;HttpWebRequest.BeginGetCompressedResponse&lt;/code&gt; and &lt;code&gt;HttpWebResponse.GetCompressedResponseStream&lt;/code&gt; (as shown above).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;By default, the sample application does not include Morten's &lt;code&gt;GZipWebClient&lt;/code&gt; because I don't want to get into the business of distributing someone else's code. However it's easy to include - the following comment in &lt;code&gt;MainPage.xaml.cs&lt;/code&gt; tells you how:&lt;/p&gt;
&lt;pre style="color: #008000;"&gt;// For an additional scenario, un-comment the following line and install the "SharpGIS.GZipWebClient" NuGet package
//#define SHARPGIS&lt;/pre&gt;
&lt;p&gt;The code to use that assembly is already in the sample application; you just need to provide the bits if you want to try it out. &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The implementation of the gzip-to-ZIP wrapper is fairly straightforward: it reads the gzip-compressed response from the server, wraps it in a stream that represents a valid ZIP archive with a single file compressed using the &lt;a href="http://en.wikipedia.org/wiki/Deflate"&gt;deflate algorithm&lt;/a&gt; which both specifications share, and hands that off to the Silverlight framework to return a decompressed stream for that file. To be clear, the compressed data isn't altered - it's simply re-packaged into a format that's more useful. &lt;nobr&gt;:)&lt;/nobr&gt; If you're interested in the specifics, you'll probably want to familiarize yourself with the &lt;a href="http://tools.ietf.org/rfc/rfc1952.txt"&gt;gzip specification&lt;/a&gt; and the &lt;a href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT"&gt;ZIP file specification&lt;/a&gt; and then have a look at the code.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There are two minor inefficiencies in my code, one of which seems unavoidable and the other of which could be dealt with.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The unavoidable one - and the reason I think SharpZipLib might be a smidge quicker - is that the size/checksum data for the gzip data is provided at the &lt;strong&gt;end&lt;/strong&gt; of the download stream, but is needed at the &lt;strong&gt;beginning&lt;/strong&gt; of the wrapper stream. If the correct values aren't used, the ZIP wrapper will be rejected - but those values are not known until the entire response has been downloaded. Therefore, it's not possible for my implementation to proactively process the data while it is being downloaded; the download must be buffered instead. A decompression library won't suffer from this limitation and ought to be quicker as a result.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The avoidable inefficiency is that a single copy of the input data is made when creating the ZIP wrapper stream. To be clear, this is the &lt;em&gt;only&lt;/em&gt; time data is copied (I've structured the code so there isn't any buffer resizing, etc.), but it's not technically necessary because the ZIP wrapper stream &lt;em&gt;could&lt;/em&gt; operate directly from the download buffers. I may make this improvement in the future, but expect the performance difference to be negligible.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Compressing HTTP traffic is a pretty clear win for desktop applications - and an even bigger benefit for mobile apps communicating over slower, less reliable cellular networks. The Windows Phone platform doesn't make using gzip easy, but it's possible if you're sufficiently motivated. For people who aren't intimidated by licenses, there are already some good options for gzip - but for those who aren't comfortable with what's out there, I'm offering a &lt;strong&gt;new&lt;/strong&gt; option under one of the most permissive licenses around.&lt;/p&gt;
&lt;p&gt;I hope you find it useful!&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10295435" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Silverlight/">Silverlight</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Silverlight+Toolkit/">Silverlight Toolkit</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Windows+Phone/">Windows Phone</category></item><item><title>"I never did mind about the little things..." [Free HideShowDesktopButtonOnTaskbar utility hides the "Show desktop" button on the Windows taskbar]</title><link>http://blogs.msdn.com/b/delay/archive/2012/01/24/quot-i-never-did-mind-about-the-little-things-quot-free-hideshowdesktopbuttonontaskbar-utility-hides-the-quot-show-desktop-quot-button-on-the-windows-taskbar.aspx</link><pubDate>Tue, 24 Jan 2012 16:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10260132</guid><dc:creator>David Anson</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10260132</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2012/01/24/quot-i-never-did-mind-about-the-little-things-quot-free-hideshowdesktopbuttonontaskbar-utility-hides-the-quot-show-desktop-quot-button-on-the-windows-taskbar.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;Over the holidays, a relative emailed me the following rant:&lt;/p&gt;
&lt;blockquote&gt;Most of my conversation with technical support was to find out how to turn off the "Show desktop" icon in the lower right corner of the screen. This icon can be engaged by clicking on it or hovering over it (if you select Peek). On a desktop or a laptop this is NO PROBLEM. But on a tablet, there is no difference between clicking and hovering so Peek is meaningless. VERY OFTEN when using and holding the slate/tablet the heel of my thumb ever so gently touches the "Show desktop" icon and I am taken to the desktop in the middle of what I am doing. &lt;strong&gt;As I work, I am in constant fear of touching this icon.&lt;/strong&gt; I know that everything on my hard drive will not be erased if I do, but it is &lt;strong&gt;very annoying&lt;/strong&gt;. I went on the internet and found a program that turns the icon off and &lt;strong&gt;it worked (so it can be done)&lt;/strong&gt;, but then my antivirus program said that it was a THREAT AND ADVISED ME TO PUT IT IN A VAULT WHERE IT COULD NOT HARM MY COMPUTER. I agreed and the program was &lt;strong&gt;deleted&lt;/strong&gt;. &lt;!-- &lt;strong&gt;How Microsoft and Samsung could not see this as a problem is beyond my comprehension.&lt;/strong&gt; --&gt; I'm not the only one with this problem. The internet has many complaining about the "Show desktop" icon. &lt;!-- The solution is simple: Add the option to turn it off to the menu you get when you right-click on the icon.
Or add the option to turn it off to the list for turning system icons on or off (Notification Area Icons &amp;gt; System Icons). --&gt; MS allows me to turn the Clock and Volume icon off; why not the "Show Desktop" icon?????&lt;/blockquote&gt;
&lt;p&gt;If you want a somewhat more positive spin, &lt;a href="http://windows.microsoft.com/en-US/windows7/help/better-stronger-faster-the-windows-7-taskbar"&gt;"Aero Peek" and the "Show desktop" button are described in this article about new Windows 7 taskbar features&lt;/a&gt;. I don't use either myself, but a bit of internet searching confirmed &lt;a href="http://answers.microsoft.com/en-us/windows/forum/windows_7-desktop/windows-7-remove-show-desktop-button/6aeb5bad-0464-41ed-b347-bfbe36b3b696"&gt;some people &lt;em&gt;really&lt;/em&gt; don't like these features&lt;/a&gt;.&lt;/p&gt;
&lt;img title="&amp;quot;Show desktop&amp;quot; button" alt="&amp;quot;Show desktop&amp;quot; button" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/0363.HideShowDesktopButtonOnTaskbar_2D00_Example.png" width="113" height="87" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The best way to disable a feature is to use an officially supported mechanism - and the good news is that disabling Aero Peek is easy to do by following the &lt;a href="http://windows.microsoft.com/en-US/windows7/Temporarily-preview-the-desktop-using-Peek"&gt;directions "To turn off desktop previews" near the bottom of this article&lt;/a&gt;. However, I was &lt;strong&gt;not&lt;/strong&gt; able to find similar support for disabling the "Show desktop" button, so I resorted to looking for the next best thing: a &lt;a href="http://en.wikipedia.org/wiki/Group_policy"&gt;group policy setting&lt;/a&gt; or documented &lt;a href="http://en.wikipedia.org/wiki/Windows_registry"&gt;registry key&lt;/a&gt;. Unfortunately, I struck out there, too. But I &lt;em&gt;did&lt;/em&gt; find this &lt;a href="http://channel9.msdn.com/Shows/The-Defrag-Show/Defrag-Disable-Show-Desktop-Hide-User-Accounts-Accurate-Energy-Usage#time=06m25s"&gt;snippet from a Channel 9 video where Gov Maharaj confirms there's no built-in way to disable the button&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: The relevant discussion is interesting, so maybe have a look even if you're not opposed to the feature itself!&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Well, if there's no &lt;em&gt;official&lt;/em&gt; way to remove the "Show desktop" button and enough people want to do it, then it's time to start considering other solutions. According to the original rant (and the video discussion), there already &lt;strong&gt;are&lt;/strong&gt; third-party utilities for this purpose - although they're not supported by Microsoft. But it sounds like at least one of these tools might be &lt;a href="http://en.wikipedia.org/wiki/Malware"&gt;malware&lt;/a&gt;, so I'm not super enthusiastic about trying them out...&lt;/p&gt;
&lt;p&gt;Fortunately, I have a rudimentary understanding of both Windows and programming [ &lt;nobr&gt;:)&lt;/nobr&gt; ], so I wondered if the simplest, most obvious trick would work here. I coded it up one night while waiting for something to compile and was pleased to find that it &lt;strong&gt;worked&lt;/strong&gt;! So I've gone ahead and prettied the code up and am sharing a simple utility to get rid of the Windows 7 taskbar's "Show desktop" button:&lt;/p&gt;
&lt;a href="http://cesso.org/Samples/HideShowDesktopButtonOnTaskbar/HideShowDesktopButtonOnTaskbar.zip"&gt;&lt;img style="border: none;" title="HideShowDesktopButtonOnTaskbar icon" alt="HideShowDesktopButtonOnTaskbar icon" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/3678.HideShowDesktopButtonOnTaskbar_2D00_Icon.png" width="151" height="163" /&gt;&lt;/a&gt;
&lt;p&gt;&lt;strong&gt; &lt;a href="http://cesso.org/Samples/HideShowDesktopButtonOnTaskbar/HideShowDesktopButtonOnTaskbar.zip"&gt;[Click here to download the HideShowDesktopButtonOnTaskbar utility and its complete source code.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Of course, HideShowDesktopButtonOnTaskbar is just as &lt;em&gt;un&lt;/em&gt;supported and &lt;em&gt;un&lt;/em&gt;official as the other utilities out there - so why choose &lt;strong&gt;it&lt;/strong&gt;?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I've included the complete source code for HideShowDesktopButtonOnTaskbar, so you can review everything and re-compile it yourself if you're paranoid. Also, you can be pretty confident I'm not a &lt;a href="http://en.wikipedia.org/wiki/L33t"&gt;1337 ***&lt;/a&gt; trying to &lt;a href="http://en.wikipedia.org/wiki/Rootkit"&gt;root your box&lt;/a&gt;. &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HideShowDesktopButtonOnTaskbar makes &lt;strong&gt;no&lt;/strong&gt; persistent changes to the machine, so there are no lingering effects and a simple logoff is all it takes to restore everything to the way it was.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HideShowDesktopButtonOnTaskbar is simple, small, unobtrusive, and easy to use - just &lt;a href="http://windows.microsoft.com/en-US/windows7/Run-a-program-automatically-when-Windows-starts"&gt;add it to your Startup group&lt;/a&gt; to have it run every time you log into Windows!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Okay, enough with the goofy sales pitch... how about some developer notes?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;As I mentioned, HideShowDesktopButtonOnTaskbar works the simplest way you can imagine: it finds the window corresponding to the "Show desktop" button and hides it. Obviously, hidden windows aren't visible - but they also don't receive input (clicks or hover status), so although the taskbar is still listening for input messages, they don't get sent. Running HideShowDesktopButtonOnTaskbar a second time finds and &lt;strong&gt;un&lt;/strong&gt;hides the "Show desktop" button, restoring things back to how they started. Logging off disposes of the entire taskbar and logging back on creates a new one from scratch, so HideShowDesktopButtonOnTaskbar's changes don't persist.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;img style="float: right;" title="Spy++ of &amp;quot;Show desktop&amp;quot; button" alt="Spy++ of &amp;quot;Show desktop&amp;quot; button" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/0458.HideShowDesktopButtonOnTaskbar_2D00_Spy.png" width="459" height="450" /&gt;
&lt;p&gt;I figured out the right window class to target by using the handy-dandy &lt;a href="http://msdn.microsoft.com/en-us/library/dd460756.aspx"&gt;Spy++ Windows development tool&lt;/a&gt;. Specifically, I ran Spy++, clicked the "Find Window" tool, dragged the crosshairs over the "Show desktop" button, and hit OK. That showed the window hierarchy to the right beginning with the desktop window at the top and going down to the "Show desktop" button. Translating that into three nested calls to &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms633500.aspx"&gt;FindWindowEx&lt;/a&gt; was trivial, as was adding a call to &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548.aspx"&gt;ShowWindow&lt;/a&gt; to hide the window. Using &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms633530.aspx"&gt;IsWindowVisible&lt;/a&gt; to unhide the button when it was already hidden was just icing on the cake. &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: If the window hierarchy changes or if any of the hard-coded class names is different in a newer version of Windows, this will stop working... Yep, that's how it is with simple hacks like this - if it matters to anyone, I can always tweak things to accommodate.&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Because HideShowDesktopButtonOnTaskbar ended up being easy to write, I was looking for a bit more challenge and set out to make it small. Specifically, the executable is just 11,776 bytes - and 7,015 bytes of that is due to the icon! While I could have squeezed a few more bytes out if I felt like it, the big win was by not linking to the standard &lt;a href="http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx"&gt;C Run-Time library&lt;/a&gt; (the use of which results in a 41,472 byte file assuming static linking (i.e., &lt;a href="http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx"&gt;/MT&lt;/a&gt;) is used to remove the dependency on MSVCR100.dll). Eschewing the CRT is an advanced scenario, but it was easy to do for HideShowDesktopButtonOnTaskbar because it's so small and simple.&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: This is why the code's entry point is named &lt;code&gt;WinMainCRTStartup&lt;/code&gt; instead of the usual &lt;code&gt;WinMain&lt;/code&gt;. And by the way: if you're interested in reading more about what it means to get rid of the default CRT, &lt;a href="http://msdn.microsoft.com/library/bb985746.aspx"&gt;Matt Pietrek's classic "Reduce EXE and DLL Size with LIBCTINY.LIB"&lt;/a&gt; is a good place to start.&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Of course, everything has a price, and I needed to make two &lt;strong&gt;other&lt;/strong&gt; changes as a result of omitting the default CRT. Both are found in Visual Studio's project Properties, Configuration Properties, C/C++, Code Generation settings: changing &lt;a href="http://msdn.microsoft.com/en-us/library/8wtf2dfz.aspx"&gt;Basic Runtime Checks&lt;/a&gt; (known as &lt;code&gt;&amp;lt;BasicRuntimeChecks&amp;gt;&lt;/code&gt; in the &lt;code&gt;.vcxproj&lt;/code&gt; file) to Default (i.e., no /RTC? option) and changing &lt;a href="http://msdn.microsoft.com/en-us/library/8dbf701c.aspx"&gt;Buffer Security Check&lt;/a&gt; (&lt;code&gt;&amp;lt;BufferSecurityCheck&amp;gt;&lt;/code&gt;) to false (i.e., /GS-). Disabling these checks isn't something you should do in general (especially the latter), but HideShowDesktopButtonOnTaskbar takes no input, has no buffers, and is so simple that I'm (tentatively!) okay sacrificing these two security/resiliency measures.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The call to &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366705.aspx"&gt;HeapSetInformation / HeapEnableTerminationOnCorruption&lt;/a&gt; is almost definitely overkill - but it's good practice and so easy to add that I did so anyway (FYI that the default CRT call this automatically). Plus, doing this made me feel a little better about losing /GS. &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
If you're bothered by Windows 7's "Show desktop" button and are looking for a solution, maybe HideShowDesktopButtonOnTaskbar is the answer. If you're curious how a hack like this works or are looking to dabble with replacing the CRT in your own programs, there might be something of interest here. Either way, HideShowDesktopButtonOnTaskbar was a fun side project - I hope you like it! &lt;nobr&gt;:)&lt;/nobr&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The code:&lt;/p&gt;
&lt;pre style="color: #000000;"&gt;&lt;span style="color: #008000;"&gt;// Include system headers (at warning level 3 because they're not /Wall-friendly)&lt;/span&gt;&lt;span style="color: #0000ff;"&gt; #pragma warning&lt;/span&gt;(&lt;span style="color: #0000ff;"&gt;push&lt;/span&gt;, 3)
&lt;span style="color: #0000ff;"&gt;#include&lt;/span&gt;&lt;span style="color: #a31515;"&gt; &amp;lt;windows.h&amp;gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt; #pragma warning&lt;/span&gt;(&lt;span style="color: #0000ff;"&gt;pop&lt;/span&gt;)

&lt;span style="color: #008000;"&gt;// Disable harmless /Wall warning C4514 "unreferenced inline function has been removed"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt; #pragma warning&lt;/span&gt;(&lt;span style="color: #0000ff;"&gt;disable&lt;/span&gt;: 4514)

&lt;span style="color: #008000;"&gt;// Default entry point function&lt;/span&gt;&lt;span style="color: #0000ff;"&gt; int __stdcall&lt;/span&gt; WinMainCRTStartup()
{
 &amp;nbsp; &amp;nbsp;&lt;span style="color: #008000;"&gt;// Enable "terminate-on-corruption"&lt;/span&gt;
 &amp;nbsp; &amp;nbsp;(&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;)HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);

 &amp;nbsp; &amp;nbsp;&lt;span style="color: #008000;"&gt;// Find the "Show desktop" button/window (starting from the Desktop window)&lt;/span&gt;&lt;span style="color: #0000ff;"&gt; &amp;nbsp; &amp;nbsp;const&lt;/span&gt; HWND hwndTaskbar = FindWindowEx(NULL, NULL, TEXT(&lt;span style="color: #a31515;"&gt;"Shell_TrayWnd"&lt;/span&gt;), NULL);
 &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (NULL != hwndTaskbar)
 &amp;nbsp; &amp;nbsp;{
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt; HWND hwndNotify = FindWindowEx(hwndTaskbar, NULL, TEXT(&lt;span style="color: #a31515;"&gt;"TrayNotifyWnd"&lt;/span&gt;), NULL);
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (NULL != hwndNotify)
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt; HWND hwndShowDesktopButton = FindWindowEx(hwndNotify, NULL, TEXT(&lt;span style="color: #a31515;"&gt;"TrayShowDesktopButtonWClass"&lt;/span&gt;), NULL);
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (NULL != hwndShowDesktopButton)
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #008000;"&gt;// Toggle the visibility of the button&lt;/span&gt;&lt;span style="color: #0000ff;"&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;const int&lt;/span&gt; nCmdShow = IsWindowVisible(hwndShowDesktopButton) ? SW_HIDE : SW_SHOW;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;)ShowWindow(hwndShowDesktopButton, nCmdShow);
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
 &amp;nbsp; &amp;nbsp;}

 &amp;nbsp; &amp;nbsp;&lt;span style="color: #008000;"&gt;// Return 0 because a message loop wasn't entered&lt;/span&gt;&lt;span style="color: #0000ff;"&gt; &amp;nbsp; &amp;nbsp;return&lt;/span&gt; 0;
}&lt;/pre&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10260132" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Utilities/">Utilities</category></item><item><title>“Make things as simple as possible, but not simpler.” [ManagedMsiExec sample app shows how to use the Windows Installer API from managed code]</title><link>http://blogs.msdn.com/b/delay/archive/2012/01/09/make-things-as-simple-as-possible-but-not-simpler-managedmsiexec-sample-app-shows-how-to-use-the-windows-installer-api-from-managed-code.aspx</link><pubDate>Mon, 09 Jan 2012 17:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10254645</guid><dc:creator>David Anson</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10254645</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2012/01/09/make-things-as-simple-as-possible-but-not-simpler-managedmsiexec-sample-app-shows-how-to-use-the-windows-installer-api-from-managed-code.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/cc185688.aspx"&gt;Windows Installer&lt;/a&gt; is the installation and configuration service used by Windows to add and remove applications. (For more information, &lt;a href="http://en.wikipedia.org/wiki/Windows_Installer"&gt;Wikipedia has a great overview of Windows Installer&lt;/a&gt;, covering products, components, setup phases, permissions, etc..) In addition to exposing a &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa372860.aspx"&gt;rich, native API&lt;/a&gt;, Windows Installer comes with &lt;code&gt;msiexec.exe&lt;/code&gt;, a command-line tool that offers fine-grained control over the install/uninstall process.&lt;/p&gt;
&lt;p&gt;I wanted to familiarize myself with the use of the Windows Installer API from .NET, so I wrote a wrapper class to expose it to managed applications and then a simple program to exercise it. Unlike &lt;code&gt;msiexec.exe&lt;/code&gt; which can do all kinds of things, my &lt;code&gt;ManagedMsiExec&lt;/code&gt; supports only UI-less install and uninstall of a .MSI Windows Installer package (i.e., &lt;code&gt;/quiet&lt;/code&gt; mode). By default, &lt;code&gt;ManagedMsiExec&lt;/code&gt; provides simple status reporting on the command line and renders a text-based progress bar that shows how each phase is going. In its "verbose" mode, &lt;code&gt;ManagedMsiExec&lt;/code&gt; outputs the complete set of status/progress/diagnostic messages generated by Windows Installer (i.e., &lt;code&gt;/l*&lt;/code&gt;) so any problems can be investigated.&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: Although I haven't tested &lt;code&gt;ManagedMsiExec&lt;/code&gt; exhaustively, it's fundamentally just a thin wrapper around Windows Installer, so I'd &lt;em&gt;expect&lt;/em&gt; it to work for pretty much any MSI out there.&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here's how it looks when run:&lt;/p&gt;
&lt;pre&gt;C:\T&amp;gt;&lt;strong&gt;ManagedMsiExec&lt;/strong&gt;
SYNTAX: ManagedMsiExec &amp;lt;--Install|-i|--Uninstall|-u&amp;gt; Package.msi [--Verbose|-v]
Windows Installer result: 87 (INVALID_PARAMETER)&lt;/pre&gt;
&lt;p&gt;Doing a simple install:&lt;/p&gt;
&lt;pre&gt;C:\T&amp;gt;&lt;strong&gt;ManagedMsiExec -i Package.msi&lt;/strong&gt;
ManagedMsiExec: Installing C:\T\Package.msi
Windows Installer result: 0 (SUCCESS)&lt;/pre&gt;
&lt;p&gt;Doing a simple uninstall:&lt;/p&gt;
&lt;pre&gt;C:\T&amp;gt;&lt;strong&gt;ManagedMsiExec -u Package.msi&lt;/strong&gt;
ManagedMsiExec: Uninstalling C:\T\Package.msi
Windows Installer result: 0 (SUCCESS)&lt;/pre&gt;
&lt;p&gt;Using verbose mode to diagnose a failure:&lt;/p&gt;
&lt;pre&gt;C:\T&amp;gt;&lt;strong&gt;ManagedMsiExec -u Package.msi -v&lt;/strong&gt;
ManagedMsiExec: Uninstalling C:\T\Package.msi
ACTIONSTART: Action 18:31:21: INSTALL.
INFO: Action start 18:31:21: INSTALL.
COMMONDATA: 1: 0 2: 1033 3: 1252
PROGRESS:
PROGRESS: 1: 2 2: 189440
COMMONDATA: 1: 0 2: 1033 3: 1252
&lt;span style="text-decoration: underline;"&gt;INFO: This action is only valid for products that are currently installed.&lt;/span&gt;
C:\T\Package.msi
COMMONDATA: 1: 2 2: 0
COMMONDATA: 1: 2 2: 1
INFO: DEBUG: Error 2755:  Server returned unexpected error 1605 attempting to
 &amp;nbsp;install package C:\T\Package.msi.
ERROR: The installer has encountered an unexpected error installing this package.
 &amp;nbsp;This may indicate a problem with this package. The error code is 2755.
INFO: Action ended 18:31:21: INSTALL. Return value 3.
TERMINATE:
Windows Installer result: 1603 (INSTALL_FAILURE)&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Of note:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Msi.cs&lt;/code&gt;, the class containing a set of &lt;a href="http://msdn.microsoft.com/en-us/library/26thfadc.aspx"&gt;.NET platform invoke definitions&lt;/a&gt; for interoperating with the native &lt;code&gt;MSI.dll&lt;/code&gt; that exposes Windows Installer APIs. The collection of functions and constants in this file is not comprehensive, but it covers enough functionality to get simple scenarios working. Most of the definitions are straightforward, and all of them have &lt;a href="http://msdn.microsoft.com/en-us/library/b2s063f7.aspx"&gt;XML documentation comments&lt;/a&gt; (via MSDN) explaining their purpose. For convenience, many of the relevant Windows error codes from &lt;code&gt;winerror.h&lt;/code&gt; are exposed by the &lt;code&gt;ERROR&lt;/code&gt; enumeration.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ManagedMsiExec.cs&lt;/code&gt;, the sample application itself which works by calling the relevant &lt;code&gt;Msi&lt;/code&gt; APIs in the right order. Conveniently, a complete install can be done in as few as three calls: &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa370339.aspx"&gt;MsiOpenPackage&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa370090.aspx"&gt;MsiDoAction&lt;/a&gt;, and &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa370067.aspx"&gt;MsiCloseHandle&lt;/a&gt; (with &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa370391.aspx"&gt;MsiSetProperty&lt;/a&gt; an optional fourth for uninstall or customization). To provide a better command-line experience, the default UI for status reporting is customized via &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa370389.aspx"&gt;MsiSetInternalUI&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa370384.aspx"&gt;MsiSetExternalUI&lt;/a&gt;, and &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa370385.aspx"&gt;MsiSetExternalUIRecord&lt;/a&gt;. Implementing the handler for a &lt;code&gt;MsiSetExternalUI&lt;/code&gt; callback is easy because it is passed pre-formatted strings; parsing record structures in the handler for the &lt;code&gt;MsiSetExternalUIRecord&lt;/code&gt; callback requires a few more API calls (and a closer reading of the documentation!).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;&lt;strong&gt;Note&lt;/strong&gt;: When providing delegates to the &lt;code&gt;MsiSetExternalUI&lt;/code&gt; and &lt;code&gt;MsiSetExternalUIRecord&lt;/code&gt; methods, it's important to ensure they won't be garbage collected while still in use (or else the application will crash!). Because the managed instances are handed off to native code and have a lifetime that extends &lt;em&gt;beyond&lt;/em&gt; the function call itself, it's necessary to maintain a reference for the life of the application (or until the callback is unregistered). A common technique for maintaining such a reference is the &lt;a href="http://msdn.microsoft.com/en-us/library/system.gc.keepalive.aspx"&gt;GC.KeepAlive&lt;/a&gt; method (though &lt;code&gt;ManagedMsiExec&lt;/code&gt; simply stores its delegate references in a &lt;a href="http://msdn.microsoft.com/en-us/library/79b3xss3.aspx"&gt;static member&lt;/a&gt; for the same effect). Conveniently, the &lt;a href="http://msdn.microsoft.com/en-us/library/43yky316.aspx"&gt;callbackOnCollectedDelegate&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/d21c150d.aspx"&gt;managed debugging assistant&lt;/a&gt; can help identify lifetime problems during debugging&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;a href="http://cesso.org/Samples/ManagedMsiExec/ManagedMsiExec.zip"&gt;[Click here to download a pre-compiled executable along with the complete source code for the ManagedMsiExec sample.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The introduction of Windows Installer helped unify the way applications install on Windows and encapsulates a great deal of complexity that installers previously needed to deal with. The openness and comprehensiveness of the Windows Installer native API makes it easy for applications to orchestrate installs directly, and the power of .NET's interoperability support makes it simple for managed applications to do the same.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Msi&lt;/code&gt; class I'm sharing here should allow developers to get started with the Windows Installer API a bit more simply - as the &lt;code&gt;ManagedMsiExec&lt;/code&gt; sample demonstrates. The wrapper class and the sample are both pretty straightforward - I hope they're useful, informative, or at least somewhat interesting! &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10254645" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Utilities/">Utilities</category></item><item><title>"You are now up to date." [IfModifiedSinceWebClient makes it easy to keep a local file in sync with online content - and do so asynchronously]</title><link>http://blogs.msdn.com/b/delay/archive/2011/10/18/quot-you-are-now-up-to-date-quot-ifmodifiedsincewebclient-makes-it-easy-to-keep-a-local-file-in-sync-with-online-content-and-do-so-asynchronously.aspx</link><pubDate>Tue, 18 Oct 2011 17:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10227049</guid><dc:creator>David Anson</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10227049</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/10/18/quot-you-are-now-up-to-date-quot-ifmodifiedsincewebclient-makes-it-easy-to-keep-a-local-file-in-sync-with-online-content-and-do-so-asynchronously.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;Recently, I was working with a program that needs to cache the content of a network file on the local disk for faster, easier access. The network file is expected to change periodically according to an unpredictable schedule; the objective is to keep the local file in "close" sync with the online copy &lt;em&gt;without&lt;/em&gt; a lot of cost or complex protocols.&lt;/p&gt;
&lt;p&gt;The network content is static (when it's not changing!), so hosting it on a web server and accessing it via &lt;a href="http://en.wikipedia.org/wiki/Http"&gt;HTTP&lt;/a&gt; seems like a reasonable start. Implementation-wise, it turns out the file is needed &lt;em&gt;immediately&lt;/em&gt; when accessed, so downloading it on-demand is not an option due to the possibility of lengthy network delays or connectivity issues. Fortunately, it's okay to use an out-of-date version as long as there's a good chance the &lt;strong&gt;next&lt;/strong&gt; access will use the latest one. So a reasonable approach seems to be to wait for the local file to be needed, use it immediately in its current state, then update it to the latest version by asynchronously downloading the network file and replacing the local copy in the background.&lt;/p&gt;
&lt;img style="float: right;" alt="IfModifiedSinceWebClientDemo sample" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/4174.IfModifiedSinceWebClientDemo.png" width="384" height="286" /&gt;
&lt;p&gt;That approach satisfies the requirements of the scenario, but it's a &lt;em&gt;little&lt;/em&gt; wasteful because the local file is likely to be used &lt;strong&gt;much&lt;/strong&gt; more frequently than the online version gets updated - which means most of the downloads will end up being the &lt;em&gt;same&lt;/em&gt; version that's already cached locally! Fortunately, we can improve things easily: the &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25"&gt;HTTP specification defines the If-Modified-Since&lt;/a&gt; header for exactly this purpose! By including that header with the HTTP request, the server "knows" whether the local file is out of date. If so, it returns the data for the network file as usual - but if the network file has &lt;strong&gt;not&lt;/strong&gt; changed more recently, the web server returns a &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5"&gt;304 Not Modified&lt;/a&gt; result and &lt;strong&gt;no&lt;/strong&gt; content. This "short circuiting" of the HTTP response eliminates the need to send redundant data and reduces the network traffic to a single, short HTTP request/response pair.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;When implementing a solution like this with the .NET Framework, two approaches spring to mind. The first is to use the low-level &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx"&gt;HttpWebRequest&lt;/a&gt;/&lt;a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.aspx"&gt;HttpWebResponse&lt;/a&gt; classes and manage the entire operation directly. &lt;code&gt;HttpWebRequest&lt;/code&gt; has an &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.ifmodifiedsince.aspx"&gt;IfModifiedSince&lt;/a&gt; property that can be used to set the relevant HTTP header (and format it correctly), so this approach is straightforward and quite flexibile. However, it &lt;em&gt;also&lt;/em&gt; requires the caller to manage the transfer of bits from the source to the destination (including reading, writing, buffering, etc.), and that's not really code we want to write. The second approach is to use something like the higher-level &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx"&gt;WebClient&lt;/a&gt; class's &lt;a href="http://msdn.microsoft.com/en-us/library/ms144196.aspx"&gt;DownloadFileAsync&lt;/a&gt; method to do the entire download and call us back when everything has been taken care of. That seems preferable, so lets go ahead and set the &lt;code&gt;WebClient.IfModifiedSince&lt;/code&gt; property and... umm... wait... &lt;code&gt;WebClient&lt;/code&gt; doesn't &lt;strong&gt;have&lt;/strong&gt; an &lt;code&gt;IfModifiedSince&lt;/code&gt; property! And not only doesn't the property exist, you're not allowed to set it manually via the &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.webclient.headers.aspx"&gt;Headers&lt;/a&gt; property: &lt;em&gt;"In addition, some other headers are also restricted when using a WebClient object. These restricted headers include, but are not limited to the following: ... If-Modified-Since ..."&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Darn, I &lt;em&gt;really&lt;/em&gt; wanted to use &lt;code&gt;WebClient&lt;/code&gt; and avoid having to encode the &lt;code&gt;If-Modified-Since&lt;/code&gt; header myself. If only it were possible to tweak the way &lt;code&gt;WebClient&lt;/code&gt; initializes its underlying &lt;code&gt;HttpWebRequest&lt;/code&gt;, we'd be set... Hey, what about the &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.webclient.getwebrequest.aspx"&gt;WebClient.GetWebRequest&lt;/a&gt; method? Isn't this exactly what it's for? Yes, it &lt;strong&gt;is&lt;/strong&gt;! &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;To make this all work, I created &lt;code&gt;IfModifiedSinceWebClient&lt;/code&gt; which is a &lt;code&gt;WebClient&lt;/code&gt; subclass that adds an &lt;code&gt;IfModifiedSince&lt;/code&gt; property and overrides &lt;code&gt;GetWebRequest&lt;/code&gt; to set that &lt;a href="http://msdn.microsoft.com/en-us/library/system.datetime.aspx"&gt;DateTime&lt;/a&gt; value onto the underlying &lt;code&gt;HttpWebRequest&lt;/code&gt;. Unfortunately, there are two issues: the destination file gets deleted &lt;em&gt;before&lt;/em&gt; the download starts (so it ends up being 0 bytes when HTTP 304 is returned) and HTTP 304 is defined as a failure code, so &lt;code&gt;WebClient&lt;/code&gt; thinks a successful (&lt;a href="http://en.wikipedia.org/wiki/NOP"&gt;NOOP&lt;/a&gt;) download has failed. To address both issues and offer a seamless experience, &lt;code&gt;IfModifiedSinceWebClient&lt;/code&gt; exposes a custom &lt;code&gt;UpdateFileIfNewer&lt;/code&gt; method that's asynchronous (i.e., "fire and forget") and simple. Just pass it the path to a local file to create/update and a URI for the remote file. (You can optionally pass a "completed" method to be called with the result of the asynchronous update.) &lt;code&gt;UpdateFileIfNewer&lt;/code&gt; sets the &lt;code&gt;If-Modified-Since&lt;/code&gt; header and initiates a call to &lt;code&gt;DownloadFileAsync&lt;/code&gt;, providing a temporary file path. If the remote file is &lt;strong&gt;not&lt;/strong&gt; newer than the local one, no transfer occurs and the &lt;code&gt;UpToDate&lt;/code&gt; result is passed to the completion method. If the remote file &lt;strong&gt;is&lt;/strong&gt; newer (or the server doesn't support &lt;code&gt;If-Modified-Since&lt;/code&gt;), the local file will be replaced with the just-downloaded copy and the &lt;code&gt;Updated&lt;/code&gt; result will be returned. And if something goes wrong, the local file is left alone and the &lt;code&gt;Error&lt;/code&gt; result is used.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here's what a typical call looks like:&lt;/p&gt;
&lt;pre style="color: #000000;"&gt;&lt;span style="color: #0000ff;"&gt;private void&lt;/span&gt; MyMethod()
{
 &amp;nbsp; &amp;nbsp;&lt;span style="color: #008000;"&gt;// ...&lt;/span&gt;

 &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; localFile = &lt;span style="color: #a31515;"&gt;"LocalFile.txt"&lt;/span&gt;;
 &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; uri = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; Uri&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"http://example.com/NetworkFile.txt"&lt;/span&gt;);
 &amp;nbsp; &amp;nbsp;&lt;span style="color: #2b91af;"&gt;IfModifiedSinceWebClient&lt;/span&gt;.&lt;span style="background-color: yellow;"&gt;UpdateFileIfNewer&lt;/span&gt;(localFile, uri, UpdateFileIfNewerCompleted);
 &amp;nbsp; &amp;nbsp;&lt;span style="color: #008000;"&gt;// Note: Download occurs asynchronously&lt;/span&gt;

 &amp;nbsp; &amp;nbsp;&lt;span style="color: #008000;"&gt;// ...&lt;/span&gt;
}

&lt;span style="color: #0000ff;"&gt;private void&lt;/span&gt; UpdateFileIfNewerCompleted(&lt;span style="color: #2b91af;"&gt;IfModifiedSinceWebClient&lt;/span&gt;.&lt;span style="color: #2b91af;"&gt;UpdateFileIfNewerResult&lt;/span&gt; result)
{
 &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt; (result)
 &amp;nbsp; &amp;nbsp;{
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; IfModifiedSinceWebClient&lt;/span&gt;.&lt;span style="color: #2b91af;"&gt;UpdateFileIfNewerResult&lt;/span&gt;.Updated:
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #008000;"&gt;// ...&lt;/span&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; IfModifiedSinceWebClient&lt;/span&gt;.&lt;span style="color: #2b91af;"&gt;UpdateFileIfNewerResult&lt;/span&gt;.UpToDate:
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #008000;"&gt;// ...&lt;/span&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; IfModifiedSinceWebClient&lt;/span&gt;.&lt;span style="color: #2b91af;"&gt;UpdateFileIfNewerResult&lt;/span&gt;.Error:
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #008000;"&gt;// ...&lt;/span&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;;
 &amp;nbsp; &amp;nbsp;}
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;a href="http://cesso.org/Samples/IfModifiedSinceWebClientDemo/IfModifiedSinceWebClientDemo.zip"&gt;[Click here to download the source code for IfModifiedSinceWebClient and the sample application shown at the start of the post.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;em&gt; (Don't forget to update the sample's &lt;a href="http://en.wikipedia.org/wiki/Localhost"&gt;localhost&lt;/a&gt; test URI to a valid URI for your environment.) &lt;/em&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;IfModifiedSinceWebClient&lt;/code&gt; is a simple subclass that adds &lt;code&gt;If-Modified-Since&lt;/code&gt; functionality to the .NET Framework's &lt;code&gt;WebClient&lt;/code&gt;. But that's only half the battle - the &lt;code&gt;UpdateFileIfNewer&lt;/code&gt; method makes the "asynchronously update a file if necessary" scenario work by building on that with a temporary file, error detection, and result codes. The result is a seamless, unobtrusive way for an application to keep itself up to date with dynamically changing online content without incurring unnecessary network overhead. Although there are other, more sophisticated solutions to this problem, it's hard to beat the simplicity and compactness of &lt;code&gt;IfModifiedSinceWebClient&lt;/code&gt;!&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: For bonus points, &lt;code&gt;IfModifiedSinceWebClient&lt;/code&gt; could also set the local file's "last modified" time to the &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.29"&gt;Last-Modified&lt;/a&gt; value returned by the server. I haven't done so in the sample because it doesn't seem like the subtle time skew (between the client and server clocks) will matter in most cases. However, I reserve the right to change my mind if practical experience contradicts me. &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/blockquote&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10227049" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category></item><item><title>Don't make the audience sit through all your typo-ing [Overview of implementing an extension for WebMatrix - and the complete source code for the Snippets sample]</title><link>http://blogs.msdn.com/b/delay/archive/2011/10/05/don-t-make-the-audience-sit-through-all-your-typo-ing-overview-of-implementing-an-extension-for-webmatrix-and-the-complete-source-code-for-the-snippets-sample.aspx</link><pubDate>Wed, 05 Oct 2011 16:04:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10220570</guid><dc:creator>David Anson</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10220570</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/10/05/don-t-make-the-audience-sit-through-all-your-typo-ing-overview-of-implementing-an-extension-for-webmatrix-and-the-complete-source-code-for-the-snippets-sample.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/b/delay/archive/2011/09/13/make-it-your-own-webmatrix-s-new-extensibility-support-enables-developers-and-applications-to-customize-the-web-development-experience-to-their-liking.aspx"&gt;When I wrote about WebMatrix's new extensibility features a couple of posts back&lt;/a&gt;, I said I'd share the complete source code to Snippets, one of the sample extensions in the gallery. In this post, I'll be doing that along with explaining the overall extension model in a bit more detail. To begin with, here's the code so those of you who want to follow along at home can do so:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;a href="http://cesso.org/Samples/Snippets/Snippets.zip"&gt;[Click here to download the complete source code for the Snippets extension]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I created the Snippets extension by starting from the &lt;a href="http://cesso.org/Samples/WebMatrix2Beta/WebMatrixExtension.zip"&gt;"WebMatrix Extension" Visual Studio Project template&lt;/a&gt; I wrote about &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/09/13/make-it-your-own-webmatrix-s-new-extensibility-support-enables-developers-and-applications-to-customize-the-web-development-experience-to-their-liking.aspx"&gt;previously&lt;/a&gt;. When expanded, the project template automatically set up the right project references (i.e., &lt;code&gt;Microsoft.WebMatrix.Extensibility.dll&lt;/code&gt;) and build steps and created a functioning extension with a single Ribbon button. From there, creating Snippets was a simple matter of adding the functionality I wanted on top of that foundation. But more on that later - I want to go over the default code first.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The default project template extension&lt;/strong&gt;&lt;/p&gt;
&lt;img style="float: right;" alt="WebMatrix Extension project template" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/3036.WebMatrix2Beta_2D00_Template.png" width="252" height="273" /&gt;
&lt;p&gt;One key thing to notice is that the template-generated &lt;code&gt;WebMatrixExtension&lt;/code&gt; class derives from &lt;code&gt;ExtensionBase&lt;/code&gt;, a base class which implements WebMatrix's &lt;code&gt;IExtension&lt;/code&gt; interface and simplifies some of the work of dealing with it. In the interest of generality (and because it's just an interface), &lt;code&gt;IExtension&lt;/code&gt; doesn't do much beyond identifying a few required properties. &lt;code&gt;ExtensionBase&lt;/code&gt; builds on that to offer concrete collections for the &lt;a href="http://msdn.microsoft.com/en-us/library/9eekhta0"&gt;IEnumerable(T)&lt;/a&gt; properties, automatically &lt;a href="http://msdn.microsoft.com/en-us/library/dd460648.aspx"&gt;MEF&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.importattribute(VS.100).aspx"&gt;Import&lt;/a&gt;s the &lt;code&gt;IWebMatrixHost&lt;/code&gt; interface, creates an &lt;code&gt;OnWebMatrixHostChanged&lt;/code&gt; override, and so on. Of course, none of this is rocket science and the decision to use &lt;code&gt;ExtensionBase&lt;/code&gt; is completely up to you. But the whole reason it exists to make your life &lt;strong&gt;easier&lt;/strong&gt;, so I'd suggest at least giving it a chance. &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;p&gt;In order for an extension to be loaded by WebMatrix, it needs to be located in the right directory (more on that in the &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/09/13/make-it-your-own-webmatrix-s-new-extensibility-support-enables-developers-and-applications-to-customize-the-web-development-experience-to-their-liking.aspx"&gt;previous post&lt;/a&gt;) and it needs to MEF &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.exportattribute(VS.100).aspx"&gt;Export&lt;/a&gt; the &lt;code&gt;IExtension&lt;/code&gt; interface. You might think that &lt;code&gt;ExtensionBase&lt;/code&gt; should do the latter for you, but it doesn't because that might restrict your own class hierarchy (i.e., intermediary classes would advertise themselves as extensions even though they're not). Therefore, subclasses like the template-generated &lt;code&gt;WebMatrixExtension&lt;/code&gt; class need to explicitly export &lt;code&gt;IExtension&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With the groundwork out of the way, the basic functionality of the example extension is to add a Ribbon button and handle activation of that button to open the current web site in the browser. Providing content for the Ribbon is as easy as adding instances implementing the relevant interfaces (&lt;code&gt;IRibbonButton&lt;/code&gt;, &lt;code&gt;IRibbonMenuButton&lt;/code&gt;, &lt;code&gt;IRibbonGroup&lt;/code&gt;, etc.) to the generated class's &lt;code&gt;RibbonItemsCollection&lt;/code&gt;. It's important to do this exactly once (typically in the extension's constructor) because subsequent changes are not honored (FYI, that &lt;em&gt;may&lt;/em&gt; change in the future, but please don't count on it). Of course, you can &lt;em&gt;show&lt;/em&gt; and &lt;em&gt;hide&lt;/em&gt; Ribbon content whenever you wish; you just can't add or remove items after initialization. Again, there are simple, concrete subclasses for each of the relevant interfaces (&lt;code&gt;IRibbonButton&lt;/code&gt;-&amp;gt;&lt;code&gt;RibbonButton&lt;/code&gt;, etc.) so you don't need to spend time implementing these simple things yourself. And just like before, using the "helper implementations" is completely optional.&lt;/p&gt;
&lt;p&gt;Creating a &lt;code&gt;RibbonButton&lt;/code&gt; requires a label, an &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.aspx"&gt;ICommand&lt;/a&gt; implementation, and (optionally) a small/large image. The template's sample includes a couple of images already configured properly to provide a working example. Wiring up the images correctly is standard WPF, but the &lt;a href="http://msdn.microsoft.com/en-us/library/aa970069.aspx"&gt;pack URI syntax&lt;/a&gt; can be a little tricky and it's common to forget to change the build type of the image files to "Resource" - so that's already been done for you as a helpful reminder. &lt;nobr&gt;:)&lt;/nobr&gt; For its &lt;code&gt;ICommand&lt;/code&gt; implementation, the template sample uses a simple &lt;code&gt;DelegateCommand&lt;/code&gt; class (also included). The sample &lt;code&gt;DelegateCommand&lt;/code&gt; is very much in line with other implementations of &lt;a href="http://msdn.microsoft.com/en-us/library/ff654132.aspx"&gt;DelegateCommand&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx"&gt;RelayCommand&lt;/a&gt;. (Feel free to use whatever version you'd like; the sample &lt;code&gt;DelegateCommand&lt;/code&gt; exists simply to avoid introducing a dependency on a third-party library.) As you'd expect, the &lt;code&gt;ICommand&lt;/code&gt;'s &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.canexecute.aspx"&gt;CanExecute&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.canexecutechanged.aspx"&gt;CanExecuteChanged&lt;/a&gt; methods are used to dynamically enable/disable the button and its &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.execute.aspx"&gt;Execute&lt;/a&gt; method is called when the button is clicked.&lt;/p&gt;
&lt;p&gt;Yeah, it takes a while to describe what's going on, but there's hardly any &lt;em&gt;code&lt;/em&gt; at all! &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Snippets extension&lt;/strong&gt;&lt;/p&gt;
&lt;img style="float: right;" alt="Snippets extension in use" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/0131.WebMatrixSnippets_2D00_MenuButton.png" width="146" height="188" /&gt;
&lt;p&gt;With the foundation behind us, it's time to consider the Snippets extension itself - and for that, it's helpful to know what it does. Snippets was created with the typical demo scenario in mind: a presenter is showing off WebMatrix and wants to add a block of code to a document, but doesn't want to type it out in front of the audience because that can be slow and boring. Instead, he or she clicks on the Snippets button in the Ribbon, selects from a list of available snippets, and the relevant text is automatically inserted in the editor. Of course, individual snippets should be easy for the user to add or modify and they should allow small and large amounts of text as well as blank lines, etc..&lt;/p&gt;
&lt;p&gt;There are probably a hundred ways you could build this extension; here's how I've done it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Each snippet is stored as a text file (ex: "Empty DIV.txt") in the &lt;code&gt;Snippets&lt;/code&gt; folder of the user's &lt;code&gt;Documents&lt;/code&gt; folder (i.e., &lt;code&gt;&lt;nobr&gt;%USERPROFILE%\Documents\Snippets&lt;/nobr&gt;&lt;/code&gt;). The file's name identifies the snippet and its contents get added when the snippet is used. You can have as many or few snippet files as you'd like; they're read when the extension is loaded and cached. If there aren't any snippet files (or the &lt;code&gt;Snippets&lt;/code&gt; folder doesn't exist), the extension provides a simple message with instructions for how to set things up.&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: WebMatrix needs to be restarted in order for snippet changes to take effect. An obvious improvement would be for the Snippets extension to monitor the &lt;code&gt;Snippets&lt;/code&gt; directory for changes and apply them on the fly.&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Snippets user interface is a &lt;code&gt;RibbonMenuButton&lt;/code&gt; which contains a collection of &lt;code&gt;RibbonButton&lt;/code&gt; instances corresponding to each of the available snippets. When the &lt;code&gt;RibbonMenuButton&lt;/code&gt; is clicked, it automatically shows the &lt;code&gt;IRibbonButton&lt;/code&gt; instances from its &lt;code&gt;Items&lt;/code&gt;collection in a small, drop-down menu. When a selection is made, the menu is automatically closed.&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: A &lt;code&gt;RibbonSplitButton&lt;/code&gt; could have been used if there was a scenario where the user could click the top half of the button to perform a similar action (like inserting a default snippet).&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Snippets button only makes sense when the "Files" workspace is active (i.e., a document is being edited), so the extension listens to the &lt;code&gt;IWebMatrixHost.WorkspaceChanged&lt;/code&gt; event and shows/hides its Ribbon button according to whether the new workspace is an instance of the &lt;code&gt;IEditorWorkspace&lt;/code&gt; interface.&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: One of the bits of feedback we've gotten so far is that this scenario (i.e., "only available for a single workspace") is common and should be simplified. Yep, message received. &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To insert text into the document, Snippets invokes the &lt;code&gt;Paste&lt;/code&gt; command via the &lt;code&gt;IWebMatrixHost.HostCommands&lt;/code&gt; property. While it's possible to get and set editor text directly for more advanced scenarios, the &lt;code&gt;Paste&lt;/code&gt; command works nicely because the editor automatically updates the caret position, replaces selected text, etc.. The downside to using the (application-wide) &lt;code&gt;Paste&lt;/code&gt; command is that if the input focus isn't in the body of an open file, then the paste action will be directed elsewhere and won't work as it's meant to.&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: The editor interfaces are &lt;em&gt;almost&lt;/em&gt; rich enough to manage everything here and avoid using &lt;code&gt;Paste&lt;/code&gt;. However, there were a couple of glitches when I tried which led me to use the simpler paste approach for the sample.&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Input focus aside, one thing that's clear is that Snippets can never be added without an open document visible. To determine if that's the case, Snippets uses an unnamed host command to populate an instance of &lt;code&gt;IEditorContainer&lt;/code&gt;. If that fails or the &lt;code&gt;IEditorExt&lt;/code&gt; within is null, that means no document is open and Snippets knows to disable its Ribbon buttons.&lt;/p&gt;
&lt;p&gt;Unnamed host commands work just like named commands (i.e., &lt;code&gt;Paste&lt;/code&gt;), though they're a little harder to get to. The &lt;code&gt;HostCommands.GetCommand&lt;/code&gt; method exists for this purpose and allows the caller to pass a &lt;a href="http://en.wikipedia.org/wiki/Guid"&gt;GUID&lt;/a&gt;/ID for the command to return. The relevant code looks like this:&lt;/p&gt;
&lt;pre style="color: #000000;"&gt;&lt;span style="color: #808080;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Gets an IEditorExt instance if the editor is in use.&lt;/span&gt;
&lt;span style="color: #808080;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #808080;"&gt;/// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;IEditorExt reference.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; IEditorExt&lt;/span&gt; GetEditorExt()
{
 &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; editorContainer = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; EditorContainer&lt;/span&gt;();
 &amp;nbsp; &amp;nbsp;_editorContainerCommand = WebMatrixHost.HostCommands.GetCommand(&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; Guid&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"27a0f541-c86c-4f0b-b436-0b50bf9f7ef8"&lt;/span&gt;), 10);
 &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (_editorContainerCommand != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;)
 &amp;nbsp; &amp;nbsp;{
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;_editorContainerCommand.Execute(editorContainer);
 &amp;nbsp; &amp;nbsp;}

 &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; editorContainer.Editor;
}&lt;/pre&gt;
&lt;p&gt;Helper properties for this and other unnamed commands be added in the future. For now, FYI about a useful one. &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Although the &lt;code&gt;RibbonButton&lt;/code&gt; class supports a &lt;code&gt;parameter&lt;/code&gt; parameter for passing to the &lt;code&gt;ICommand&lt;/code&gt;'s &lt;code&gt;CanExecute&lt;/code&gt;/&lt;code&gt;Execute&lt;/code&gt; methods to provide additional context, this value is &lt;strong&gt;not&lt;/strong&gt; actually passed through in some cases. &lt;nobr&gt;:(&lt;/nobr&gt; This bug was found too late to fix for the Beta, but the good news is that it's easy to work around by creating a &lt;a href="http://en.wikipedia.org/wiki/Closure_(computer_science)"&gt;closure&lt;/a&gt; to capture the relevant parameter information instead. If you're not familiar with this technique, it involves defining an anonymous method that references the desired data; the compiler automatically captures the necessary values and passes them along when the delegate gets called.&lt;/p&gt;
&lt;p&gt;Here's what it looks like in the sample (using &lt;a href="http://en.wikipedia.org/wiki/Linq"&gt;LINQ&lt;/a&gt; to create the collection):&lt;/p&gt;
&lt;pre style="color: #000000;"&gt;&lt;span style="color: #008000;"&gt;// Create buttons for each snippet&lt;/span&gt;
&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; snippetsButtons = _snippets
 &amp;nbsp; &amp;nbsp;.Select(s =&amp;gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; RibbonButton&lt;/span&gt;(
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;s.Key,
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; DelegateCommand&lt;/span&gt;(
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(parameter) =&amp;gt; GetEditorExt() != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;,
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(parameter) =&amp;gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color: #008000;"&gt;// parameter is (incorrectly) null, so add this indirection for now&lt;/span&gt;
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;HandleSnippetInvoke(s.Value);
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}),
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;s.Value,
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;_snippetsImageSmall,
 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;_snippetsImageLarge));&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It turns out there's a subtle bug because of the following code in the sample:&lt;/p&gt;
&lt;pre style="color: #0000ff;"&gt;&lt;span style="color: #008000;"&gt;// Paste the snippet into the editor&lt;/span&gt;
var&lt;span style="color: #000000;"&gt; paste = WebMatrixHost.HostCommands.Paste;&lt;/span&gt;
if&lt;span style="color: #000000;"&gt; (paste.CanExecute(insertText))&lt;/span&gt;
&lt;span style="color: #000000;"&gt;{&lt;/span&gt;
&lt;span style="color: #000000;"&gt; &amp;nbsp; &amp;nbsp;paste.Execute(insertText);&lt;/span&gt;
&lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Note that Snippets is invoking a special flavor of the &lt;code&gt;Paste&lt;/code&gt; command by providing the text as the &lt;code&gt;parameter&lt;/code&gt; property for the &lt;code&gt;CanExecute&lt;/code&gt;/&lt;code&gt;Execute&lt;/code&gt; methods (meaning "paste &lt;em&gt;this&lt;/em&gt; text, please"). However, the underlying editor code is returning a &lt;code&gt;CanExecute&lt;/code&gt; result based on whether or not it could paste from the &lt;em&gt;clipboard&lt;/em&gt; (i.e., it's not honoring the meaning of the text parameter). Therefore, if the clipboard is empty or contains non-text data like a file, &lt;code&gt;CanExecute&lt;/code&gt; returns &lt;code&gt;false&lt;/code&gt; and Snippets isn't able to insert text.&lt;/p&gt;
&lt;p&gt;The easy workaround is to copy some text to the clipboard so the underlying implementation will return &lt;code&gt;true&lt;/code&gt; for &lt;code&gt;CanExecute&lt;/code&gt; and the specialized paste operation will be invoked.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Snippets is a small extension that builds on the default WebMatrix Extension project template to implement some useful (if limited) functionality. Its original purpose was to simplify demos, but if people find practical uses for it, that's great, too! &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;p&gt;But whether or not people &lt;strong&gt;use&lt;/strong&gt; it, the Snippets extension touches on enough interesting areas of extensibility that people can probably &lt;strong&gt;learn&lt;/strong&gt; from it. If you're getting started with WebMatrix extensions and are looking for a "real world" sample, I hope Snippets can be helpful. If you have feedback or questions - about Snippets or more generally - please let me know!&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10220570" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Web+Platform/">Web Platform</category></item><item><title>TextAnalysisTool.NET to Windows 8: "Y U no run me under .NET 4?" [How to avoid the "please install .NET 3.5" dialog when running older .NET applications on the Windows 8 Developer Preview]</title><link>http://blogs.msdn.com/b/delay/archive/2011/09/22/textanalysistool-net-to-windows-8-quot-y-u-no-run-me-under-net-4-quot-how-to-avoid-the-quot-please-install-net-3-5-quot-dialog-when-running-older-net-applications-on-the-windows-8-developer-preview.aspx</link><pubDate>Fri, 23 Sep 2011 03:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10215654</guid><dc:creator>David Anson</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10215654</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/09/22/textanalysistool-net-to-windows-8-quot-y-u-no-run-me-under-net-4-quot-how-to-avoid-the-quot-please-install-net-3-5-quot-dialog-when-running-older-net-applications-on-the-windows-8-developer-preview.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;I wrote &lt;a href="http://blogs.msdn.com/b/delay/archive/2007/06/21/powerful-log-file-analysis-for-everyone-releasing-textanalysistool-net.aspx"&gt;TextAnalysisTool.NET&lt;/a&gt; a number of years ago to streamline the task of analyzing large log files by creating an interactive experience that combines searching, filtering, and tagging and allow the user to quickly identify interesting portions of a large log file. Although .NET 2.0 was out at the time, I targeted .NET 1.1 because it was more widely available, coming &lt;a href="http://en.wikipedia.org/wiki/.NET_Framework_version_history"&gt;pre-installed on Windows Server 2003&lt;/a&gt; (the "latest and greatest" OS then). In the years since, I've heard from folks around the world running TextAnalysisTool.NET on subsequent Windows operating systems and .NET Framework versions. Because Windows and the .NET Framework do a great job maintaining backwards compatibility, the same TextAnalysisTool.NET binary has continued to work as-is for the near-decade since its initial release.&lt;/p&gt;
&lt;img alt="TextAnalysisTool.NET demonstration" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Components-PostAttachments/00-03-45-06-47/TextAnalysisTool.NET.gif" width="681" height="329" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;But the story changes with Windows 8! Although Windows 8 has the new .NET 4.5 pre-installed (including .NET 4.0 upon which it's based), it does &lt;strong&gt;not&lt;/strong&gt; include .NET 3.5 (and therefore .NET 2.0). While I can imagine some very sensible reasons for the Windows team to take this approach, it's inconvenient for existing applications because .NET 4 in this scenario does &lt;strong&gt;not&lt;/strong&gt; automatically run applications targeting an earlier framework version. What &lt;em&gt;is&lt;/em&gt; cool is that the &lt;a href="http://msdn.microsoft.com/en-us/windows/home/"&gt;public Windows 8 Developer Preview&lt;/a&gt; detects when an older .NET application is run and &lt;em&gt;automatically&lt;/em&gt; prompts the user to install .NET 3.5:&lt;/p&gt;
&lt;img alt="Windows 8 .NET 3.5 install prompt" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/1832.TAT_2D00_Windows8Net35InstallPrompt.png" width="334" height="271" /&gt;
&lt;p&gt;That's pretty slick and is a really nice way to bridge the gap. However, it's still kind of annoying for users as it may not always be practical for them to perform a multi-megabyte download the first time they try to run an older .NET program. So it would be nice if there were an easy way for older .NET applications to opt into running under the .NET 4 framework that's &lt;strong&gt;already&lt;/strong&gt; present on Windows 8...&lt;/p&gt;
&lt;p&gt;And there is! :) One aspect of .NET's "side-by-side" support involves using &lt;code&gt;.config&lt;/code&gt; files to specify which .NET versions an application is known to work with. (For more information, please refer to the MSDN article &lt;a href="http://msdn.microsoft.com/en-us/library/9w519wzk.aspx"&gt;How to: Use an Application Configuration File to Target a .NET Framework Version&lt;/a&gt;.) Consequently, improving the Windows 8 experience for TextAnalisisTool.NET should be as easy as creating a suitable &lt;code&gt;TextAnalysisTool.NET.exe.config&lt;/code&gt; file in the same folder as &lt;code&gt;TextAnalysisTool.NET.exe&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Specifically, the following should do the trick:&lt;/p&gt;
&lt;pre style="color: #0000ff;"&gt;&amp;lt;?&lt;span style="color: #a31515;"&gt;xml&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; version&lt;/span&gt;=&lt;span style="color: #000000;"&gt;"&lt;/span&gt;1.0&lt;span style="color: #000000;"&gt;"&lt;/span&gt;?&amp;gt;
&amp;lt;&lt;span style="color: #a31515;"&gt;configuration&lt;/span&gt;&amp;gt;
 &amp;nbsp;&amp;lt;&lt;span style="color: #a31515;"&gt;startup&lt;/span&gt;&amp;gt;
 &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span style="color: #a31515;"&gt;supportedRuntime&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; version&lt;/span&gt;=&lt;span style="color: #000000;"&gt;"&lt;/span&gt;v1.1.4322&lt;span style="color: #000000;"&gt;"&lt;/span&gt;/&amp;gt;
 &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span style="color: #a31515;"&gt;supportedRuntime&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; version&lt;/span&gt;=&lt;span style="color: #000000;"&gt;"&lt;/span&gt;v2.0.50727&lt;span style="color: #000000;"&gt;"&lt;/span&gt;/&amp;gt;
 &amp;nbsp; &amp;nbsp;&amp;lt;&lt;span style="color: #a31515;"&gt;supportedRuntime&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; version&lt;/span&gt;=&lt;span style="color: #000000;"&gt;"&lt;/span&gt;v4.0&lt;span style="color: #000000;"&gt;"&lt;/span&gt;/&amp;gt;
 &amp;nbsp;&amp;lt;/&lt;span style="color: #a31515;"&gt;startup&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style="color: #a31515;"&gt;configuration&lt;/span&gt;&amp;gt;&lt;/pre&gt;
&lt;p&gt;And it does! :) With that &lt;code&gt;TextAnalysisTool.NET.exe.config&lt;/code&gt; file in place, TextAnalysisTool.NET runs on a clean install of the Windows 8 Developer Preview as-is and &lt;strong&gt;without&lt;/strong&gt; prompting the user to install .NET 3.5. I've updated the download ZIP to include this file so new users will automatically benefit; existing users should drop &lt;code&gt;TextAnalysisTool.NET.exe.config&lt;/code&gt; in the right place, and they'll be set as well!&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: Although this trick will work in many cases, it isn't &lt;em&gt;guaranteed&lt;/em&gt; to work. In particular, if there has been a breaking change in .NET 4, then attempting to run a pre-.NET 4 application in this manner might fail. Therefore, it's prudent to do some verification when trying a change like this!&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;a href="http://cesso.org/Samples/TextAnalysisTool.NET/TextAnalysisTool.NET.zip"&gt;[Click here to download a ZIP file containing TextAnalysisTool.NET, the relevant .config file, its documentation, and a ReadMe.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;TextAnalysisTool.NET has proven to be extremely popular with support engineers and it's always nice to hear from new users. I hope today's post extends the usefulness of TextAnalysisTool.NET by making the Windows 8 experience as seamless as people have come to expect!&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10215654" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/TextAnalysisTool/">TextAnalysisTool</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Utilities/">Utilities</category></item><item><title>Make it your own [WebMatrix's new extensibility support enables developers and applications to customize the web development experience to their liking!]</title><link>http://blogs.msdn.com/b/delay/archive/2011/09/13/make-it-your-own-webmatrix-s-new-extensibility-support-enables-developers-and-applications-to-customize-the-web-development-experience-to-their-liking.aspx</link><pubDate>Wed, 14 Sep 2011 05:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10210534</guid><dc:creator>David Anson</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10210534</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/09/13/make-it-your-own-webmatrix-s-new-extensibility-support-enables-developers-and-applications-to-customize-the-web-development-experience-to-their-liking.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;In conjunction with Microsoft's ongoing &lt;a href="http://www.buildwindows.com/"&gt;BUILD Windows&lt;/a&gt; conference, we have just released betas of the next version of the &lt;a href="http://www.microsoft.com/web/platform/"&gt;Microsoft Web Platform&lt;/a&gt;. Today's releases include a &lt;strong&gt;lot&lt;/strong&gt; of new functionality and I encourage interested parties to have a look at what's new in &lt;a href="http://www.asp.net/vnext/whats-new"&gt;ASP.NET&lt;/a&gt; and &lt;a href="http://www.microsoft.com/web/webmatrix/next/"&gt;WebMatrix&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this post, I'm going to focus on one aspect of the &lt;strong&gt;WebMatrix 2 Beta&lt;/strong&gt;: extensibility. By exposing a public API and opening up the application to others, WebMatrix enables individuals and community members to customize the experience to best fit their own &lt;em&gt;unique&lt;/em&gt; processes and workflow. Many aspects of the development experience are configurable, so users can become more productive by streamlining common tasks, automating monotonous ones, and simplifying difficult ones!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;img style="float: right;" alt="Task-based extensibility" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/5466.WebMatrix2Beta_2D00_TBEX.png" width="300" height="203" /&gt;
&lt;p&gt;Extensibility for the WebMatrix 2 Beta takes three forms: task-based extensibility, help extensibility, and extensions.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Task-based extensibility refers to the ability of a web application like &lt;a href="http://umbraco.com/"&gt;Umbraco&lt;/a&gt; or &lt;a href="http://wordpress.org/"&gt;WordPress&lt;/a&gt; to embed a file within the install package to customize the WebMatrix user interface for that particular application. By providing some simple XML, applications in the &lt;a href="http://www.microsoft.com/web/gallery/"&gt;Web App Gallery&lt;/a&gt; can add custom links to the Ribbon or dashboard, protect core application files, provide enhanced Intellisense for PHP, and more.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Help extensibility makes it possible to integrate custom content with WebMatrix's new, context-sensitive help pane. The new help system shows links to relevant content and videos based on where the user is in the application and what he or she is doing. Help content is drawn from a variety of sources; content providers can create custom feeds to cover new topics or provide more context on existing ones. &lt;a href="http://learn.iis.net/page.aspx/1032/creating-a-content-feed-for-learning/"&gt;This article explains how to create custom help content.&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For developers, the real power lies in the ability to write extensions that run inside WebMatrix because they're capable of &lt;strong&gt;far&lt;/strong&gt; richer customization. WebMatrix extensions can be written in any .NET language, are loaded by &lt;a href="http://msdn.microsoft.com/en-us/library/dd460648.aspx"&gt;MEF, the Managed Extensibility Framework&lt;/a&gt;, and installed/uninstalled (behind the scenes) as &lt;a href="http://nuget.org/"&gt;NuGet&lt;/a&gt; packages (with a slight twist I'll explain in a different post). Similar to Visual Studio, WebMatrix has an extension gallery that allows users to browse and install extensions from a central feed - or create and share custom feeds!&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;img style="float: right; border: 1px solid gray;" alt="ColorThemeManager" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/0412.WebMatrix2Beta_2D00_ColorThemeEditor.png" width="300" height="210" /&gt;
&lt;p&gt;Opening WebMatrix's extension gallery (by clicking the "Extensions/Gallery" Ribbon button from the &lt;code&gt;Site&lt;/code&gt; workspace) shows some of the extensions that have been created to help give an idea what's possible. I'll call out three of them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ColorThemeManager&lt;/strong&gt; - This extension by &lt;a href="http://blogs.iis.net/yigalatz/"&gt;Yishai Galatzer&lt;/a&gt; allows you to customize the colors used by the file editor in WebMatrix, export your settings, and import settings from other sources. So if you're one of those people who enjoys looking at &lt;span style="background-color: black; color: lime;"&gt;green on black text&lt;/span&gt;, then you're in luck. &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ImageOptimizer&lt;/strong&gt; - This extension by &lt;a href="http://madskristensen.net/"&gt;Mads Kristensen&lt;/a&gt; makes it easy to "optimize" the PNG and JPEG images of a web site by removing unnecessary metadata and recompressing content to minimize file sizes - thereby keeping bandwidth down and site responsiveness up.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Snippets&lt;/strong&gt; - This extension by me makes it easy to insert snippets of text into an open document in the &lt;code&gt;Files&lt;/code&gt; workspace. It was written to make WebMatrix demos a little easier (watch for it in the &lt;a href="http://channel9.msdn.com/events/BUILD/BUILD2011/TOOL-825T"&gt;WebMatrix: uber geek in designer clothes&lt;/a&gt; presentation today at BUILD!), but its simplicity makes it a good learning tool, too. I'll be blogging the complete source code for Snippets in a few days.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;img style="float: right;" alt="WebMatrix Extension project template" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/3036.WebMatrix2Beta_2D00_Template.png" width="252" height="273" /&gt;
&lt;p&gt;In addition to providing an overview of the Snippets sample, I plan to discuss other aspects of WebMatrix extensibility over the next few weeks. In the meantime, you can start exploring WebMatrix extensibility &lt;strong&gt;today&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Download the &lt;strong&gt;&lt;a href="http://cesso.org/Samples/WebMatrix2Beta/Microsoft.WebMatrix.Extensibility.chm"&gt;Microsoft.WebMatrix.Extensibility CHM file&lt;/a&gt;&lt;/strong&gt;, unblock it (&lt;span style="color: red;"&gt;important&lt;/span&gt;: &lt;a href="http://blogs.msdn.com/b/delay/p/unblockingdownloadedfile.aspx"&gt;click here for directions on "unblocking" a file&lt;/a&gt;), open it, and browse the contents. &lt;em&gt;(If you see the message "Navigation to the webpage was canceled", then the file is still blocked.)&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Download the &lt;strong&gt;&lt;a href="http://cesso.org/Samples/WebMatrix2Beta/WebMatrixExtension.zip"&gt;"WebMatrix Extension" Visual Studio project template&lt;/a&gt;&lt;/strong&gt;, save the ZIP file in your &lt;code&gt;"%USERPROFILE%\Documents\Visual Studio 2010\Templates\ProjectTemplates"&lt;/code&gt; directory, choose &lt;strong&gt;File&lt;/strong&gt;, &lt;strong&gt;New&lt;/strong&gt;, &lt;strong&gt;Project&lt;/strong&gt; in Visual Studio 2010, select the "Visual C#" node, click the "WebMatrix Extension" item, type a project name (ex: "MyExtension" (no spaces, please)), and click OK.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The project template sets up the right infrastructure, all the necessary references, includes pre- and post-build rules to make development a little easier, and helps get you started with a simple Ribbon-based extension that demonstrates some of the basic extensibility points. The template's &lt;code&gt;ReadMe.txt&lt;/code&gt; explains how to configure Visual Studio so that pressing &lt;code&gt;F5&lt;/code&gt; will automatically load the extension &lt;em&gt;inside&lt;/em&gt; WebMatrix for a simple, seamless debugging experience with complete breakpoint support, etc.. FYI that I'd like to improve this template by adding support for NuGet package generation (so it will be easier to deploy extensions to a gallery) and maybe also create a VISX wrapper for it (to enable more seamless install of the template itself).&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: While the project template "helpfully" copies your extension to the right place for WebMatrix to load it on startup, the extension is &lt;strong&gt;not&lt;/strong&gt; properly installed and so WebMatrix doesn't know how to &lt;strong&gt;un&lt;/strong&gt;install it. For now, the easiest way to get rid of a custom extension is to close WebMatrix and delete the contents of the &lt;code&gt;"%USERPROFILE%\AppData\Local\Microsoft\WebMatrix\Components"&lt;/code&gt; directory.&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The new extensibility APIs in the WebMatrix 2 Beta allow developers to get started with extensions today. And while there aren't yet extension points for &lt;em&gt;everything&lt;/em&gt;, there are enough to enable some pretty interesting scenarios. Available extension points include:&lt;/p&gt;
&lt;img style="float: right;" alt="Microsoft.WebMatrix.Extensibility help file" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/6505.WebMatrix2Beta_2D00_CHM.png" width="300" height="200" /&gt;
&lt;ul&gt;
&lt;li&gt;Ribbon content&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Buttons, groups, tabs, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Application information&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Name, local path, remote URI&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Integrated dialog and notification UI&lt;/li&gt;
&lt;li&gt;Context menu items for application files/directories&lt;/li&gt;
&lt;li&gt;Editor manipulation&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Text buffer, settings, theming, custom types&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Dashboard content&lt;/li&gt;
&lt;li&gt;Simple commanding&lt;/li&gt;
&lt;li&gt;Active workspace&lt;/li&gt;
&lt;li&gt;More...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That said, people are going to have a lot of &lt;strong&gt;great&lt;/strong&gt; extension ideas that are either difficult or impossible to achieve with the Beta APIs. Not being able to put good ideas into practice is certainly disappointing, but it's also a great opportunity to let us know what features are missing from the API and how we can improve it! To make that easy, there's a &lt;a href="http://go.microsoft.com/fwlink/?LinkID=194793"&gt;WebMatrix forum where you can ask questions and exchange ideas&lt;/a&gt;. Once you've tried things out, please go there and share your thoughts!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: It probably goes without saying (but I'll say it anyway!) that the APIs available in the WebMatrix 2 Beta are subject to change and it's likely that extensions written for Beta will need to be modified in order to run on later releases. That's not to discourage people from writing extensions, but rather an attempt to set expectations appropriately. :)&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;strong&gt;Further aside&lt;/strong&gt;: It's natural to wonder if existing plugins for Visual Studio will "just work" in WebMatrix. The answer is that they will not - but in &lt;em&gt;most&lt;/em&gt; cases it turns out that trying to load a Visual Studio extension inside WebMatrix wouldn't be all that meaningful anyway... At this point, the functionality of these two products and the target audience (both users &lt;em&gt;and&lt;/em&gt; developers) are different enough that things don't align in a way that makes this scenario work.&lt;/blockquote&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10210534" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Web+Platform/">Web Platform</category></item><item><title>Know your place in life [Free PlaceImage control makes it easy to add placeholder images to any WPF, Silverlight, or Windows Phone application!]</title><link>http://blogs.msdn.com/b/delay/archive/2011/09/08/know-your-place-in-life-free-placeimage-control-makes-it-easy-to-add-placeholder-images-to-any-wpf-silverlight-or-windows-phone-application.aspx</link><pubDate>Thu, 08 Sep 2011 16:33:11 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10207954</guid><dc:creator>David Anson</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10207954</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/09/08/know-your-place-in-life-free-placeimage-control-makes-it-easy-to-add-placeholder-images-to-any-wpf-silverlight-or-windows-phone-application.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;One of the challenges with referencing online content is that you never know just how long it will take to download... On a good day, images show up immediately and your application has exactly the experience you want. On a bad day, images take a &lt;strong&gt;looong&lt;/strong&gt; time to load - or never load at all! - and your application's interface is full of blank spaces. Applications that make use of remote images need to be prepared for variability like this and should have "placeholder" content to display when the desired image isn't available.&lt;/p&gt;
&lt;p&gt;Of course, there are a variety of ways to deal with this; I thought it would be neat to create a reusable, self-contained class and share it here. I envisioned a simple control that "looked" like a standard &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.image.aspx"&gt;Image&lt;/a&gt; element (i.e., had the same API), but that seamlessly handled the work of displaying placeholder content before an image loaded and getting rid of it afterward. Naturally, I also wanted code that would run on WPF, Silverlight, &lt;strong&gt;and&lt;/strong&gt; Windows Phone! &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="color: #0000ff;"&gt;&amp;lt;&lt;span style="color: #a31515;"&gt;delay&lt;/span&gt;:&lt;span style="color: #a31515;"&gt;PlaceImage&lt;/span&gt;
&lt;span style="color: #ff0000;"&gt; PlaceholderSource&lt;/span&gt;="PlaceholderPhoto.png"
&lt;span style="color: #ff0000;"&gt; Source&lt;/span&gt;="{&lt;span style="color: #a31515;"&gt;Binding&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; ImageUri&lt;/span&gt;}"/&amp;gt;&lt;/pre&gt;
&lt;p&gt;The result of this exercise is something I've called &lt;code&gt;PlaceImage&lt;/code&gt;. &lt;code&gt;PlaceImage&lt;/code&gt; has the same API as the framework's &lt;code&gt;Image&lt;/code&gt; and can be dropped in pretty much anywhere an &lt;code&gt;Image&lt;/code&gt; is used. To enable the "placeholder" effect, simply set the &lt;code&gt;PlaceholderSource&lt;/code&gt; property to a suitable image. (&lt;strong&gt;Aside&lt;/strong&gt;: While you &lt;em&gt;could&lt;/em&gt; specify another remote image for the placeholder, the most sensible thing to do is to reference an image that's bundled with the application (e.g., as content or a resource).) &lt;code&gt;PlaceImage&lt;/code&gt; immediately shows your placeholder image and waits for the desired image to load - at which point, &lt;code&gt;PlaceImage&lt;/code&gt; swaps it in and gets rid of the placeholder!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I've written a sample application for each of the supported platforms that displays contact cards of imaginary employees. When the sample first runs, none of the remote images have loaded, so each card shows the "?" placeholder image:&lt;/p&gt;
&lt;img alt="PlaceImageDemo on Windows Phone" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/4747.PlaceImageDemo_2D00_WP.png" width="584" height="336" /&gt;
&lt;p&gt;After a while, some of the remote images will have loaded:&lt;/p&gt;
&lt;img alt="PlaceImageDemo on Silverlight" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/4834.PlaceImageDemo_2D00_SL.png" width="280" height="402" /&gt;
&lt;p&gt;Eventually, all the remote images load:&lt;/p&gt;
&lt;img alt="PlaceImageDemo on WPF" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/7077.PlaceImageDemo_2D00_WPF.png" width="254" height="378" /&gt;
&lt;p&gt;&lt;em&gt;&lt;small&gt;Thanks to &lt;a href="http://placekitten.com/"&gt;placekitten&lt;/a&gt; for the handy placeholder images!&lt;/small&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Making use of online content in an application is easy to do and a great way to enrich an application. However, the unpredictable nature of the network means content might not always be available when it's needed. &lt;code&gt;PlaceImage&lt;/code&gt; makes it easy to add placeholder images to common scenarios and helps keep the user interface free of blank spaces. With easy support for WPF, Silverlight, &lt;strong&gt;and&lt;/strong&gt; Windows Phone, you can add it to pretty much &lt;em&gt;any&lt;/em&gt; XAML-based application!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;a href="http://cesso.org/Samples/PlaceImageDemo/PlaceImageDemo.zip"&gt;[Click here to download the PlaceImageDemo project which includes PlaceImage.cs and sample applications for WPF, Silverlight, and Windows Phone.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Just like &lt;code&gt;Image&lt;/code&gt;, &lt;code&gt;PlaceImage&lt;/code&gt; has properties for &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.image.source.aspx"&gt;Source&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.image.stretch.aspx"&gt;Stretch&lt;/a&gt;, and &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.image.stretchdirection.aspx"&gt;StretchDirection&lt;/a&gt; (the last being available only on WPF). &lt;code&gt;PlaceImage&lt;/code&gt;'s additional &lt;code&gt;PlaceholderSource&lt;/code&gt; property is used just like &lt;code&gt;Source&lt;/code&gt; and identifies the placeholder image to be displayed before the &lt;code&gt;Source&lt;/code&gt; image is available. (So set it to a local image!)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Changes to the &lt;code&gt;Source&lt;/code&gt; property of a loaded &lt;code&gt;Image&lt;/code&gt; immediately clear its contents. Similarly, changing the &lt;code&gt;Source&lt;/code&gt; of a loaded &lt;code&gt;PlaceImage&lt;/code&gt; immediately switches to its placeholder image while the new remote content loads. You can trigger this behavior in the sample application by clicking any kitten.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Because the Silverlight version of the demo application references web content, it needs to be run from the &lt;code&gt;PlaceImageDemoSL&lt;strong&gt;.Web&lt;/strong&gt;&lt;/code&gt; project. (Although running &lt;code&gt;PlaceImageDemoSL&lt;/code&gt; &lt;em&gt;will&lt;/em&gt; show placeholders, the kitten pictures never load.) The MSDN article &lt;a href="http://msdn.microsoft.com/en-us/library/cc189008(v=VS.95).aspx"&gt;URL Access Restrictions in Silverlight&lt;/a&gt; has more information on Silverlight's "cross-scheme access" limitations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.control.aspx"&gt;Control&lt;/a&gt; subclasses typically live in a dedicated assembly and define their default &lt;a href="http://msdn.microsoft.com/en-us/library/ms745683.aspx"&gt;Style/Template&lt;/a&gt; in &lt;code&gt;Generic.xaml&lt;/code&gt;. This is a great, general-purpose model, but I wanted &lt;code&gt;PlaceImage&lt;/code&gt; to be easy to add to existing projects in source code form, so it does everything in a single file. All you need to do is include &lt;code&gt;PlaceImage.cs&lt;/code&gt; in your project, and &lt;code&gt;PlaceImage&lt;/code&gt; will be available in the &lt;code&gt;Delay&lt;/code&gt; namespace.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The absence of the &lt;code&gt;StretchDirection&lt;/code&gt; property on Silverlight and Windows Phone isn't the only platform difference &lt;code&gt;PlaceImage&lt;/code&gt; runs into: whereas Silverlight and Windows Phone offer the handy &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.image.imageopened(VS.95).aspx"&gt;Image.ImageOpened&lt;/a&gt; event, WPF has only the (more cumbersome) &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapsource.downloadcompleted.aspx"&gt;BitmapSource.DownloadCompleted&lt;/a&gt; event. The meaning of these two events isn't &lt;em&gt;quite&lt;/em&gt; identical, but for the purposes of &lt;code&gt;PlaceImage&lt;/code&gt;, they're considered equivalent.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10207954" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Silverlight/">Silverlight</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/WPF/">WPF</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Windows+Phone/">Windows Phone</category></item><item><title>Invisible pixels are just as clickable as real pixels! [Tip: Use a Transparent brush to make "empty" parts of a XAML element respond to mouse and touch input]</title><link>http://blogs.msdn.com/b/delay/archive/2011/08/18/invisible-pixels-are-just-as-clickable-as-real-pixels-tip-use-a-transparent-brush-to-make-quot-empty-quot-parts-of-a-xaml-element-respond-to-mouse-and-touch-input.aspx</link><pubDate>Fri, 19 Aug 2011 05:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10197637</guid><dc:creator>David Anson</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10197637</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/08/18/invisible-pixels-are-just-as-clickable-as-real-pixels-tip-use-a-transparent-brush-to-make-quot-empty-quot-parts-of-a-xaml-element-respond-to-mouse-and-touch-input.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p class="TipHeader"&gt;Tip&lt;/p&gt;
&lt;p class="TipTip"&gt;Use a Transparent brush to make "empty" parts of a XAML element respond to mouse and touch input&lt;/p&gt;
&lt;p class="TipHeader"&gt;Explanation&lt;/p&gt;
&lt;p&gt;I got a question yesterday and thought the answer would make a good addition to my &lt;a href="http://blogs.msdn.com/b/delay/archive/tags/development+tips/"&gt;Development Tips&lt;/a&gt; series. As you probably know, WPF, Silverlight, and Windows Phone support a rich, hierarchical way of laying out an application's UI. Elements can be created in &lt;a href="http://en.wikipedia.org/wiki/Xaml"&gt;XAML&lt;/a&gt; or in code and respond to input by firing the relevant events (&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.uielement.mouseleftbuttondown.aspx"&gt;MouseLeftButtonDown&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.buttonbase.click.aspx"&gt;Click&lt;/a&gt;, etc.). Input events bubble from the element "closest" to the user all the way up to the root element (stopping if an event is marked &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.routedeventargs.handled.aspx"&gt;Handled&lt;/a&gt;). Every now and then someone finds that an element they expect to be getting input is &lt;strong&gt;not&lt;/strong&gt; (and they've made sure none of its children are "eating" the event). The most common reason is that the element doesn't have any pixels for the user to click on! For example, in a 100x100 panel containing a short message, &lt;em&gt;only the text pixels&lt;/em&gt; are considered part of the panel and respond to mouse input - everything else passes "through" the empty area and bubbles up to the parent. This behavior enables the creation of elements with &lt;em&gt;any&lt;/em&gt; shape, but sometimes it's not what you want. Fortunately, it's simple to get empty parts of an element to respond to input: just draw some pixels! And while a &lt;a href="http://msdn.microsoft.com/en-us/library/ms743593.aspx"&gt;Brush&lt;/a&gt; of any color will do the trick, painting with &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.media.brushes.transparent.aspx"&gt;Transparent&lt;/a&gt; pixels is a fantastic way to keep empty space looking empty while &lt;strong&gt;also&lt;/strong&gt; being clickable!&lt;/p&gt;
&lt;p class="TipHeader"&gt;Good Example&lt;/p&gt;
&lt;pre style="color: #0000ff;"&gt;&amp;lt;&lt;span style="color: #a31515;"&gt;Grid&lt;/span&gt;
    &lt;span style="background-color: yellow;"&gt;&lt;span style="color: #ff0000;"&gt;Background&lt;/span&gt;="Transparent"&lt;/span&gt;
    &lt;span style="color: #ff0000;"&gt;MouseLeftButtonDown&lt;/span&gt;="Grid_MouseLeftButtonDown"&amp;gt;
    &amp;lt;&lt;span style="color: #a31515;"&gt;TextBlock&lt;/span&gt;
        &lt;span style="color: #ff0000;"&gt;Text&lt;/span&gt;="You can click anywhere in the Grid!"
        &lt;span style="color: #ff0000;"&gt;HorizontalAlignment&lt;/span&gt;="Center"
        &lt;span style="color: #ff0000;"&gt;VerticalAlignment&lt;/span&gt;="Center"/&amp;gt;
&amp;lt;/&lt;span style="color: #a31515;"&gt;Grid&lt;/span&gt;&amp;gt;&lt;/pre&gt;
&lt;p class="TipHeader"&gt;More information&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/aa970904.aspx"&gt;WPF Brushes Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms742806.aspx"&gt;Routed Events Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms745058.aspx"&gt;Layout System&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10197637" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Silverlight/">Silverlight</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/WPF/">WPF</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Development+Tips/">Development Tips</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Windows+Phone/">Windows Phone</category></item><item><title>Preprocessor? .NET don't need no stinkin' preprocessor! [DebugEx.Assert provides meaningful assertion failure messages automagically!]</title><link>http://blogs.msdn.com/b/delay/archive/2011/07/28/preprocessor-net-don-t-need-no-stinkin-preprocessor-debugex-assert-provides-meaningful-assertion-failure-messages-automagically.aspx</link><pubDate>Thu, 28 Jul 2011 16:51:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10190792</guid><dc:creator>David Anson</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10190792</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/07/28/preprocessor-net-don-t-need-no-stinkin-preprocessor-debugex-assert-provides-meaningful-assertion-failure-messages-automagically.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;If you use .NET's &lt;a href="http://msdn.microsoft.com/en-us/library/kssw4w7z.aspx"&gt;Debug.Assert&lt;/a&gt; method, you probably write code to validate assumptions like so:&lt;/p&gt;
&lt;pre style="color: #000000;"&gt;&lt;span style="color: #2b91af;"&gt;Debug&lt;/span&gt;.Assert(args == &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;);&lt;/pre&gt;
&lt;p&gt;If the expression above evaluates to &lt;code&gt;false&lt;/code&gt; at run-time, .NET immediately halts the program and informs you of the problem:&lt;/p&gt;
&lt;img alt="Typical Debug.Assert" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/2248.DebugEx_2D00_DebugAssertNoMessage.png" width="487" height="231" /&gt;
&lt;p&gt;The stack trace can be really helpful (and it's cool you can attach a debugger right then!), but it would be even &lt;strong&gt;more&lt;/strong&gt; helpful if the message told you something about the faulty assumption... Fortunately, there's an overload of &lt;a href="http://msdn.microsoft.com/en-us/library/e63efys0.aspx"&gt;Debug.Assert&lt;/a&gt; that lets you provide a message:&lt;/p&gt;
&lt;pre style="color: #000000;"&gt;&lt;span style="color: #2b91af;"&gt;Debug&lt;/span&gt;.Assert(args == &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"args should be null."&lt;/span&gt;);&lt;/pre&gt;
&lt;p&gt;The failure dialog now looks like this:&lt;/p&gt;
&lt;img alt="Debug.Assert with message" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/8015.DebugEx_2D00_DebugAssertWithMessage.png" width="487" height="231" /&gt;
&lt;p&gt;That's a &lt;strong&gt;much&lt;/strong&gt; nicer experience - especially when there are lots of calls to &lt;code&gt;Assert&lt;/code&gt; and you're comfortable ignoring some of them from time to time (for example, if a network request failed and you know there's no connection). Some code analysis tools (notably &lt;a href="http://stylecop.codeplex.com/"&gt;StyleCop&lt;/a&gt;) go as far as to flag a &lt;em&gt;warning&lt;/em&gt; for any call to &lt;code&gt;Assert&lt;/code&gt; that doesn't provide a custom message.&lt;/p&gt;
&lt;p&gt;At first, adding a message to every &lt;code&gt;Assert&lt;/code&gt; seems like it ought to be pure goodness, but there turn out to be some drawbacks in practice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The comment is often a &lt;strong&gt;direct&lt;/strong&gt; restatement of the code - especially for very simple conditions. &lt;a href="http://knowyourmeme.com/memes/x-y-is-x-redundant-adjectives-are-redundant"&gt;Redundant redundancy is redundant&lt;/a&gt;, and when I see messages like that, I'm reminded of code comments like this:&lt;/p&gt;
&lt;pre style="color: #000000;"&gt;i++; &lt;span style="color: #008000;"&gt;// Increment i&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It takes time and energy to type out all those custom messages, and the irony is that most of them will never be seen at all!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Because the code for the condition is often expressive enough as-is, it would be nice if &lt;code&gt;Assert&lt;/code&gt; automatically used the &lt;strong&gt;code&lt;/strong&gt; as the message!&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: This is hardly a new idea; &lt;a href="http://en.wikipedia.org/wiki/Assert.h"&gt;C developers have been doing this for years&lt;/a&gt; by leveraging macro magic in the &lt;a href="http://en.wikipedia.org/wiki/C_preprocessor"&gt;preprocessor&lt;/a&gt; to create a string from the text of the condition.&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;strong&gt;Further aside&lt;/strong&gt;: This isn't even a new idea for .NET; I found a couple places on the web where people ask how to do this. And though nobody I saw seemed to have done quite what I show here, I'm sure there are other examples of this technique "in the wild".&lt;/blockquote&gt;
&lt;p&gt;As it happens, displaying the code for a condition can be accomplished fairly easily in .NET &lt;em&gt;without&lt;/em&gt; introducing a preprocessor! However, it requires that calls to &lt;code&gt;Assert&lt;/code&gt; be made &lt;em&gt;slightly&lt;/em&gt; differently so as to defer execution of the condition. In a normal call to &lt;code&gt;Assert&lt;/code&gt;, the expression passed to the &lt;code&gt;condition&lt;/code&gt; parameter is completely evaluated &lt;strong&gt;before&lt;/strong&gt; being checked. But by changing the type of the &lt;code&gt;condition&lt;/code&gt; parameter from &lt;code&gt;bool&lt;/code&gt; to &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb534960.aspx"&gt;Func&lt;/a&gt;&amp;lt;bool&amp;gt;&lt;/code&gt; and then wrapping it in the magic &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb335710.aspx"&gt;Expression&lt;/a&gt;&amp;lt;Func&amp;lt;bool&amp;gt;&amp;gt;&lt;/code&gt;, we're able to pass nearly complete information about the expression into the &lt;code&gt;Assert&lt;/code&gt; method where it can be used to recreate the original source code at run-time!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;To make this a little more concrete, the original "message-less" call I showed at the beginning of the post can be trivially changed to:&lt;/p&gt;
&lt;pre style="color: #000000;"&gt;&lt;span style="color: #2b91af;"&gt;DebugEx&lt;/span&gt;.Assert(() =&amp;gt; args == &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;);&lt;/pre&gt;
&lt;p&gt;And the &lt;code&gt;DebugEx.Assert&lt;/code&gt; method I've written will automatically provide a meaningful message (by calling the &lt;strong&gt;real&lt;/strong&gt; &lt;code&gt;Debug.Assert&lt;/code&gt; and passing the condition and a message):&lt;/p&gt;
&lt;img alt="DebugEx.Assert with automatic message" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-60-92-metablogapi/3302.DebugEx_2D00_DebugExAssert.png" width="487" height="261" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The message above is &lt;em&gt;identical&lt;/em&gt; to the original code - but maybe that's because it's so simple... Let's try something more complex:&lt;/p&gt;
&lt;pre style="color: #2b91af;"&gt;DebugEx&lt;span style="color: #000000;"&gt;.Assert(() =&amp;gt; args.Select(a =&amp;gt; a.Length).Sum() == 10);&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Becomes:&lt;/p&gt;
&lt;pre&gt;Assertion Failed: (args.Select(a =&amp;gt; a.Length).Sum() == 10)&lt;/pre&gt;
&lt;p&gt;Wow, amazing! So is it &lt;strong&gt;always&lt;/strong&gt; perfect? Unfortunately, no:&lt;/p&gt;
&lt;pre style="color: #2b91af;"&gt;DebugEx&lt;span style="color: #000000;"&gt;.Assert(() =&amp;gt; args.Length == 5);&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Becomes:&lt;/p&gt;
&lt;pre&gt;Assertion Failed: (ArrayLength(args) == 5)&lt;/pre&gt;
&lt;p&gt;The translation of the code to an expression tree and back seems to have lost a little fidelity along the way; the compiler translated the &lt;code&gt;Length&lt;/code&gt; access into an expression tree that doesn't map back to code exactly the same. Similarly:&lt;/p&gt;
&lt;pre style="color: #2b91af;"&gt;DebugEx&lt;span style="color: #000000;"&gt;.Assert(() =&amp;gt; 5 + 3 + 2 &amp;gt;= 100);&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Becomes:&lt;/p&gt;
&lt;pre&gt;Assertion Failed: False&lt;/pre&gt;
&lt;p&gt;In this case, the compiler evaluated the constant expression &lt;em&gt;at compile time&lt;/em&gt; (it's constant, after all!), and the information about which numbers were used in the computation was lost.&lt;/p&gt;
&lt;p&gt;Yep, the loss of fidelity in some cases is a bit of a shame, but I'll assert (&lt;em&gt;ha ha!&lt;/em&gt;) that nearly all the original &lt;strong&gt;intent&lt;/strong&gt; is preserved and that it's still quite easy to determine the nature of the failing code &lt;strong&gt;without&lt;/strong&gt; having to provide a message. And of course, you can always switch an ambiguous &lt;code&gt;DebugEx.Assert&lt;/code&gt; back to a normal &lt;code&gt;Assert&lt;/code&gt; and provide a &lt;code&gt;message&lt;/code&gt; parameter whenever you want. &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;a href="http://cesso.org/Samples/DebugEx/DebugEx.zip"&gt;[Click here to download the source code for DebugEx.Assert and the sample application used for the examples above.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;DebugEx.Assert&lt;/code&gt; was a fun experiment and a great introduction to .NET's powerful expression infrastructure. &lt;code&gt;DebugEx.Assert&lt;/code&gt; is a nearly-direct replacement for &lt;code&gt;Debug.Assert&lt;/code&gt; and (similarly) applies &lt;strong&gt;only&lt;/strong&gt; when &lt;code&gt;DEBUG&lt;/code&gt; is defined, so it costs nothing in release builds. It's worth noting there will be a bit of extra overhead due to the &lt;a href="http://msdn.microsoft.com/en-us/library/bb397687.aspx"&gt;lambda&lt;/a&gt;, but it should be negligible - especially when compared to the time you'll save by not having to type out a bunch of unnecessary messages!&lt;/p&gt;
&lt;p&gt;If you're getting tired of typing the same code twice, maybe &lt;code&gt;DebugEx.Assert&lt;/code&gt; can help! &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The code for &lt;code&gt;DebugEx.Assert&lt;/code&gt; turned out to be simple because nearly all the work is done by the &lt;code&gt;Expression(T)&lt;/code&gt; class. The one bit of trickiness stems from the fact that in order to create a lambda to pass as the &lt;code&gt;Func(T)&lt;/code&gt;, the compiler creates a &lt;a href="http://en.wikipedia.org/wiki/Closure_(computer_science)"&gt;closure&lt;/a&gt; which introduces an additional class (though they're never exposed to the developer). Therefore, even simple statements like the original example become kind of hard to read: &lt;code&gt;Assertion Failed: (value(Program+&amp;lt;&amp;gt;c__DisplayClass0).args == null)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To avoid that problem, I created an &lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.expressions.expressionvisitor.aspx"&gt;ExpressionVisitor&lt;/a&gt; subclass to rewrite the expression tree on the fly, getting rid of the references to such extra classes along the way. What I've done with &lt;code&gt;SimplifyingExpressionVisitor&lt;/code&gt; is simple, but seems to work nicely for the things I've tried. However, if you find scenarios where it doesn't work as well, I'd love to know so I can handle them too!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10190792" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category></item><item><title>Use it or lose it, part deux [New Delay.FxCop code analysis rule helps identify uncalled public or private methods and properties in a .NET assembly]</title><link>http://blogs.msdn.com/b/delay/archive/2011/07/14/use-it-or-lose-it-part-deux-new-delay-fxcop-code-analysis-rule-helps-identify-uncalled-public-or-private-methods-and-properties-in-a-net-assembly.aspx</link><pubDate>Thu, 14 Jul 2011 17:01:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10186576</guid><dc:creator>David Anson</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10186576</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/07/14/use-it-or-lose-it-part-deux-new-delay-fxcop-code-analysis-rule-helps-identify-uncalled-public-or-private-methods-and-properties-in-a-net-assembly.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;Previous posts &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/06/16/speling-misteaks-make-an-aplikation-look-sily-new-delay-fxcop-code-analysis-rule-finds-spelling-errors-in-a-net-assembly-s-string-literals.aspx"&gt;introduced the Delay.FxCop custom code analysis assembly&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/06/29/use-it-or-lose-it-new-delay-fxcop-code-analysis-rule-helps-identify-unused-resources-in-a-net-assembly.aspx"&gt;demonstrated the benefits of automated code analysis&lt;/a&gt; for easily identifying problem areas in an assembly. The &lt;code&gt;Delay.FxCop&lt;/code&gt; project included two rules, &lt;code&gt;DF1000: Check spelling of all string literals&lt;/code&gt; and &lt;code&gt;DF1001: Resources should be referenced&lt;/code&gt; - today I'm introducing another! The new rule follows in the footsteps of &lt;code&gt;DF1001&lt;/code&gt; by identifying unused parts of an assembly that can be removed to save space and reduce complexity. But while &lt;code&gt;DF1001&lt;/code&gt; operated on &lt;em&gt;resources&lt;/em&gt;, today's &lt;code&gt;DF1002: Uncalled methods should be removed&lt;/code&gt; analyzes the &lt;em&gt;methods&lt;/em&gt; and &lt;em&gt;properties&lt;/em&gt; of an assembly to help find those stale bits of code that aren't being used any more.&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Note&lt;/strong&gt;: If this functionality seems familiar, it's because &lt;a href="http://msdn.microsoft.com/en-us/library/ms182264.aspx"&gt;CA1811: Avoid uncalled private code&lt;/a&gt; is one of the standard FxCop rules. I've always been a big fan of &lt;code&gt;CA1811&lt;/code&gt;, but frequently wished it could look beyond just &lt;em&gt;private&lt;/em&gt; code to consider &lt;em&gt;all&lt;/em&gt; code. Of course, limiting the scope of the "in-box" rule makes perfect sense from an FxCop point of view: you don't want the default rules to be noisy or else they'll get turned off and ignored. But the &lt;code&gt;Delay.FxCop&lt;/code&gt; assembly isn't subject to the same restrictions, so I thought it would be neat to experiment with an implementation that analyzed &lt;strong&gt;all&lt;/strong&gt; of an assembly's code.&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;strong&gt;Further note&lt;/strong&gt;: One of the downsides of this increased scope is that &lt;code&gt;DF1002&lt;/code&gt; can't distinguish between methods that are part of a library's public API and those that are accidentally unused. As far as &lt;code&gt;DF1002&lt;/code&gt; is concerned, they're &lt;strong&gt;both&lt;/strong&gt; examples of code that's not called from within the assembly. Therefore, running this rule on a library involves some extra overhead to suppress the warnings for public APIs. If it's just a little extra work, maybe it's still worthwhile - but if it's overwhelming, you can always disable &lt;code&gt;DF1002&lt;/code&gt; for library assemblies and restrict it to applications where it's more relevant.&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Implementation-wise, &lt;code&gt;DF1002: Uncalled methods should be removed&lt;/code&gt; isn't all that different from its predecessors - in fact, it extends and reuses the same assembly node enumeration helper introduced with &lt;code&gt;DF1001&lt;/code&gt;. During analysis, every method of the assembly is visited and if it isn't "used" (more on this in a moment), a code analysis warning is output:&lt;/p&gt;
&lt;pre&gt;DF1002 : Performance : The method 'SilverlightApplication.MainPage.UnusedPublicMethod' does not appear to be used in code.&lt;/pre&gt;
&lt;p&gt;Of course, these warnings can be suppressed in the usual manner:&lt;/p&gt;
&lt;pre style="color: #000000;"&gt;[&lt;span style="color: #0000ff;"&gt;assembly&lt;/span&gt;: &lt;span style="color: #2b91af;"&gt;SuppressMessage&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"Usage"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"DF1001:ResourcesShouldBeReferenced"&lt;/span&gt;,
           MessageId = &lt;span style="color: #a31515;"&gt;"app.xaml"&lt;/span&gt;, Scope = &lt;span style="color: #a31515;"&gt;"resource"&lt;/span&gt;, Target = &lt;span style="color: #a31515;"&gt;"SilverlightApplication.g.resources"&lt;/span&gt;,
           Justification = &lt;span style="color: #a31515;"&gt;"Loaded by Silverlight for App.xaml."&lt;/span&gt;)]&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;It's interesting to consider what it means for a method or a property to be "used"... (Internally, properties are implemented as a pair of get/set methods.) Clearly, a direct call to a method means it's used - but that logic alone results in a lot of &lt;a href="http://en.wikipedia.org/wiki/False_positive"&gt;false positives&lt;/a&gt;! For example, a class implementing an interface &lt;strong&gt;must&lt;/strong&gt; define all the relevant interface methods in order to compile successfully. Therefore, explicit and implicit interface method implementations (even if uncalled) do not result in a &lt;code&gt;DF1002&lt;/code&gt; warning. Similarly, a method &lt;a href="http://msdn.microsoft.com/en-us/library/ms173149.aspx"&gt;override&lt;/a&gt; may not be directly called within an assembly, but can still be executed and should not trigger a warning. Other kinds of "unused" methods that do &lt;strong&gt;not&lt;/strong&gt; result in a warning include: static constructors, assembly entry-points, and methods passed as parameters (ex: to a delegate for use by an event).&lt;/p&gt;
&lt;p&gt;With all those special cases, you might think nothing would &lt;em&gt;ever&lt;/em&gt; be misdiagnosed. &lt;nobr&gt;:)&lt;/nobr&gt; But there's a particular scenario that leads to &lt;strong&gt;many&lt;/strong&gt; &lt;code&gt;DF1002&lt;/code&gt; warnings in a perfectly correct application: reflection-based access to properties and methods. Granted, reflection is rare at the &lt;em&gt;application&lt;/em&gt; level - but at the &lt;em&gt;framework&lt;/em&gt; level, it forms the very foundation of data binding as implemented by WPF and Silverlight! Therefore, running &lt;code&gt;DF1002&lt;/code&gt; against a &lt;a href="http://en.wikipedia.org/wiki/Xaml"&gt;XAML&lt;/a&gt; application with data binding can result in warnings for the property getters on all model classes...&lt;/p&gt;
&lt;p&gt;To avoid that problem, I've considered whether it would make sense to suppress &lt;code&gt;DF1002&lt;/code&gt; for classes that implement &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx"&gt;INotifyPropertyChanged&lt;/a&gt; (which most model classes do), but it seems like that would also mask a bunch of legitimate errors. The same reasoning applies to subclasses of &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.aspx"&gt;DependencyObject&lt;/a&gt; or implementations of &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dependencyproperty.aspx"&gt;DependencyProperty&lt;/a&gt; (though the latter might turn out to be a decent heuristic with a bit more work). Another approach might be for the rule to &lt;strong&gt;also&lt;/strong&gt; parse the XAML in an assembly and identify the various forms of data binding within. That seems promising, but goes way beyond the initial scope of &lt;code&gt;DF1002&lt;/code&gt;! &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;p&gt;Of course, there may be other common patterns which generate false positives - please let me know if you find one and I'll look at whether I can improve things for the next release.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;a href="http://cesso.org/Samples/DelayFxCop/Delay.FxCop.zip"&gt;[Click here to download the Delay.FxCop rule assembly, associated .ruleset files, samples, and the complete source code.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt; For directions about running &lt;code&gt;Delay.FxCop&lt;/code&gt; on a standalone assembly or integrating it into a project, &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/06/16/speling-misteaks-make-an-aplikation-look-sily-new-delay-fxcop-code-analysis-rule-finds-spelling-errors-in-a-net-assembly-s-string-literals.aspx"&gt;please refer to the steps in my original post&lt;/a&gt;. &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Unused code is an unnecessary tax on the development process. It's a distraction when reading, incurs additional costs during coding (ex: when refactoring), and it can mislead others about how an application &lt;em&gt;really&lt;/em&gt; works. That's why there's &lt;code&gt;DF1002: Uncalled methods should be removed&lt;/code&gt; - to help you easily identify unused methods. Try running it on your favorite .NET application; you might be surprised by what you find! &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10186576" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category></item><item><title>Use it or lose it! [New Delay.FxCop code analysis rule helps identify unused resources in a .NET assembly]</title><link>http://blogs.msdn.com/b/delay/archive/2011/06/29/use-it-or-lose-it-new-delay-fxcop-code-analysis-rule-helps-identify-unused-resources-in-a-net-assembly.aspx</link><pubDate>Wed, 29 Jun 2011 17:07:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10181489</guid><dc:creator>David Anson</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10181489</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/06/29/use-it-or-lose-it-new-delay-fxcop-code-analysis-rule-helps-identify-unused-resources-in-a-net-assembly.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;My previous post outlined the benefits of automated code analysis and &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/06/16/speling-misteaks-make-an-aplikation-look-sily-new-delay-fxcop-code-analysis-rule-finds-spelling-errors-in-a-net-assembly-s-string-literals.aspx"&gt;introduced the Delay.FxCop custom code analysis assembly&lt;/a&gt;. The initial release of &lt;code&gt;Delay.FxCop&lt;/code&gt; included only one rule, &lt;code&gt;DF1000: Check spelling of all string literals&lt;/code&gt;, which didn't seem like enough to me, so today's update &lt;strong&gt;doubles&lt;/strong&gt; the number of rules! &lt;nobr&gt;:)&lt;/nobr&gt; The new rule is &lt;code&gt;DF1001: Resources should be referenced&lt;/code&gt; - but before getting into that I'm going to spend a moment more on spell-checking...&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;What I &lt;em&gt;planned&lt;/em&gt; to write for the second code analysis rule was something to check the spelling of &lt;a href="http://msdn.microsoft.com/en-us/library/f45fce5x.aspx"&gt;.NET string resources&lt;/a&gt; (i.e., strings from a RESX file). This seemed like another place misspellings might occur and I'd heard of other custom rules that performed this same task (for example, &lt;a href="http://www.binarycoder.net/fxcop/html/ex_spellcheckingstringresources.html"&gt;here's a sample by Jason Kresowaty&lt;/a&gt;). However, in the process of doing research, I discovered rule &lt;a href="http://msdn.microsoft.com/en-us/library/bb264483.aspx"&gt;CA1703: Resource strings should be spelled correctly&lt;/a&gt; which is part of the &lt;strong&gt;default&lt;/strong&gt; set of rules!&lt;/p&gt;
&lt;p&gt;To make sure it did what I expected, I started a new application, added a misspelled string resource, and ran code analysis. To my surprise, the misspelling was &lt;strong&gt;not&lt;/strong&gt; detected... However, I noticed a different warning that seemed related: &lt;a href="http://msdn.microsoft.com/en-us/library/bb385967.aspx"&gt;CA1824: Mark assemblies with NeutralResourcesLanguageAttribute&lt;/a&gt; &lt;em&gt;"Because assembly 'Application.exe' contains a ResX-based resource file, mark it with the NeutralResourcesLanguage attribute, specifying the language of the resources within the assembly."&lt;/em&gt; Sure enough, when I un-commented the (project template-provided) &lt;code&gt;NeutralResourcesLanguage&lt;/code&gt; line in &lt;code&gt;AssemblyInfo.cs&lt;/code&gt;, the desired warning showed up:&lt;/p&gt;
&lt;pre&gt;CA1703 : Microsoft.Naming : In resource 'WpfApplication.Properties.Resources.resx', referenced by name
'SampleResource', correct the spelling of 'mispelling' in string value 'This string has a mispelling.'.&lt;/pre&gt;
&lt;p&gt;In my experience, a some people suppress &lt;code&gt;CA1824&lt;/code&gt; instead of addressing it. But as we've just discovered, they're &lt;strong&gt;also&lt;/strong&gt; giving up on free spell checking for their assembly's string resources. That seems silly, so I recommend setting &lt;a href="http://msdn.microsoft.com/en-us/library/system.resources.neutralresourceslanguageattribute.aspx"&gt;NeutralResourcesLanguageAttribute&lt;/a&gt; for its helpful side-effects!&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Note&lt;/strong&gt;: For expository purposes, I've included an example in the download: &lt;code&gt;CA1703 : Microsoft.Naming : In resource 'WpfApplication.Properties.Resources.resx', referenced by name 'IncorrectSpelling', correct the spelling of 'mispelling' in string value 'This string has a single mispelling.'.&lt;/code&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Once I realized resource spell checking was unnecessary, I decided to focus on a different pet peeve of mine: unused resources in an assembly. In much the same way stale chunks of unused code can be found in most applications, it's pretty common to find resources that aren't referenced and are just taking up valuable space. But while there's a built-in rule to detect certain kinds of uncalled code (&lt;a href="http://msdn.microsoft.com/en-us/library/ms182264.aspx"&gt;CA1811: Avoid uncalled private code&lt;/a&gt;), I'm not aware of anything similar for resources... And though it's &lt;em&gt;possible&lt;/em&gt; to perform this check manually (by searching for the use of each individual resource), this is the kind of boring, monotonous task that computers are &lt;strong&gt;made&lt;/strong&gt; for! &lt;nobr&gt;:)&lt;/nobr&gt;&lt;/p&gt;
&lt;p&gt;Therefore, I've created the second &lt;code&gt;Delay.FxCop&lt;/code&gt; rule, &lt;code&gt;DF1001: Resources should be referenced&lt;/code&gt;, which compares the set of resource references in an assembly with the set of resources that are actually present. Any cases where a resource exists (whether it's a string, stream, or object), but is not referenced in code will result in an instance of the &lt;code&gt;DF1001&lt;/code&gt; warning during code analysis.&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: For directions about how to run the &lt;code&gt;Delay.FxCop&lt;/code&gt; rules on a standalone assembly or integrate them into a project, &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/06/16/speling-misteaks-make-an-aplikation-look-sily-new-delay-fxcop-code-analysis-rule-finds-spelling-errors-in-a-net-assembly-s-string-literals.aspx"&gt;please refer to the steps in my original post&lt;/a&gt;.&lt;/blockquote&gt;
&lt;p&gt;As a word of caution, there can be cases where &lt;code&gt;DF1001&lt;/code&gt; reports that a resource isn't referenced from code, but that resource &lt;strong&gt;is&lt;/strong&gt; actually used by an assembly. While I don't think it will miss typical uses from code (either via the automatically-generated &lt;code&gt;Resources&lt;/code&gt; class or one of the lower-level &lt;a href="http://msdn.microsoft.com/en-us/library/system.resources.resourcemanager.aspx"&gt;ResourceManager&lt;/a&gt; methods), the catch is that &lt;em&gt;not all resource references show up in code&lt;/em&gt;! For example, the markup for a Silverlight or WPF application is included as a &lt;a href="http://en.wikipedia.org/wiki/Xaml"&gt;XAML&lt;/a&gt;/BAML resource which is loaded at run-time &lt;em&gt;without&lt;/em&gt; an explicit reference from the assembly itself. &lt;code&gt;DF1001&lt;/code&gt; will (correctly; sort of) report this resource as unused, so please remember that global code analysis suppressions can be used to squelch false-positives:&lt;/p&gt;
&lt;pre style="color: #000000;"&gt;[&lt;span style="color: #0000ff;"&gt;assembly&lt;/span&gt;: &lt;span style="color: #2b91af;"&gt;SuppressMessage&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"Usage"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"DF1001:ResourcesShouldBeReferenced"&lt;/span&gt;, MessageId = &lt;span style="color: #a31515;"&gt;"mainwindow.baml"&lt;/span&gt;,
    Scope = &lt;span style="color: #a31515;"&gt;"resource"&lt;/span&gt;, Target = &lt;span style="color: #a31515;"&gt;"WpfApplication.g.resources"&lt;/span&gt;, Justification = &lt;span style="color: #a31515;"&gt;"Loaded by WPF for MainWindow.xaml."&lt;/span&gt;)]&lt;/pre&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: There are other ways to "fool" &lt;code&gt;DF1001&lt;/code&gt;, such as by loading a resource from a &lt;em&gt;different&lt;/em&gt; assembly or passing a variable to &lt;code&gt;ResourceManager.GetString&lt;/code&gt;. But in terms of how things are done 95% of the time, the rule's current implementation should be accurate. Of course, if you find cases where it misreports unused resources, please let me know and I'll look into whether it's possible to improve things in a future release!&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;a href="http://cesso.org/Samples/DelayFxCop/Delay.FxCop.zip"&gt;[Click here to download the Delay.FxCop rule assembly, associated .ruleset files, samples, and the complete source code.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Stale references are an unnecessary annoyance: they bloat an assembly, waste time and money (for example, when localized unnecessarily), confuse new developers, and generally just get in the way. Fortunately, detecting them in an automated fashion is easy with &lt;code&gt;DF1001: Resources should be referenced&lt;/code&gt;! After making sure unused resources really &lt;strong&gt;are&lt;/strong&gt; unused, remove them from your project - and enjoy the benefits of a smaller, leaner application!&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10181489" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category></item><item><title>Speling misteaks make an aplikation look sily [New Delay.FxCop code analysis rule finds spelling errors in a .NET assembly's string literals]</title><link>http://blogs.msdn.com/b/delay/archive/2011/06/16/speling-misteaks-make-an-aplikation-look-sily-new-delay-fxcop-code-analysis-rule-finds-spelling-errors-in-a-net-assembly-s-string-literals.aspx</link><pubDate>Thu, 16 Jun 2011 16:08:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10175339</guid><dc:creator>David Anson</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10175339</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/06/16/speling-misteaks-make-an-aplikation-look-sily-new-delay-fxcop-code-analysis-rule-finds-spelling-errors-in-a-net-assembly-s-string-literals.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;No matter how polished the appearance of an application, web site, or advertisement is, the presence of even a single spelling error can make it look sloppy and unprofessional. The &lt;strong&gt;bad&lt;/strong&gt; news is that spelling errors are incredibly easy to make - either due to mistyping or because one forgot which of the many, conflicting special cases applies in a particular circumstance. The &lt;strong&gt;good&lt;/strong&gt; news is that technology to detect and correct spelling errors exists and is readily available. By making regular use of a spell-checker, you don't have to &lt;em&gt;be&lt;/em&gt; a good speller to &lt;em&gt;look&lt;/em&gt; like one. Trust me! &lt;nobr&gt;;)&lt;/nobr&gt; &lt;/p&gt;
&lt;p&gt;Spell-checking of documents is pretty well covered these days, with all the popular word processors offering automated, interactive assistance. However, spell-checking of code is not quite so far along - even high-end editors like Visual Studio don't tend to offer interactive spell-checking support. Fortunately, it's possible - even easy! - to augment the capabilities of many development tools to integrate spell-checking into the development workflow. There are a few different ways of doing this: one is to incorporate the checking into the editing experience (&lt;a href="http://visualstudiogallery.msdn.microsoft.com/0db4814c-255e-4cc6-a2c2-a428de7f8949"&gt;like this plugin by coworker Mikhail Arkhipov&lt;/a&gt;) and another is to do the checking as part of the code analysis workflow (&lt;a href="http://msdn.microsoft.com/en-us/library/bb264483.aspx"&gt;like code analysis rule CA1703: ResourceStringsShouldBeSpelledCorrectly&lt;/a&gt;). I'd already been toying with the idea of implementing my own code analysis rules, so I decided to experiment with the latter approach... &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: If you're not familiar with Visual Studio's code analysis feature, I highly recommend the MSDN article &lt;a href="http://msdn.microsoft.com/en-us/library/dd264939.aspx"&gt;Analyzing Managed Code Quality by Using Code Analysis&lt;/a&gt;. Although the fully integrated experience is only available on higher-end Visual Studio products, the same exact code analysis functionality is available to &lt;strong&gt;everyone&lt;/strong&gt; with the standalone &lt;a href="http://msdn.microsoft.com/en-us/library/bb429476.aspx"&gt;FxCop&lt;/a&gt; tool which is free as part of the &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b"&gt;Microsoft Windows SDK for Windows 7 and .NET Framework 4&lt;/a&gt;. (&lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=917023F6-D5B7-41BB-BBC0-411A7D66CF3C"&gt;FxCop has a dedicated download page&lt;/a&gt; with handy links, but it directs you to the SDK to do the actual install.) &lt;/blockquote&gt;
&lt;blockquote&gt;&lt;strong&gt;Unrelated aside&lt;/strong&gt;: In the &lt;em&gt;ideal&lt;/em&gt; world, all of an application's strings would probably come from a resource file where they can be easily translated to other languages - and therefore string literals wouldn't need spell-checking. However, in the &lt;em&gt;real&lt;/em&gt; world, there are often cases where user-visible text ends up in string literals (ex: exception messages) and therefore a rule like this seems to have practical value. If the string resources of your application are already perfectly separated, congratulations! However, if your application doesn't use resources (or uses them incompletely!), please continue reading... &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you might expect, it's possible to create custom code analysis rules &lt;strong&gt;and&lt;/strong&gt; easily integrate them into your build environment; a great walk-through can be found on the &lt;a href="http://blogs.msdn.com/b/codeanalysis/archive/2010/03/26/how-to-write-custom-static-code-analysis-rules-and-integrate-them-into-visual-studio-2010.aspx"&gt;Code Analysis Team Blog&lt;/a&gt;. If you still have questions after reading that, &lt;a href="http://blog.tatham.oddie.com.au/2010/01/06/custom-code-analysis-rules-in-vs2010-and-how-to-make-them-run-in-fxcop-and-vs2008-too/"&gt;this post by Tatham Oddie&lt;/a&gt; is also quite good. And once you have an idea what you're doing, &lt;a href="http://www.binarycoder.net/fxcop/"&gt;this documentation by Jason Kresowaty&lt;/a&gt; is a great resource for technical information. &lt;/p&gt;
&lt;p&gt;Code analysis is a powerful tool and has a &lt;strong&gt;lot&lt;/strong&gt; of potential for improving the development process. But for now, I'm just going to discuss a single rule I created: &lt;code&gt;DF1000: CheckSpellingOfAllStringLiterals&lt;/code&gt;. As its name suggests, this rule checks the spelling of all string literals in an assembly. To be clear, there &lt;em&gt;are&lt;/em&gt; other rules that check spelling (including some of the default FxCop/Visual Studio ones), but I didn't see any that checked &lt;strong&gt;all&lt;/strong&gt; the literals, so this seemed like an interesting place to start. &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: Programs tend to have a lot of strings and those strings aren't always words (ex: namespace prefixes, regular expressions, etc.). Therefore, this rule will almost certainly report a &lt;em&gt;lot&lt;/em&gt; of warnings run for the first time! Be prepared for that - and be ready to spend some time &lt;a href="http://msdn.microsoft.com/en-us/library/ms182068.aspx"&gt;suppressing warnings&lt;/a&gt; that don't matter to you. &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As I typically do, I've published a pre-compiled binary and complete source code, so you can see exactly how &lt;code&gt;CheckSpellingOfAllStringLiterals&lt;/code&gt; works (it's quite simple, really, as it uses the existing introspection and spell-checking APIs). I'm not going to spend a lot of time talking about how this rule is implemented, but I did want to show how to use it so others can experiment with their own projects. &lt;/p&gt;
&lt;blockquote&gt;&lt;strong style="background-color: yellow;"&gt;Important&lt;/strong&gt;: Everything I show here was done with the Visual Studio 2010/.NET 4 toolset. Past updates to the code analysis infrastructure are such that things &lt;em&gt;may&lt;/em&gt; not work with older (or newer) releases. &lt;/blockquote&gt;
&lt;p&gt;To add the Delay.FxCop rules to a project, you'll want to know a little about rule sets - the MSDN article &lt;a href="http://msdn.microsoft.com/en-us/library/dd264996.aspx"&gt;Using Rule Sets to Group Managed Code Analysis Rules&lt;/a&gt; is a good place to start. I've provided two &lt;code&gt;.ruleset&lt;/code&gt; files in the download: &lt;code&gt;Delay.FxCop.ruleset&lt;/code&gt; which contains just the custom rule I've written and &lt;code&gt;AllRules_Delay.FxCop.ruleset&lt;/code&gt; which contains my custom rule &lt;strong&gt;and&lt;/strong&gt; everything in the shipping "Microsoft All Rules" ruleset. (Of course, creating and using your own &lt;code&gt;.ruleset&lt;/code&gt; is another option!) Incorporating a custom rule set into a Visual Studio project is as easy as: &lt;strong&gt;Project&lt;/strong&gt; menu, &lt;strong&gt;&lt;em&gt;ProjectName&lt;/em&gt; Properties...&lt;/strong&gt;, &lt;strong&gt;Code Analysis&lt;/strong&gt; tab, &lt;strong&gt;Run this rule set:&lt;/strong&gt;, &lt;strong&gt;Browse...&lt;/strong&gt;, specify the path to the custom rule set, &lt;strong&gt;Build&lt;/strong&gt; menu, &lt;strong&gt;Run Code Analysis on &lt;em&gt;ProjectName&lt;/em&gt;&lt;/strong&gt;. &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Note&lt;/strong&gt;: For WPF projects, you may also want to uncheck &lt;strong&gt;Suppress results from generated code&lt;/strong&gt; in the "Code Analysis" tab above because the XAML compiler adds &lt;a href="http://msdn.microsoft.com/en-us/library/system.codedom.compiler.generatedcodeattribute.aspx"&gt;GeneratedCodeAttribute&lt;/a&gt; to all classes with an associated &lt;code&gt;.xaml&lt;/code&gt; file and that automatically suppresses code analysis warnings for those classes. (Silverlight and Windows Phone projects don't set this attribute, so the default "ignore" behavior is fine.) &lt;/blockquote&gt;
&lt;p&gt;Assuming your project contains a string literal that's not in the dictionary, the &lt;strong&gt;Error List&lt;/strong&gt; window should show one or more warnings like this: &lt;/p&gt;
&lt;pre&gt;DF1000 : Spelling : The word 'recieve' is not in the dictionary.&lt;/pre&gt;
&lt;p&gt;At this point, you have a few options (examples of which can be found in the &lt;code&gt;TestProjects\ConsoleApplication&lt;/code&gt; directory of the sample): &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fix the misspelling.&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;Duh. &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Suppress the instance.&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;If it's an isolated use of the word and is correct, then simply right-clicking the warning and choosing &lt;strong&gt;Suppress Message(s)&lt;/strong&gt;, &lt;strong&gt;In Source&lt;/strong&gt; will add something like the following attribute to the code which will silence the warning: &lt;/p&gt;
&lt;pre style="color: #000000;"&gt;[&lt;span style="color: #2b91af;"&gt;SuppressMessage&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"Spelling"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"DF1000:CheckSpellingOfAllStringLiterals"&lt;/span&gt;, MessageId = &lt;span style="color: #a31515;"&gt;"leet"&lt;/span&gt;)]&lt;/pre&gt;
&lt;p&gt;While you're at it, feel free to add a &lt;a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.codeanalysis.suppressmessageattribute.justification.aspx"&gt;Justification&lt;/a&gt; message if the reason might not be obvious to someone else. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Suppress the entire method.&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;If a method contains no user-visible text, but has lots of strings that cause warnings, you can suppress the entire method by omitting the &lt;code&gt;MessageId&lt;/code&gt; parameter like so: &lt;/p&gt;
&lt;pre style="color: #000000;"&gt;[&lt;span style="color: #2b91af;"&gt;SuppressMessage&lt;/span&gt;(&lt;span style="color: #a31515;"&gt;"Spelling"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"DF1000:CheckSpellingOfAllStringLiterals"&lt;/span&gt;)]&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add the word to the custom dictionary.&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;If the "misspelled" word is correct and appears throughout the application, you'll probably want to add it to the project's custom dictionary which will silence &lt;strong&gt;all&lt;/strong&gt; relevant warnings at once. MSDN has a great overview of the custom dictionary format as well as the exact steps to take to add a custom dictionary to a project in the article &lt;a href="http://msdn.microsoft.com/en-us/library/bb514188.aspx"&gt;How to: Customize the Code Analysis Dictionary&lt;/a&gt;. &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Alternatively, if you're a command-line junkie or don't want to modify your Visual Studio project, you can use &lt;a href="http://msdn.microsoft.com/en-us/library/bb429474.aspx"&gt;FxCopCmd&lt;/a&gt; directly by running it from a Visual Studio Command Prompt like so: &lt;/p&gt;
&lt;pre&gt;C:\T&amp;gt;"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\FxCopCmd.exe"
  /file:C:\T\ConsoleApplication\bin\Debug\ConsoleApplication.exe
  /ruleset:=C:\T\Delay.FxCop\Delay.FxCop.ruleset /console
Microsoft (R) FxCop Command-Line Tool, Version 10.0 (10.0.30319.1) X86
Copyright (C) Microsoft Corporation, All Rights Reserved.

[...]
Loaded delay.fxcop.dll...
Loaded ConsoleApplication.exe...
Initializing Introspection engine...
Analyzing...
Analysis Complete.
Writing 1 messages...

C:\T\ConsoleApplication\Program.cs(12,1) : warning  : DF1000 : Spelling : The word 'recieve' is not in the dictionary.
Done:00:00:01.4352025&lt;/pre&gt;
&lt;p&gt;Or else you can install the standalone FxCop tool to get the benefits of a graphical user interface without changing anything about your existing workflow! &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cesso.org/Samples/DelayFxCop/Delay.FxCop.zip"&gt;[Click here to download the Delay.FxCop rule assembly, associated .ruleset files, samples, and the complete source code.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Spelling is one of those things that's easy to get wrong - and also easy to get right if you apply the proper technology and discipline. I can't hope to make anyone a better speller ('i' before 'e', except after 'c'!), but I &lt;strong&gt;can&lt;/strong&gt; help out a little on the technology front. I plan to add new code analysis rules to &lt;code&gt;Delay.FxCop&lt;/code&gt; over time - but for now I hope people put &lt;code&gt;DF1000: CheckSpellingOfAllStringLiterals&lt;/code&gt; to good use finding spelling mistakes in their applications! &lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10175339" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category></item><item><title>Safe X (ml parsing with XLINQ) [XLinqExtensions helps make XML parsing with .NET's XLINQ a bit safer and easier]</title><link>http://blogs.msdn.com/b/delay/archive/2011/05/26/safe-x-ml-parsing-with-xlinq-xlinqextensions-helps-make-xml-parsing-with-net-s-xlinq-a-bit-safer-and-easier.aspx</link><pubDate>Thu, 26 May 2011 16:54:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10168745</guid><dc:creator>David Anson</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10168745</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/05/26/safe-x-ml-parsing-with-xlinq-xlinqextensions-helps-make-xml-parsing-with-net-s-xlinq-a-bit-safer-and-easier.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/library/bb308960.aspx"&gt;XLINQ (aka LINQ-to-XML)&lt;/a&gt; is a set of classes that make it simple to work with XML by exposing the element tree in a way that's easy to manipulate using standard &lt;a href="http://msdn.microsoft.com/en-us/library/bb308959.aspx"&gt;LINQ&lt;/a&gt; queries. So, for example, it's trivial to write code to select specific nodes for reading, create well-formed XML fragments, or transform an entire document. Because of its query-oriented nature, XLINQ makes it easy to ignore parts of a document that aren't relevant: if you don't query for them, they don't show up! Because it's so handy and powerful, I encourage folks who aren't already familiar to find out more. &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: As usual, flexibility comes with a cost and it is often more efficient to read and write XML with the underlying &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.aspx"&gt;XmlReader&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.xmlwriter.aspx"&gt;XmlWriter&lt;/a&gt; classes because they don't expose the same high-level abstractions. However, I'll suggest that the extra productivity of developing with XLINQ will often outweigh the minor computational cost it incurs. &lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;When I &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/04/14/quot-those-who-cannot-remember-the-past-are-condemned-to-repeat-it-quot-webbrowserextensions-stringsource-attached-dependency-property-makes-silverlight-windows-phone-wpf-s-webbrowser-control-more-xaml-and-binding-friendly.aspx"&gt;wrote the world's simplest RSS reader as a sample for my post on WebBrowserExtensions&lt;/a&gt;, I needed some code to parse &lt;a href="http://blogs.msdn.com/b/delay/rss.aspx"&gt;the RSS feed for my blog&lt;/a&gt; and dashed off the simplest thing possible using XLINQ. Here's a simplified version of that RSS feed for reference: &lt;/p&gt;
&lt;pre style="color: #0000ff;"&gt;&amp;lt;&lt;span style="color: #a31515;"&gt;rss&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; version&lt;/span&gt;=&lt;span style="color: #000000;"&gt;"&lt;/span&gt;2.0&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&amp;gt;
  &amp;lt;&lt;span style="color: #a31515;"&gt;channel&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style="color: #a31515;"&gt;title&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt;Delay's Blog&lt;/span&gt;&amp;lt;/&lt;span style="color: #a31515;"&gt;title&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style="color: #a31515;"&gt;item&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: #a31515;"&gt;title&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt;First Post&lt;/span&gt;&amp;lt;/&lt;span style="color: #a31515;"&gt;title&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: #a31515;"&gt;pubDate&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt;Sat, 21 May 2011 13:00:00 GMT&lt;/span&gt;&amp;lt;/&lt;span style="color: #a31515;"&gt;pubDate&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: #a31515;"&gt;description&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt;Post description.&lt;/span&gt;&amp;lt;/&lt;span style="color: #a31515;"&gt;description&lt;/span&gt;&amp;gt;
    &amp;lt;/&lt;span style="color: #a31515;"&gt;item&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span style="color: #a31515;"&gt;item&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: #a31515;"&gt;title&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt;Another Post&lt;/span&gt;&amp;lt;/&lt;span style="color: #a31515;"&gt;title&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: #a31515;"&gt;pubDate&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt;Sun, 22 May 2011 14:00:00 GMT&lt;/span&gt;&amp;lt;/&lt;span style="color: #a31515;"&gt;pubDate&lt;/span&gt;&amp;gt;
      &amp;lt;&lt;span style="color: #a31515;"&gt;description&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt;Another post description.&lt;/span&gt;&amp;lt;/&lt;span style="color: #a31515;"&gt;description&lt;/span&gt;&amp;gt;
    &amp;lt;/&lt;span style="color: #a31515;"&gt;item&lt;/span&gt;&amp;gt;
  &amp;lt;/&lt;span style="color: #a31515;"&gt;channel&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style="color: #a31515;"&gt;rss&lt;/span&gt;&amp;gt;&lt;/pre&gt;
&lt;p&gt;The code I wrote at the time looked a lot like the following: &lt;/p&gt;
&lt;pre style="color: #000000;"&gt;&lt;span style="color: #0000ff;"&gt;private static void&lt;/span&gt; NoChecking(&lt;span style="color: #2b91af;"&gt;XElement&lt;/span&gt; feedRoot)
{
    &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; version = feedRoot.Attribute(&lt;span style="color: #a31515;"&gt;"version"&lt;/span&gt;).Value;
    &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; title = feedRoot.Element(&lt;span style="color: #a31515;"&gt;"channel"&lt;/span&gt;).Element(&lt;span style="color: #a31515;"&gt;"title"&lt;/span&gt;).Value;
    ShowFeed(version, title);
    &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; feedRoot.Element(&lt;span style="color: #a31515;"&gt;"channel"&lt;/span&gt;).Elements(&lt;span style="color: #a31515;"&gt;"item"&lt;/span&gt;))
    {
        title = item.Element(&lt;span style="color: #a31515;"&gt;"title"&lt;/span&gt;).Value;
        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; publishDate = &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt;.Parse(item.Element(&lt;span style="color: #a31515;"&gt;"pubDate"&lt;/span&gt;).Value);
        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; description = item.Element(&lt;span style="color: #a31515;"&gt;"description"&lt;/span&gt;).Value;
        ShowItem(title, publishDate, description);
    }
}&lt;/pre&gt;
&lt;p&gt;Not surprisingly, running it on the XML above leads to the following output: &lt;/p&gt;
&lt;pre&gt;Delay's Blog (RSS 2.0)
  First Post
    Date: 5/21/2011
    Characters: 17
  Another Post
    Date: 5/22/2011
    Characters: 25&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;That code is simple, easy to read, and obvious in its intent. However (as is typical for sample code tangential to the topic of interest), there's no error checking or handling of malformed data. If &lt;em&gt;anything&lt;/em&gt; within the feed changes, it's quite likely the code I show above will throw an exception (for example: because the result of the &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.linq.xcontainer.element.aspx"&gt;Element&lt;/a&gt; method is &lt;code&gt;null&lt;/code&gt; when the named element can't be found). And although I don't expect changes to the format of this RSS feed, I'd be wary of shipping code like that because it's so fragile. &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: Safely parsing external data is a challenging task; many &lt;a href="http://en.wikipedia.org/wiki/Exploit_(computer_security)"&gt;exploits&lt;/a&gt; take advantage of parsing errors to corrupt a process's state. In the discussion here, I'm focusing mainly on "safety" in the sense of "resiliency": the ability of code to continue to work (or at least not throw an exception) despite changes to the format of the data it's dealing with. Naturally, more resilient parsing code is &lt;em&gt;likely&lt;/em&gt; to be less vulnerable to hacking, too - but I'm not specifically concerned with making code hack-proof here. &lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Adding the necessary error-checking to get the above snippet into shape for real-world use isn't particularly hard - but it does add a &lt;strong&gt;lot&lt;/strong&gt; more code. Consequently, readability suffers; although the following method performs exactly the same task, its implementation is decidedly harder to follow than the original: &lt;/p&gt;
&lt;pre style="color: #000000;"&gt;&lt;span style="color: #0000ff;"&gt;private static void&lt;/span&gt; Checking(&lt;span style="color: #2b91af;"&gt;XElement&lt;/span&gt; feedRoot)
{
    &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; version = &lt;span style="color: #a31515;"&gt;""&lt;/span&gt;;
    &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; versionAttribute = feedRoot.Attribute(&lt;span style="color: #a31515;"&gt;"version"&lt;/span&gt;);
    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; != versionAttribute)
    {
        version = versionAttribute.Value;
    }
    &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; channelElement = feedRoot.Element(&lt;span style="color: #a31515;"&gt;"channel"&lt;/span&gt;);
    &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; != channelElement)
    {
        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; title = &lt;span style="color: #a31515;"&gt;""&lt;/span&gt;;
        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; titleElement = channelElement.Element(&lt;span style="color: #a31515;"&gt;"title"&lt;/span&gt;);
        &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; != titleElement)
        {
            title = titleElement.Value;
        }
        ShowFeed(version, title);
        &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; channelElement.Elements(&lt;span style="color: #a31515;"&gt;"item"&lt;/span&gt;))
        {
            title = &lt;span style="color: #a31515;"&gt;""&lt;/span&gt;;
            titleElement = item.Element(&lt;span style="color: #a31515;"&gt;"title"&lt;/span&gt;);
            &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; != titleElement)
            {
                title = titleElement.Value;
            }
            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; publishDate = &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt;.MinValue;
            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; pubDateElement = item.Element(&lt;span style="color: #a31515;"&gt;"pubDate"&lt;/span&gt;);
            &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; != pubDateElement)
            {
                &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt;.TryParse(pubDateElement.Value, &lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; publishDate))
                {
                    publishDate = &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt;.MinValue;
                }
            }
            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; description = &lt;span style="color: #a31515;"&gt;""&lt;/span&gt;;
            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; descriptionElement = item.Element(&lt;span style="color: #a31515;"&gt;"description"&lt;/span&gt;);
            &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; != descriptionElement)
            {
                description = descriptionElement.Value;
            }
            ShowItem(title, publishDate, description);
        }
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;It would be nice if we could somehow combine the two approaches to arrive at something that reads easily while &lt;strong&gt;also&lt;/strong&gt; handling malformed content gracefully... And that's what the &lt;code&gt;XLinqExtensions&lt;/code&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx"&gt;extension methods&lt;/a&gt; are all about! &lt;/p&gt;
&lt;p&gt;Using the naming convention &lt;code&gt;SafeGet*&lt;/code&gt; where "*" can be &lt;code&gt;Element&lt;/code&gt;, &lt;code&gt;Attribute&lt;/code&gt;, &lt;code&gt;StringValue&lt;/code&gt;, or &lt;code&gt;DateTimeValue&lt;/code&gt;, these methods are simple wrappers that avoid problems by &lt;strong&gt;always&lt;/strong&gt; returning a valid object - even if they have to create an empty one themselves. In this manner, calls that are expected to return an &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement.aspx"&gt;XElement&lt;/a&gt; always do; calls that are expected to return a &lt;a href="http://msdn.microsoft.com/en-us/library/system.datetime.aspx"&gt;DateTime&lt;/a&gt; always do (with a user-provided fallback value for scenarios where the underlying string doesn't parse successfully). To be clear, there's no magic here - all the code is very simple - but by pushing error handling &lt;em&gt;into&lt;/em&gt; the accessor methods, the overall experience feels much nicer. &lt;/p&gt;
&lt;p&gt;To see what I mean, here's what the same code looks like after it has been changed to use &lt;code&gt;XLinqExtensions&lt;/code&gt; - note how similar it looks to the &lt;strong&gt;original&lt;/strong&gt; implementation that used the simple "write it the obvious way" approach: &lt;/p&gt;
&lt;pre style="color: #000000;"&gt;&lt;span style="color: #0000ff;"&gt;private static void&lt;/span&gt; Safe(&lt;span style="color: #2b91af;"&gt;XElement&lt;/span&gt; feedRoot)
{
    &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; version = feedRoot.SafeGetAttribute(&lt;span style="color: #a31515;"&gt;"version"&lt;/span&gt;).SafeGetStringValue();
    &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; title = feedRoot.SafeGetElement(&lt;span style="color: #a31515;"&gt;"channel"&lt;/span&gt;).SafeGetElement(&lt;span style="color: #a31515;"&gt;"title"&lt;/span&gt;).SafeGetStringValue();
    ShowFeed(version, title);
    &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; feedRoot.SafeGetElement(&lt;span style="color: #a31515;"&gt;"channel"&lt;/span&gt;).Elements(&lt;span style="color: #a31515;"&gt;"item"&lt;/span&gt;))
    {
        title = item.SafeGetElement(&lt;span style="color: #a31515;"&gt;"title"&lt;/span&gt;).SafeGetStringValue();
        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; publishDate = item.SafeGetElement(&lt;span style="color: #a31515;"&gt;"pubDate"&lt;/span&gt;).SafeGetDateTimeValue(&lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt;.MinValue);
        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; description = item.SafeGetElement(&lt;span style="color: #a31515;"&gt;"description"&lt;/span&gt;).SafeGetStringValue();
        ShowItem(title, publishDate, description);
    }
}&lt;/pre&gt;
&lt;p&gt;Not only is the &lt;code&gt;XLinqExtensions&lt;/code&gt; version almost as easy to read as the simple approach, it has all the resiliancy benefits of the complex one! What's not to like?? &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cesso.org/Samples/XLinqExtensions/XLinqExtensions.zip"&gt;[Click here to download the XLinqExtensions sample application containing everything shown here.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I've found the &lt;code&gt;XLinqExtensions&lt;/code&gt; approach helpful in my own projects because it enables me to parse XML with ease and peace of mind. The example I've provided here only scratches the surface of what's possible (ex: &lt;code&gt;SafeGetIntegerValue&lt;/code&gt;, &lt;code&gt;SafeGetUriValue&lt;/code&gt;, etc.), and is intended to set the stage for others to adopt a more robust approach to XML parsing. So if you find yourself parsing XML, please consider something similar! &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;PS - The complete set of &lt;code&gt;XLinqExtensions&lt;/code&gt; methods I use in the sample is provided below. Implementation of additional methods to suit custom scenarios is left as an exercise to the reader. :) &lt;/p&gt;
&lt;pre style="color: #000000;"&gt;&lt;span style="color: #808080;"&gt;/// &amp;lt;summary&amp;gt;
///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Class that exposes a variety of extension methods to make parsing XML with XLINQ easier and safer.
&lt;/span&gt;&lt;span style="color: #808080;"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static class&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; XLinqExtensions
&lt;/span&gt;{
    &lt;span style="color: #808080;"&gt;/// &amp;lt;summary&amp;gt;
    ///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Gets the named XElement child of the specified XElement.
&lt;/span&gt;&lt;span style="color: #808080;"&gt;    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="element"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;Specified element.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="name"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;Name of the child.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;XElement instance.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;    public static&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; XElement&lt;/span&gt; SafeGetElement(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; XElement&lt;/span&gt; element, &lt;span style="color: #2b91af;"&gt;XName&lt;/span&gt; name)
    {
        &lt;span style="color: #2b91af;"&gt;Debug&lt;/span&gt;.Assert(&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; != element);
        &lt;span style="color: #2b91af;"&gt;Debug&lt;/span&gt;.Assert(&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; != name);
        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; element.Element(name) ?? &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; XElement&lt;/span&gt;(name, &lt;span style="color: #a31515;"&gt;""&lt;/span&gt;);
    }

    &lt;span style="color: #808080;"&gt;/// &amp;lt;summary&amp;gt;
    ///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Gets the named XAttribute of the specified XElement.
&lt;/span&gt;&lt;span style="color: #808080;"&gt;    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="element"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;Specified element.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="name"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;Name of the attribute.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;XAttribute instance.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;    public static&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; XAttribute&lt;/span&gt; SafeGetAttribute(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; XElement&lt;/span&gt; element, &lt;span style="color: #2b91af;"&gt;XName&lt;/span&gt; name)
    {
        &lt;span style="color: #2b91af;"&gt;Debug&lt;/span&gt;.Assert(&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; != element);
        &lt;span style="color: #2b91af;"&gt;Debug&lt;/span&gt;.Assert(&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; != name);
        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; element.Attribute(name) ?? &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; XAttribute&lt;/span&gt;(name, &lt;span style="color: #a31515;"&gt;""&lt;/span&gt;);
    }

    &lt;span style="color: #808080;"&gt;/// &amp;lt;summary&amp;gt;
    ///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Gets the string value of the specified XElement.
&lt;/span&gt;&lt;span style="color: #808080;"&gt;    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="element"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;Specified element.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;String value.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;    public static string&lt;/span&gt; SafeGetStringValue(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; XElement&lt;/span&gt; element)
    {
        &lt;span style="color: #2b91af;"&gt;Debug&lt;/span&gt;.Assert(&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; != element);
        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; element.Value;
    }

    &lt;span style="color: #808080;"&gt;/// &amp;lt;summary&amp;gt;
    ///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Gets the string value of the specified XAttribute.
&lt;/span&gt;&lt;span style="color: #808080;"&gt;    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="attribute"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;Specified attribute.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;String value.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;    public static string&lt;/span&gt; SafeGetStringValue(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; XAttribute&lt;/span&gt; attribute)
    {
        &lt;span style="color: #2b91af;"&gt;Debug&lt;/span&gt;.Assert(&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; != attribute);
        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; attribute.Value;
    }

    &lt;span style="color: #808080;"&gt;/// &amp;lt;summary&amp;gt;
    ///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Gets the DateTime value of the specified XElement, falling back to a provided value in case of failure.
&lt;/span&gt;&lt;span style="color: #808080;"&gt;    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="element"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;Specified element.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="fallback"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;Fallback value.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;DateTime value.&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/returns&amp;gt;
&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;    public static&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; DateTime&lt;/span&gt; SafeGetDateTimeValue(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; XElement&lt;/span&gt; element, &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt; fallback)
    {
        &lt;span style="color: #2b91af;"&gt;Debug&lt;/span&gt;.Assert(&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt; != element);
        &lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt; value;
        &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt;.TryParse(element.Value, &lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; value))
        {
            value = fallback;
        }
        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; value;
    }
}&lt;/pre&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10168745" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category></item><item><title>"Sort" of a follow-up post [IListExtensions class enables easy sorting of .NET list types; today's updates make some scenarios faster or more convenient]</title><link>http://blogs.msdn.com/b/delay/archive/2011/05/18/quot-sort-quot-of-a-follow-up-post-ilistextensions-class-enables-easy-sorting-of-net-list-types-today-s-updates-make-some-scenarios-faster-or-more-convenient.aspx</link><pubDate>Wed, 18 May 2011 17:20:31 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10165948</guid><dc:creator>David Anson</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10165948</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/05/18/quot-sort-quot-of-a-follow-up-post-ilistextensions-class-enables-easy-sorting-of-net-list-types-today-s-updates-make-some-scenarios-faster-or-more-convenient.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;Recently, I wrote a post about the &lt;code&gt;IListExtensions&lt;/code&gt; collection of &lt;a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx"&gt;extension methods&lt;/a&gt; I created to make it easy to maintain a sorted list based on any &lt;a href="http://msdn.microsoft.com/en-us/library/5y536ey6.aspx"&gt;IList(T)&lt;/a&gt; implementation without needing to create a special subclass. In that post, &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/05/04/something-quot-sort-quot-of-handy-ilistextensions-adds-easy-sorting-to-net-list-types-enabling-faster-search-and-removal-too.aspx"&gt;I explained why I implemented IListExtensions the way I did&lt;/a&gt; and outlined some of the benefits for scenarios like using &lt;a href="http://msdn.microsoft.com/en-us/library/ms668604.aspx"&gt;ObservableCollection(T)&lt;/a&gt; for dynamic updates on Silverlight, WPF, and Windows Phone where the underlying class doesn't intrinsically support sorting. A couple of readers followed up with &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/05/04/something-quot-sort-quot-of-handy-ilistextensions-adds-easy-sorting-to-net-list-types-enabling-faster-search-and-removal-too.aspx#comments"&gt;some good questions and clarifications&lt;/a&gt; which I'd encourage having a look for additional context. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;During the time I've been using &lt;code&gt;IListExtensions&lt;/code&gt; in a project of my own, I have noticed two patterns that prompted today's update: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;It's easy to get performant set-like behavior from a sorted list.&lt;/strong&gt; Recall that a &lt;a href="http://en.wikipedia.org/wiki/Set_(computer_science)"&gt;set&lt;/a&gt; is simply a collection in which a particular item appears either 0 or 1 times (i.e., there are no duplicates in the collection). While this invariant can be easily maintained with any sorted list by performing a remove before each add (recall that &lt;a href="http://msdn.microsoft.com/en-us/library/bye7h94w.aspx"&gt;ICollection(T).Remove&lt;/a&gt; (and therefore &lt;code&gt;IListExtensions.RemoveSorted&lt;/code&gt;) doesn't throw if an element is not present), it also means there are &lt;strong&gt;two&lt;/strong&gt; searches of the list every time an item is added: one for the call to &lt;code&gt;RemoveSorted&lt;/code&gt; and another for the call to &lt;code&gt;AddSorted&lt;/code&gt;. While it's possible to be a bit more clever and avoid the extra search &lt;strong&gt;some&lt;/strong&gt;times, the API doesn't let you to "remember" the right index between calls to &lt;code&gt;*Sorted&lt;/code&gt; methods, so you can't get rid of the redundant search every time. &lt;/p&gt;
&lt;p&gt;Therefore, I created the &lt;code&gt;AddOrReplaceSorted&lt;/code&gt; method which has the same signature as &lt;code&gt;AddSorted&lt;/code&gt; (and therefore &lt;a href="http://msdn.microsoft.com/en-us/library/63ywd54z.aspx"&gt;ICollection(T).Add&lt;/a&gt;) and implements the set-like behavior of ensuring there is at most one instance of a particular item (i.e., the &lt;a href="http://msdn.microsoft.com/en-us/library/4d7sx9hd.aspx"&gt;IComparable(T)&lt;/a&gt; search key) present in the collection at any time. Because this one method does everything, it only ever needs to perform a &lt;strong&gt;single&lt;/strong&gt; search of the list and can help save a few CPU cycles in relevant scenarios. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;It's convenient to be able to call &lt;code&gt;RemoveSorted&lt;/code&gt;/&lt;code&gt;IndexOfSorted&lt;/code&gt;/&lt;code&gt;ContainsSorted&lt;/code&gt; with an instance of the search key.&lt;/strong&gt; Recall from the original post that &lt;code&gt;IListExtensions&lt;/code&gt; requires items in the list to implement the &lt;code&gt;IComparable(T)&lt;/code&gt; interface in order to define their sort order. This is fine most of the time, but can require a bit of extra overhead in situations where the items' sort order depends on only some (or commonly just one) of their properties. &lt;/p&gt;
&lt;p&gt;For example, note that the sort order the &lt;code&gt;Person&lt;/code&gt; class below depends only on the &lt;code&gt;Name&lt;/code&gt; property: &lt;/p&gt;
&lt;pre style="color: #000000;"&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; Person&lt;/span&gt; : &lt;span style="color: #2b91af;"&gt;IComparable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af;"&gt;Person&lt;/span&gt;&amp;gt;
{
    &lt;span style="color: #0000ff;"&gt;public string&lt;/span&gt; Name { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }
    &lt;span style="color: #0000ff;"&gt;public string&lt;/span&gt; Details { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }

    &lt;span style="color: #0000ff;"&gt;public int&lt;/span&gt; CompareTo(&lt;span style="color: #2b91af;"&gt;Person&lt;/span&gt; other)
    {
        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; Name.CompareTo(other.Name);
    }
}&lt;/pre&gt;
&lt;p&gt;In this case, using &lt;code&gt;ContainsSorted&lt;/code&gt; on a &lt;code&gt;List(Person)&lt;/code&gt; to search for a particular name would require the creation of a fake &lt;code&gt;Person&lt;/code&gt; instance to pass as the parameter to &lt;code&gt;ContainsSorted&lt;/code&gt; in order to match the type of the underlying collection. This isn't usually a big deal (though it &lt;em&gt;can&lt;/em&gt; be if the class doesn't have a public constructor!), but it complicates the code and seems like it ought to be unnecessary. &lt;/p&gt;
&lt;p&gt;Therefore, I've added new versions of &lt;code&gt;RemoveSorted&lt;/code&gt;/&lt;code&gt;IndexOfSorted&lt;/code&gt;/&lt;code&gt;ContainsSorted&lt;/code&gt; that take a &lt;code&gt;key&lt;/code&gt; parameter and a &lt;code&gt;keySelector&lt;/code&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/bb549151.aspx"&gt;Func(T, K)&lt;/a&gt;. The selector is passed an item from the list and needs to return that item's sort key (the thing that its &lt;a href="http://msdn.microsoft.com/en-us/library/43hc6wht.aspx"&gt;IComparable(T).CompareTo&lt;/a&gt; operates on). Not surprisingly, the underlying type of the keys must implement &lt;code&gt;IComparable(T)&lt;/code&gt;; keys are then compared directly (instead of indirectly via the containing items). In this way, it's possible to look up (or remove) a &lt;code&gt;Person&lt;/code&gt; in a &lt;code&gt;List(Person)&lt;/code&gt; by passing only the person's name and &lt;strong&gt;not&lt;/strong&gt; having to bother with the temporary &lt;code&gt;Person&lt;/code&gt; object at all! &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In addition to the code changes discussed above, I've updated the automated test project that comes with &lt;code&gt;IListExtensions&lt;/code&gt; to cover all the new scenarios. Conveniently, the new implementation of &lt;code&gt;AddOrReplaceSorted&lt;/code&gt; is nearly identical to that of &lt;code&gt;AddSorted&lt;/code&gt; and can be easily validated with &lt;a href="http://msdn.microsoft.com/en-us/library/dd412070.aspx"&gt;SortedSet(T)&lt;/a&gt;. Similarly, the three new key-based methods have all been implemented as variations of the pre-existing methods and &lt;em&gt;those&lt;/em&gt; have been modified to call directly into the new methods. Aside from a bit of clear, deliberate redundancy for &lt;code&gt;AddOrReplaceSorted&lt;/code&gt;, there's hardly any more code in this release than there was in the previous one - yet refactoring the implementation slightly enabled some handy new scenarios! &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cesso.org/Samples/IListExtensions/IListExtensions.zip"&gt;[Click here to download the IListExtensions implementation and its complete unit test project.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Proper sorting libraries offer a wide variety of ways to sort, compare, and work with sorted lists. &lt;code&gt;IListExtensions&lt;/code&gt; is &lt;strong&gt;not&lt;/strong&gt; a proper sorting library - nor does it aspire to be one. &lt;nobr&gt;:)&lt;/nobr&gt; Rather, it's a small collection of handy methods that make it easy to incorporate sorting into some common Silverlight, WPF, and Windows Phone scenarios. Sometimes you're forced to use a collection (like &lt;code&gt;ObservableCollection(T)&lt;/code&gt;) that doesn't do everything you want - but if all you're missing is basic sorting functionality, then &lt;code&gt;IListExtensions&lt;/code&gt; just might be the answer! &lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10165948" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Silverlight/">Silverlight</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/WPF/">WPF</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Windows+Phone/">Windows Phone</category></item><item><title>When you live on the bleeding edge, be prepared for a few nicks [Minor update to the Delay.Web.Helpers ASP.NET assembly download to avoid a NuGet packaging bug affecting Razor installs]</title><link>http://blogs.msdn.com/b/delay/archive/2011/05/09/when-you-live-on-the-bleeding-edge-be-prepared-for-a-few-nicks-minor-update-to-the-delay-web-helpers-asp-net-assembly-download-to-avoid-a-nuget-packaging-bug-affecting-razor-installs.aspx</link><pubDate>Mon, 09 May 2011 16:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10162565</guid><dc:creator>David Anson</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10162565</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/05/09/when-you-live-on-the-bleeding-edge-be-prepared-for-a-few-nicks-minor-update-to-the-delay-web-helpers-asp-net-assembly-download-to-avoid-a-nuget-packaging-bug-affecting-razor-installs.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;I had a surprise last week when coworker &lt;a href="http://bilalaslam.com/"&gt;Bilal Aslam&lt;/a&gt; mentioned he was using my &lt;code&gt;Delay.Web.Helpers&lt;/code&gt; assembly but wasn't able to install the 1.1.0 version with the &lt;a href="http://msdn.microsoft.com/library/gg549172(VS.99).aspx"&gt;ASP.NET Razor&lt;/a&gt; "_Admin" control panel. (Fortunately, the previous version (1.0.0) &lt;em&gt;did&lt;/em&gt; install and had the functionality he needed, so he was using that one for the time being.) I quickly told Bilal he was crazy because I remembered testing with the &lt;a href="http://nuget.org/"&gt;NuGet&lt;/a&gt; plugin for Visual Studio and knew it installed successfully. At which point he demonstrated the problem for me - and I was forced to admit defeat. &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: Delay.Web.Helpers is a collection of ASP.NET web helpers that provide access to &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/01/13/there-s-a-blob-on-your-web-page-but-don-t-wipe-it-off-new-delay-web-helpers-assembly-brings-easy-amazon-s3-blob-access-to-asp-net-web-sites.aspx"&gt;Amazon Simple Storage Service (S3) buckets and blobs&lt;/a&gt; as well as &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/04/06/images-in-a-web-page-meh-images-in-a-web-page-cool-delay-web-helpers-assembly-now-includes-an-asp-net-web-helper-for-data-uris-in-addition-to-amazon-s3-blob-bucket-support.aspx"&gt;easy ways to create "data URIs"&lt;/a&gt;. (And eventually more stuff as I get time to add it...) &lt;/blockquote&gt;
&lt;p&gt;Naturally, the first thing I did was to repeat my previous testing in Visual Studio - and it worked fine just like I remembered. So I tried with the Razor administration interface and it failed just like Bilal showed me: &lt;code&gt;"System.InvalidOperationException: The 'schemaVersion' attribute is not declared."&lt;/code&gt;. Because the previous version (1.0.0) didn't have this problem, I was a little confused; I'd built everything from the same &lt;code&gt;.nuspec&lt;/code&gt; file, so it wasn't clear why the Razor/1.1.0 scenario would be uniquely broken. &lt;/p&gt;
&lt;p&gt;At that point, I contacted a couple folks on the NuGet team and got a quick answer: for some (short) period of time, the official version of &lt;code&gt;nuget.exe&lt;/code&gt; created packages with a &lt;code&gt;schemaVersion&lt;/code&gt; attribute on the &lt;code&gt;package/metadata&lt;/code&gt; element of the embedded &lt;code&gt;.nuspec&lt;/code&gt; file and the presence of this attribute causes the Razor install implementation to fail with the exception we were seeing. I'd created 1.0.0 with a good version of &lt;code&gt;nuget.exe&lt;/code&gt;, but apparantly created 1.1.0 with the broken version. &lt;nobr&gt;:(&lt;/nobr&gt; &lt;/p&gt;
&lt;p&gt;The team's recommendedation was to re-create my packages with the current &lt;code&gt;nuget.exe&lt;/code&gt; and re-deploy them to the NuGet servers. I did that and the result is version 1.1.1 of the &lt;a href="http://www.nuget.org/List/Packages/Delay.Web.Helpers"&gt;Delay.Web.Helpers package&lt;/a&gt; and its associated &lt;a href="http://www.nuget.org/List/Packages/Delay.Web.Helpers.SampleWebSite"&gt;Delay.Web.Helpers.SampleWebSite package&lt;/a&gt;. "Once bitten, twice shy", so I verified the install in &lt;strong&gt;both&lt;/strong&gt; Visual Studio and Razor now that I know they're different and can fail independently. &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: There are no changes to the &lt;code&gt;Delay.Web.Helpers&lt;/code&gt; assembly or samples in this release. The only changes are the necessary tweaks to the NuGet metadata for both packages to install successfully under Razor. Therefore, if you've already installed 1.1.0 successfully, there's no need to upgrade. &lt;/blockquote&gt;
&lt;blockquote&gt;&lt;strong&gt;Further aside&lt;/strong&gt;: The &lt;a href="http://cesso.org/Samples/DelayWebHelpers/Delay.Web.Helpers.zip"&gt;standalone ZIP file with the assembly, source code, automated tests, and sample web site&lt;/a&gt; is unaffected by this update. &lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;To sum things up, if you created a NuGet package sometime around early April and you expect it to be installable with the Razor administration panel, I'd highly recommend trying it out to be sure! &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10162565" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Web+Platform/">Web Platform</category></item><item><title>Something "sort" of handy... [IListExtensions adds easy sorting to .NET list types - enabling faster search and removal, too!]</title><link>http://blogs.msdn.com/b/delay/archive/2011/05/04/something-quot-sort-quot-of-handy-ilistextensions-adds-easy-sorting-to-net-list-types-enabling-faster-search-and-removal-too.aspx</link><pubDate>Wed, 04 May 2011 16:58:44 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10161023</guid><dc:creator>David Anson</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10161023</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/05/04/something-quot-sort-quot-of-handy-ilistextensions-adds-easy-sorting-to-net-list-types-enabling-faster-search-and-removal-too.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;If you want to display a dynamically changing collection of items in WPF, Silverlight, or Windows Phone, there are a lot of collection classes to pick from - but there's really just &lt;strong&gt;one&lt;/strong&gt; good choice: &lt;a href="http://msdn.microsoft.com/en-us/library/ms668604.aspx"&gt;ObservableCollection(T)&lt;/a&gt;. Although nearly all the &lt;a href="http://msdn.microsoft.com/en-us/library/5y536ey6.aspx"&gt;IList(T)&lt;/a&gt;/&lt;a href="http://msdn.microsoft.com/en-us/library/92t2ye13.aspx"&gt;ICollection(T)&lt;/a&gt;/&lt;a href="http://msdn.microsoft.com/en-us/library/9eekhta0.aspx"&gt;IEnumerable(T)&lt;/a&gt; implementations work well for &lt;em&gt;static&lt;/em&gt; data, &lt;em&gt;dynamic&lt;/em&gt; data only updates automatically when it's in a collection that implements &lt;a href="http://msdn.microsoft.com/en-us/library/system.collections.specialized.inotifycollectionchanged.aspx"&gt;INotifyCollectionChanged&lt;/a&gt;. And while it's possible to write your own &lt;code&gt;INotifyCollectionChanged&lt;/code&gt; code, doing a good job takes a fair amount of work. Fortunately, &lt;code&gt;ObservableCollection(T)&lt;/code&gt; does nearly everything you'd want and is a great choice nearly all of the time. &lt;/p&gt;
&lt;p&gt;Unless you want your data sorted... &lt;/p&gt;
&lt;p&gt;By design, &lt;code&gt;ObservableCollection(T)&lt;/code&gt; doesn't sort data - that's left to the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.data.collectionview.aspx"&gt;CollectionView&lt;/a&gt; class which is the officially recommended way to sort lists for display (for more details, please refer to the &lt;a href="http://msdn.microsoft.com/en-us/library/ms752347.aspx#binding_to_collections"&gt;Data Binding Overview's "Binding to Collections" section&lt;/a&gt;). The way &lt;code&gt;CollectionView&lt;/code&gt; works is to add an additional layer of indirection on top of your list. &lt;strong&gt;That&lt;/strong&gt; gets sorted and the underlying collection isn't modified at all. This is a fine, flexible design (it enables a variety of other scenarios like filtering, grouping, and multiple views), but sometimes it'd be easier if the actual collection were sorted and the extra layer wasn't present (in addition to imposing a bit of overhead, working with &lt;code&gt;CollectionView&lt;/code&gt; requires additional code to account for the indirection). &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So it would be nice if there were a handy way to sort an &lt;code&gt;ObservableCollection(T)&lt;/code&gt; - something like the &lt;a href="http://msdn.microsoft.com/en-us/library/b0zbh7b6.aspx"&gt;List(T).Sort&lt;/a&gt; method. Unfortunately, &lt;code&gt;ObservableCollection(T)&lt;/code&gt; doesn't derive from &lt;code&gt;List(T)&lt;/code&gt;, so it doesn't have that method... Besides, it'd be better if adding items to the list put them in the right place to begin with - instead of adding them to the wrong place and then re-sorting the entire list after the fact. Along the same lines, scenarios that could take advantage of sorting for faster look-ups would benefit from something like &lt;a href="http://msdn.microsoft.com/en-us/library/w4e7fxsh.aspx"&gt;List(T).BinarySearch&lt;/a&gt; - which &lt;strong&gt;also&lt;/strong&gt; doesn't exist on &lt;code&gt;ObservableCollection(T)&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;All we really need to do here is provide custom implementations of add/remove/contains/index-of for &lt;code&gt;ObservableCollection(T)&lt;/code&gt; and we'd have the best of both worlds. One way of doing that is to subclass - but that ties the code to a specific base class and limits its usefulness somewhat (just like &lt;code&gt;Sort&lt;/code&gt; and &lt;code&gt;BinarySearch&lt;/code&gt; for &lt;code&gt;List(T)&lt;/code&gt; above). What we can do instead is implement these helper methods in a standalone class and enable them to target the least common denominator, &lt;code&gt;IList(T)&lt;/code&gt;, and therefore apply in a &lt;strong&gt;variety&lt;/strong&gt; of scenarios (i.e., all classes that implement that interface). What's more, these helpers can be trivially written as &lt;a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx"&gt;extension methods&lt;/a&gt; so they'll look just like APIs on the underlying classes! &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This sounds promising - let's see how it might work by considering the complete &lt;code&gt;IList(T)&lt;/code&gt; interface hierarchy: &lt;/p&gt;
&lt;pre style="color: #000000;"&gt;&lt;span style="color: #0000ff;"&gt;public interface&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; IList&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color: #2b91af;"&gt;ICollection&lt;/span&gt;&amp;lt;T&amp;gt;, &lt;span style="color: #2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;T&amp;gt;, &lt;span style="color: #2b91af;"&gt;IEnumerable
&lt;/span&gt;{
    T &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;[&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; index] { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }         &lt;span style="color: #008000;"&gt;// Good as-is
&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;    int&lt;/span&gt; IndexOf(T item);                    &lt;span style="color: #008000; background-color: yellow;"&gt;// Okay as-is; could be faster if sorted&lt;/span&gt;
&lt;span style="color: #0000ff;"&gt;    void&lt;/span&gt; Insert(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; index, T item);         &lt;span style="color: #008000; background-color: yellow;"&gt;// Should NOT be used with a sorted collection (might un-sort it)&lt;/span&gt;
&lt;span style="color: #0000ff;"&gt;    void&lt;/span&gt; RemoveAt(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; index);               &lt;span style="color: #008000;"&gt;// Good as-is
&lt;/span&gt;}
&lt;span style="color: #0000ff;"&gt;public interface&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; ICollection&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color: #2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;T&amp;gt;, &lt;span style="color: #2b91af;"&gt;IEnumerable
&lt;/span&gt;{
    &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; Count { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; }                      &lt;span style="color: #008000;"&gt;// Good as-is
&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;    bool&lt;/span&gt; IsReadOnly { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; }                &lt;span style="color: #008000;"&gt;// Good as-is
&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;    void&lt;/span&gt; Add(T item);                       &lt;span style="color: #008000; background-color: yellow;"&gt;// Needs custom implementation that preserves sort order&lt;/span&gt;
&lt;span style="color: #0000ff;"&gt;    void&lt;/span&gt; Clear();                           &lt;span style="color: #008000;"&gt;// Good as-is
&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;    bool&lt;/span&gt; Contains(T item);                  &lt;span style="color: #008000; background-color: yellow;"&gt;// Okay as-is; could be faster if sorted&lt;/span&gt;
&lt;span style="color: #0000ff;"&gt;    void&lt;/span&gt; CopyTo(T[] array, &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; arrayIndex); &lt;span style="color: #008000;"&gt;// Good as-is
&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;    bool&lt;/span&gt; Remove(T item);                    &lt;span style="color: #008000; background-color: yellow;"&gt;// Okay as-is; could be faster if sorted&lt;/span&gt;
}
&lt;span style="color: #0000ff;"&gt;public interface&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; IEnumerable&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color: #2b91af;"&gt;IEnumerable
&lt;/span&gt;{
    &lt;span style="color: #2b91af;"&gt;IEnumerator&lt;/span&gt;&amp;lt;T&amp;gt; GetEnumerator();         &lt;span style="color: #008000;"&gt;// Good as-is
&lt;/span&gt;}
&lt;span style="color: #0000ff;"&gt;public interface&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; IEnumerable
&lt;/span&gt;{
    &lt;span style="color: #2b91af;"&gt;IEnumerator&lt;/span&gt; GetEnumerator();            &lt;span style="color: #008000;"&gt;// Good as-is
&lt;/span&gt;}&lt;/pre&gt;
&lt;p&gt;To create a sorted &lt;code&gt;IList(T)&lt;/code&gt;, there's only one method that &lt;strong&gt;needs&lt;/strong&gt; to be written (add) and three others that &lt;strong&gt;should&lt;/strong&gt; be written to take advantage of the sorted collection for better performance (remove, contains, and index-of). (Aside: If you know a list is sorted, finding the right location changes from an &lt;code&gt;O(n)&lt;/code&gt; problem to an &lt;code&gt;O(log n)&lt;/code&gt; problem. &lt;a href="http://en.wikipedia.org/wiki/Big_O_notation"&gt;Read more about "big O" notation here.&lt;/a&gt;) The only additional requirement we'll impose is that the elements of the collection must have a natural order. One way this is commonly done is by implementing the &lt;a href="http://msdn.microsoft.com/en-us/library/4d7sx9hd.aspx"&gt;IComparable(T)&lt;/a&gt; interface on the item class. Basic .NET types already do this, as do other classes in the framework (ex: &lt;a href="http://msdn.microsoft.com/en-us/library/system.datetime.aspx"&gt;DateTime&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/system.tuple.aspx"&gt;Tuple&lt;/a&gt;, etc.). Because this interface has just one method, it's easy to add - and can often be implemented in terms of &lt;code&gt;IComparable(T)&lt;/code&gt; for its constituent parts! &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So here's what the &lt;code&gt;IListExtensions&lt;/code&gt; class I've created looks like: &lt;/p&gt;
&lt;pre style="color: #000000;"&gt;&lt;span style="color: #0000ff;"&gt;static class&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; IListExtensions
&lt;/span&gt;{
    &lt;span style="color: #0000ff;"&gt;public static void&lt;/span&gt; AddSorted&amp;lt;T&amp;gt;(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; IList&lt;/span&gt;&amp;lt;T&amp;gt; list, T item) &lt;span style="color: #0000ff;"&gt;where&lt;/span&gt; T : &lt;span style="color: #2b91af;"&gt;IComparable&lt;/span&gt;&amp;lt;T&amp;gt; { ... }
    &lt;span style="color: #0000ff;"&gt;public static bool&lt;/span&gt; RemoveSorted&amp;lt;T&amp;gt;(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; IList&lt;/span&gt;&amp;lt;T&amp;gt; list, T item) &lt;span style="color: #0000ff;"&gt;where&lt;/span&gt; T : &lt;span style="color: #2b91af;"&gt;IComparable&lt;/span&gt;&amp;lt;T&amp;gt; { ... }
    &lt;span style="color: #0000ff;"&gt;public static int&lt;/span&gt; IndexOfSorted&amp;lt;T&amp;gt;(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; IList&lt;/span&gt;&amp;lt;T&amp;gt; list, T item) &lt;span style="color: #0000ff;"&gt;where&lt;/span&gt; T : &lt;span style="color: #2b91af;"&gt;IComparable&lt;/span&gt;&amp;lt;T&amp;gt; { ... }
    &lt;span style="color: #0000ff;"&gt;public static bool&lt;/span&gt; ContainsSorted&amp;lt;T&amp;gt;(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #2b91af;"&gt; IList&lt;/span&gt;&amp;lt;T&amp;gt; list, T item) &lt;span style="color: #0000ff;"&gt;where&lt;/span&gt; T : &lt;span style="color: #2b91af;"&gt;IComparable&lt;/span&gt;&amp;lt;T&amp;gt; { ... }
}&lt;/pre&gt;
&lt;p&gt;You can use it to create and manage a sorted &lt;code&gt;ObservableCollection(T)&lt;/code&gt; simply by adding "Sorted" to the code you already have! &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cesso.org/Samples/IListExtensions/IListExtensions.zip"&gt;[Click here to download the IListExtensions implementation and its complete unit test project.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;One downside to the extension method approach is that the existing &lt;code&gt;List(T)&lt;/code&gt; methods remain visible and can be called by code that doesn't know to use the &lt;code&gt;*Sorted&lt;/code&gt; versions instead. For &lt;code&gt;Contains&lt;/code&gt;, &lt;code&gt;IndexOf&lt;/code&gt;, and &lt;code&gt;Remove&lt;/code&gt;, this is inefficient, but will still yield the correct answer - but for &lt;code&gt;Add&lt;/code&gt; and &lt;code&gt;Insert&lt;/code&gt; it's a &lt;strong&gt;bug&lt;/strong&gt; because these two methods are likely to ruin the sorted nature of the list when used without care. Once a list becomes unsorted, the &lt;code&gt;*Sorted&lt;/code&gt; methods will return incorrect results because they optimize searches based on the assumption that the list is correctly sorted. Subclassing would be the obvious "solution" to this problem, but it's not a good option here because the original methods aren't &lt;a href="http://msdn.microsoft.com/en-us/library/9fkccyh4.aspx"&gt;virtual&lt;/a&gt; on &lt;code&gt;ObservableCollection(T)&lt;/code&gt;... &lt;/p&gt;
&lt;p&gt;I'm not aware of a good way to make things foolproof without giving up on the nice generality benefits of the current approach, so this seems like one of those times where you just need to be careful about what you're doing. Fortunately, most programs probably only call the relevant methods a couple of times, so it's pretty easy to visit all the call sites and change them to use the corresponding &lt;code&gt;*Sorted&lt;/code&gt; method instead. [Trust me, I've done this myself. &lt;nobr&gt;:)&lt;/nobr&gt; ] &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: There's a subtle ambiguity regarding what to do if the collection contains duplicate items (i.e., multiple items that sort to the same location). It doesn't seem like it will matter most of the time, so &lt;code&gt;IListExtensions&lt;/code&gt; takes the performant way out and returns the &lt;em&gt;first&lt;/em&gt; correct answer it finds. It's important to note this is not necessarily the &lt;em&gt;first&lt;/em&gt; of a group of duplicate items, nor the &lt;em&gt;last&lt;/em&gt; of them - nor will it always be the same one of them! Basically, if the items' &lt;code&gt;IComparable(T)&lt;/code&gt; implementation says two items are equivalent, then &lt;code&gt;IListExtensions&lt;/code&gt; assumes they are and that they're equally valid answers. If the distinction matters in &lt;strong&gt;your&lt;/strong&gt; scenario, please feel free to tweak this code and take the corresponding performance hit. &lt;nobr&gt;:)&lt;/nobr&gt; (Alternatively, if the items' &lt;code&gt;IComparable(T)&lt;/code&gt; implementation can be modified to distinguish between otherwise "identical" items, the underlying ambiguity will be resolved and things will be deterministic again.) &lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;It's usually best to leverage platform support for something when it's available, so please look to &lt;code&gt;CollectionView&lt;/code&gt; for your sorting needs in WPF, Silverlight, and Windows Phone applications. But if you end up in a situation where it'd be better to maintain a sorted list yourself, maybe &lt;code&gt;IListExtensions&lt;/code&gt; is just what you need! &lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10161023" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Silverlight/">Silverlight</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/WPF/">WPF</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Windows+Phone/">Windows Phone</category></item><item><title>Don't shoot the messenger [A WebBrowserExtensions workaround for Windows Phone and a BestFitPanel tweak for infinite layout bounds on Windows Phone/Silverlight/WPF]</title><link>http://blogs.msdn.com/b/delay/archive/2011/04/20/don-t-shoot-the-messenger-a-webbrowserextensions-workaround-for-windows-phone-and-a-bestfitpanel-tweak-for-infinite-layout-bounds-on-windows-phone-silverlight-wpf.aspx</link><pubDate>Wed, 20 Apr 2011 20:50:25 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10156411</guid><dc:creator>David Anson</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10156411</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/04/20/don-t-shoot-the-messenger-a-webbrowserextensions-workaround-for-windows-phone-and-a-bestfitpanel-tweak-for-infinite-layout-bounds-on-windows-phone-silverlight-wpf.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;One of the neat things about sharing code with the community is hearing how people have learned from it or are using it in their own work. Of course, the more people use something, the more likely they are to identify problems with it - which is &lt;strong&gt;great&lt;/strong&gt; because it provides an opportunity to improve things! This blog post is about addressing two issues that came up around some code I published recently. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Platform Workaround (WebBrowserExtensions)&lt;/strong&gt; &lt;/p&gt;
&lt;img height="400" width="240" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/3173.WebBrowserExtensions_2D00_WP.png" alt="WebBrowserExtensions on Windows Phone" style="float:right" /&gt;
&lt;p&gt;&lt;a href="https://twitter.com/rogerguess"&gt;Roger Guess&lt;/a&gt; contacted me a couple of days after &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/04/14/quot-those-who-cannot-remember-the-past-are-condemned-to-repeat-it-quot-webbrowserextensions-stringsource-attached-dependency-property-makes-silverlight-windows-phone-wpf-s-webbrowser-control-more-xaml-and-binding-friendly.aspx"&gt;I posted the WebBrowserExtensions code&lt;/a&gt; to report a problem he saw when using it on Windows Phone 7 with the platform's &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.navigation.navigationservice(v=VS.95).aspx"&gt;NavigationService&lt;/a&gt; in a scenario where the user could hit the Back button to return to a page with a &lt;a href="http://msdn.microsoft.com/en-us/library/cc491073(v=VS.95).aspx"&gt;WebBrowser&lt;/a&gt; control that had its content set by the &lt;code&gt;WebBrowserExtensions.StringSource&lt;/code&gt; property. (Whew!) Instead of seeing the content that was there before, the control was &lt;strong&gt;blank&lt;/strong&gt;! Sure enough, I was able to duplicate the problem after I knew the setup... &lt;/p&gt;
&lt;p&gt;My initial theory was that the &lt;code&gt;WebBrowser&lt;/code&gt; was discarding its content during the navigation and not being reinitialized properly when it came back into view. Sure enough, some quick testing &lt;strong&gt;confirmed&lt;/strong&gt; this was the case - and what's more, the same problem happens with the official &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.webbrowser.source(v=VS.95).aspx"&gt;Source&lt;/a&gt; property as well! That made me feel a little better because it suggests a bug with the platform's &lt;code&gt;WebBrowser&lt;/code&gt; control rather than my own code. &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;p&gt;The workaround I came up with for &lt;code&gt;StringSource&lt;/code&gt; (and that was kindly verified by Roger) should work just as well for the official &lt;code&gt;Source&lt;/code&gt; property: I created an application-level event handler for the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.loaded(v=VS.95).aspx"&gt;Loaded&lt;/a&gt; event on the &lt;code&gt;WebBrowser&lt;/code&gt; and use that event to re-apply the correct content during the "back" navigation. I updated the Windows Phone sample application and added a new button/page to demonstrate the fix in action. &lt;/p&gt;
&lt;p&gt;If this scenario is possible with &lt;strong&gt;your&lt;/strong&gt; application, please consider applying a similar workaround! &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: Although it should be possible to apply the workaround to the &lt;code&gt;WebBrowserExtensions&lt;/code&gt; code itself, I decided that wasn't ideal because of the event handler: the entire &lt;code&gt;StringSource&lt;/code&gt; attached dependency property implementation is &lt;a href="http://msdn.microsoft.com/en-us/library/98f28cdx(v=VS.100).aspx"&gt;static&lt;/a&gt;, and tracking per-instance data from static code can be tricky. In this case, it would be necessary to ensure the &lt;code&gt;Loaded&lt;/code&gt; event handler was added only once, that it was removed when necessary, and that it didn't introduce any &lt;a href="http://blogs.msdn.com/b/delay/archive/2009/03/09/controls-are-like-diapers-you-don-t-want-a-leaky-one-implementing-the-weakevent-pattern-on-silverlight-with-the-weakeventlistener-class.aspx"&gt;memory leaks&lt;/a&gt;. Because such logic is often &lt;em&gt;much&lt;/em&gt; easier at the application level &lt;strong&gt;and&lt;/strong&gt; because the same basic workaround is necessary for the official &lt;code&gt;WebBrowser.Source&lt;/code&gt; property &lt;strong&gt;and&lt;/strong&gt; because it applies only to Windows Phone, it seemed best to leave the core &lt;code&gt;WebBrowserExtensions&lt;/code&gt; implementation as-is. &lt;/blockquote&gt;
&lt;blockquote&gt;&lt;strong&gt;Further aside&lt;/strong&gt;: This same scenario works fine on Silverlight 4, so it's another example of a Windows Phone quirk that needs to be worked around. (Recall from the &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/04/14/quot-those-who-cannot-remember-the-past-are-condemned-to-repeat-it-quot-webbrowserextensions-stringsource-attached-dependency-property-makes-silverlight-windows-phone-wpf-s-webbrowser-control-more-xaml-and-binding-friendly.aspx"&gt;previous post&lt;/a&gt; that it was already necessary to work around the fact that the Windows Phone &lt;code&gt;WebBrowser&lt;/code&gt; implementation can't be touched outside the visual tree.) That's a shame because the scenario itself is reasonable and consistent with the platform recommendation to use &lt;code&gt;NavigationService&lt;/code&gt; for everything. The fact that it seems broken for the "real" &lt;code&gt;Source&lt;/code&gt; property as well makes me think other people will run into this, too. &lt;nobr&gt;:(&lt;/nobr&gt; &lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cesso.org/Samples/WebBrowserExtensions/WebBrowserExtensions.zip"&gt;[Click here to download the WebBrowserExtensions class and samples for Silverlight, Windows Phone, and WPF.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Layout Implementation Oversight (BestFitPanel)&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/EitanGabay76"&gt;Eitan Gabay&lt;/a&gt; contacted me soon after &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/03/30/each-one-is-the-best-for-different-definitions-of-quot-best-quot-the-bestfitpanel-collection-of-layout-containers-provides-flexible-easy-to-use-options-for-silverlight-wpf-and-windows-phone-applications.aspx"&gt;I posted my BestFitPanel code&lt;/a&gt; to report an exception he saw when using one of the &lt;code&gt;BestFitPanel&lt;/code&gt; classes as the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemspanel.aspx"&gt;ItemsPanel&lt;/a&gt; of a &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.listbox.aspx"&gt;ListBox&lt;/a&gt; at design-time. I hadn't tried that particular configuration, but once I did, I saw the same message: &lt;code&gt;"MeasureOverride of element 'Delay.MostBigPanel' should not return PositiveInfinity or NaN as its DesiredSize."&lt;/code&gt;. If you've dealt much with custom &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.panel.aspx"&gt;Panel&lt;/a&gt; implementations, this probably isn't all that surprising... Although coding layout is often straightforward, there can be a variety of edge cases depending on how the layout is done. (For example: only one child, no children, no available size, nested inside different kinds of parent containers, etc..) &lt;/p&gt;
&lt;p&gt;In this case, it turns out that the constraint passed to &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.measureoverride.aspx"&gt;MeasureOverride&lt;/a&gt; included a value of &lt;a href="http://msdn.microsoft.com/en-us/library/system.double.positiveinfinity.aspx"&gt;double.PositiveInfinity&lt;/a&gt; and &lt;code&gt;BestFitPanel&lt;/code&gt; was returning that same value. That isn't allowed because the &lt;code&gt;MeasureOverride&lt;/code&gt; method of an element is supposed to return the smallest size the element can occupy without clipping - and &lt;strong&gt;nothing&lt;/strong&gt; should require infinite size! (If you think about it, though, the scenario is a little wacky for &lt;code&gt;BestFitPanel&lt;/code&gt;: what does it mean to make the best use of an infinite amount of space?) &lt;/p&gt;
&lt;p&gt;There are two parts to my fix for this problem. The first part is to skip calling the &lt;code&gt;CalculateBestFit&lt;/code&gt; override for infinite bounds (it's unlikely to know what to do anyway) and to &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.uielement.measure.aspx"&gt;Measure&lt;/a&gt; all the children at the provided size instead. This ensures all children get a chance to measure during the measure pass - which some controls &lt;strong&gt;require&lt;/strong&gt; in order to render correctly. The second part of the fix is to return a &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.size.aspx"&gt;Size&lt;/a&gt; with the longest width and height of any child measured when infinite bounds are passed in. Because children are subject to the same rule about not returning an infinite value from &lt;code&gt;Measure&lt;/code&gt;, this approach means &lt;code&gt;BestFitPanel&lt;/code&gt; won't either &lt;strong&gt;and&lt;/strong&gt; that the &lt;code&gt;Panel&lt;/code&gt; will occupy an amount of space that's related to the size of its content (instead of being arbitrary like 0x0, 100x100, etc.). &lt;/p&gt;
&lt;p&gt;The combined effect of these changes is to fix the reported exception, provide a better design-time experience, and offer an more versatile run-time experience as well! &lt;/p&gt;
&lt;img height="348" width="614" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/6327.BestFitPanel_2D00_All.png" alt="All BestFitPanels overlapped" /&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cesso.org/Samples/BestFitPanel/BestFitPanel.zip"&gt;[Click here to download the source code for all BestFitPanels along with sample projects for Silverlight, WPF, and Windows Phone.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The more a piece of code gets looked at and used, the more likely it is that potential problems are uncovered. It can be difficult to catch everything on your own, so it's &lt;strong&gt;fantastic&lt;/strong&gt; to have a community of people looking at stuff and providing feedback when something doesn't work. Thanks again to Robert and Eitan for bringing these issues to my attention and for taking the time to try out early versions of each fix! &lt;/p&gt;
&lt;p&gt;I'm always hopeful people won't have problems with my code - but when they &lt;strong&gt;do&lt;/strong&gt;, I &lt;em&gt;really&lt;/em&gt; appreciate them taking the time to let me know! &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10156411" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Silverlight/">Silverlight</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/WPF/">WPF</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Windows+Phone/">Windows Phone</category></item><item><title>"Those who cannot remember the past are condemned to repeat it." [WebBrowserExtensions.StringSource attached dependency property makes Silverlight/Windows Phone/WPF's WebBrowser control more XAML- and binding-friendly]</title><link>http://blogs.msdn.com/b/delay/archive/2011/04/14/quot-those-who-cannot-remember-the-past-are-condemned-to-repeat-it-quot-webbrowserextensions-stringsource-attached-dependency-property-makes-silverlight-windows-phone-wpf-s-webbrowser-control-more-xaml-and-binding-friendly.aspx</link><pubDate>Thu, 14 Apr 2011 18:02:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10154060</guid><dc:creator>David Anson</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10154060</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/04/14/quot-those-who-cannot-remember-the-past-are-condemned-to-repeat-it-quot-webbrowserextensions-stringsource-attached-dependency-property-makes-silverlight-windows-phone-wpf-s-webbrowser-control-more-xaml-and-binding-friendly.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/cc491073(v=VS.95).aspx"&gt;WebBrowser&lt;/a&gt; control is available in Silverlight 4, Windows Phone 7, and all versions of WPF. It's mostly the same everywhere, though there are &lt;a href="http://msdn.microsoft.com/en-us/library/ff431795(v=VS.92).aspx"&gt;some specific differences to keep in mind&lt;/a&gt; when using it on Silverlight-based platforms. &lt;code&gt;WebBrowser&lt;/code&gt; offers two ways to provide its content: by passing a &lt;a href="http://en.wikipedia.org/wiki/Uniform_Resource_Identifier"&gt;URI&lt;/a&gt; or by passing a string with &lt;a href="http://en.wikipedia.org/wiki/Html"&gt;HTML&lt;/a&gt; text: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;If you have a URI, you can set the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.webbrowser.source(v=VS.95).aspx"&gt;Source&lt;/a&gt; (dependency) property in code or &lt;a href="http://en.wikipedia.org/wiki/Xaml"&gt;XAML&lt;/a&gt; &lt;strong&gt;or&lt;/strong&gt; you can call the &lt;a href="http://msdn.microsoft.com/en-us/library/cc491011(v=VS.95).aspx"&gt;Navigate(Uri)&lt;/a&gt; method from code. &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: It's not clear to me what the &lt;code&gt;Navigate(Uri)&lt;/code&gt; method enables that the &lt;code&gt;Source&lt;/code&gt; property doesn't, but flexibility is nice, so I won't dwell on this. &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On the other hand, if you have a string, your &lt;strong&gt;only&lt;/strong&gt; option is to call the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.webbrowser.navigatetostring(v=VS.95).aspx"&gt;NavigateToString(string)&lt;/a&gt; method from code. &lt;/p&gt;
&lt;p&gt;XAML and data-binding support for strings? &lt;em&gt;Nope, not so much...&lt;/em&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I'm not sure why all three platforms have the same limitation, but I suspect there was a good reason at some point in time and maybe nobody has revisited the decision since then. Be that as it may, the brief research I did before writing this post suggests that a good number of people have been inconvenienced by the issue. Therefore, I've written a simple &lt;a href="http://msdn.microsoft.com/en-us/library/ms749011.aspx"&gt;attached dependency property&lt;/a&gt; to add support for providing HTML strings in XAML via &lt;a href="http://msdn.microsoft.com/en-us/library/ms752347.aspx"&gt;data binding&lt;/a&gt;! &lt;/p&gt;
&lt;pre style="color:#0000ff"&gt;&amp;lt;&lt;span style="color:#a31515"&gt;phone&lt;/span&gt;:&lt;span style="color:#a31515"&gt;WebBrowser&lt;/span&gt;&lt;span style="color:#ff0000"&gt; delay&lt;/span&gt;:&lt;span style="color:#ff0000"&gt;WebBrowserExtensions.StringSource&lt;/span&gt;="{&lt;span style="color:#a31515"&gt;Binding&lt;/span&gt;&lt;span style="color:#ff0000"&gt; MyProperty&lt;/span&gt;}"/&amp;gt;&lt;/pre&gt;
&lt;p&gt;As you can see above, this functionality is made possible by the &lt;code&gt;StringSource&lt;/code&gt; property which is exposed by the &lt;code&gt;WebBrowserExtensions&lt;/code&gt; class. It's a fairly simple attached property that just passes its new value on to the &lt;code&gt;WebBrowser&lt;/code&gt;'s &lt;code&gt;NavigateToString&lt;/code&gt; method to do the &lt;strong&gt;real&lt;/strong&gt; work. For everyone's convenience, I've tried to make sure my &lt;code&gt;StringSource&lt;/code&gt; implementation works on Silverlight 4, Windows Phone 7, and WPF. &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: The &lt;code&gt;StringSource&lt;/code&gt; property is read/write from code and XAML, but does &lt;strong&gt;not&lt;/strong&gt; attempt to detect &lt;code&gt;WebBrowser&lt;/code&gt; navigation by other means (and somehow "transform" the results into a corresponding HTML string). Therefore, if you're interleaving multiple navigation methods in the same application, reading from &lt;code&gt;StringSource&lt;/code&gt; &lt;em&gt;may not&lt;/em&gt; be correct - but writing to it should always work! &lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Aside&lt;/strong&gt;: Things are more complicated on Windows Phone because the &lt;code&gt;WebBrowser&lt;/code&gt; implementation there throws exceptions if it gets touched outside the visual tree. Therefore, if &lt;code&gt;WINDOWS_PHONE&lt;/code&gt; is defined (and by default it &lt;strong&gt;is&lt;/strong&gt; for phone projects), this code catches the possible &lt;a href="http://msdn.microsoft.com/en-us/library/system.invalidoperationexception(v=VS.95).aspx"&gt;InvalidOperationException&lt;/a&gt; and deals with it by creating a handler for the &lt;code&gt;WebBrowser&lt;/code&gt;'s &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.loaded(v=VS.95).aspx"&gt;Loaded&lt;/a&gt; event that attempts to re-set the string once the control is known to be in the visual tree. If the second attempt fails, the exception is allowed to bubble out of the method. This seems to work nicely for the typical "string in XAML" scenario, though it's possible more complex scenarios will require a more involved workaround. &lt;/p&gt;
&lt;p&gt;My thanks go out to &lt;a href="https://twitter.com/rogerguess"&gt;Roger Guess&lt;/a&gt; for trying an early version of the code and reminding me of this gotcha! &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;To prove to ourselves that &lt;code&gt;StringSource&lt;/code&gt; behaves as we intend, let's create the world's simplest &lt;a href="http://en.wikipedia.org/wiki/Rss"&gt;RSS&lt;/a&gt; reader! All it will do is download a single RSS feed, parse it for the titles and content of each post, and display those titles in a &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.listbox.aspx"&gt;ListBox&lt;/a&gt;. There'll be a &lt;code&gt;WebBrowser&lt;/code&gt; control using &lt;code&gt;StringSource&lt;/code&gt; to bind to the ListBox's &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.selector.selecteditem.aspx"&gt;SelectedItem&lt;/a&gt; property (all XAML; no code!), so that when a title is clicked, its content will &lt;strong&gt;automatically&lt;/strong&gt; be displayed by the &lt;code&gt;WebBrowser&lt;/code&gt;! &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here's what it looks like on Silverlight (note that the sample must be run outside the browser because of &lt;a href="http://msdn.microsoft.com/en-us/library/cc645032(VS.95).aspx"&gt;network security access restrictions in Silverlight&lt;/a&gt;): &lt;/p&gt;
&lt;img height="353" width="618" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/4643.WebBrowserExtensions_2D00_SL.png" alt="WebBrowserExtensions on Silverlight" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And here's the same code running on Windows Phone: &lt;/p&gt;
&lt;img height="400" width="240" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/3173.WebBrowserExtensions_2D00_WP.png" alt="WebBrowserExtensions on Windows Phone" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And on WPF: &lt;/p&gt;
&lt;img height="366" width="624" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/5040.WebBrowserExtensions_2D00_WPF.png" alt="WebBrowserExtensions on WPF" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cesso.org/Samples/WebBrowserExtensions/WebBrowserExtensions.zip"&gt;[Click here to download the WebBrowserExtensions class and the samples above for Silverlight, Windows Phone, and WPF.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;StringSource&lt;/code&gt; attached dependency property is simple code for a simple purpose. It doesn't have a lot of bells and whistles, but it gets the job done nicely and fills a small gap in the platform. You won't always deal with HTML content directly, but when you &lt;strong&gt;do&lt;/strong&gt;, &lt;code&gt;StringSource&lt;/code&gt; makes it easy to combine the &lt;code&gt;WebBrowser&lt;/code&gt; control with XAML and data binding! &lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10154060" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Silverlight/">Silverlight</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/WPF/">WPF</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Windows+Phone/">Windows Phone</category></item><item><title>Images in a web page: meh... Images *in* a web page: cool! [Delay.Web.Helpers assembly now includes an ASP.NET web helper for data URIs (in addition to Amazon S3 blob/bucket support)]</title><link>http://blogs.msdn.com/b/delay/archive/2011/04/06/images-in-a-web-page-meh-images-in-a-web-page-cool-delay-web-helpers-assembly-now-includes-an-asp-net-web-helper-for-data-uris-in-addition-to-amazon-s3-blob-bucket-support.aspx</link><pubDate>Wed, 06 Apr 2011 17:13:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10150550</guid><dc:creator>David Anson</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10150550</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/04/06/images-in-a-web-page-meh-images-in-a-web-page-cool-delay-web-helpers-assembly-now-includes-an-asp-net-web-helper-for-data-uris-in-addition-to-amazon-s3-blob-bucket-support.aspx#comments</comments><description>&lt;div class="delay"&gt;&lt;img height="709" width="382" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/7242.DelayWebHelpers_2D00_DataUri.png" alt="Delay.Web.Helpers DataUri sample page" style="float:right" /&gt;
&lt;p&gt;The topic of &lt;a href="http://en.wikipedia.org/wiki/Data_Uri"&gt;"data URIs"&lt;/a&gt; came up on a discussion list I follow last week in the context of "I'm in the process of creating a page and have the bytes of an image from my database. Can I deliver them directly or must I go through a separate URL with &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.helpers.webimage(v=VS.99).aspx"&gt;WebImage&lt;/a&gt;?" And the response was that using a data URI would allow that page to deliver the image content &lt;strong&gt;inline&lt;/strong&gt;. But while data URIs are fairly simple, there didn't seem to be a convenient way to use them from an &lt;a href="http://www.asp.net/mvc/mvc3"&gt;ASP.NET MVC/Razor&lt;/a&gt; web page. &lt;/p&gt;
&lt;p&gt;Which was kind of fortuitous for me because I've been interested in learning more about data URIs for a while and it seemed that creating a web helper for this purpose would be fun. Better yet, I'd already released the &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/01/13/there-s-a-blob-on-your-web-page-but-don-t-wipe-it-off-new-delay-web-helpers-assembly-brings-easy-amazon-s3-blob-access-to-asp-net-web-sites.aspx"&gt;Delay.Web.Helpers assembly (with support for Amazon S3 blob/bucket access)&lt;/a&gt;, so I had the &lt;strong&gt;perfect&lt;/strong&gt; place to put the new &lt;code&gt;DataUri&lt;/code&gt; class once I wrote it! &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: For those who aren't familiar, the &lt;code&gt;WebImage&lt;/code&gt; class provides a variety of handy methods for dealing with images on the server - including a &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.helpers.webimage.write(v=VS.99).aspx"&gt;Write&lt;/a&gt; method for sending them to the user's browser. However, the &lt;code&gt;Write&lt;/code&gt; method needs to be called from a dedicated page that serves up &lt;em&gt;just the relevant image&lt;/em&gt;, so it isn't a solution for the original scenario. &lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In case you've not heard of them before, data URIs are a kind of URL scheme documented by &lt;a href="http://tools.ietf.org/html/rfc2397"&gt;RFC 2397&lt;/a&gt;. They're quite simple, really - here's the relevant part of the specification: &lt;/p&gt;
&lt;pre&gt;data:[&amp;lt;mediatype&amp;gt;][;base64],&amp;lt;data&amp;gt;

dataurl    := "data:" [ mediatype ] [ ";base64" ] "," data
mediatype  := [ type "/" subtype ] *( ";" parameter )
data       := *urlchar
parameter  := attribute "=" value
&lt;/pre&gt;
&lt;p&gt;It takes &lt;strong&gt;two&lt;/strong&gt; pieces of information to create a data URI: the data and its media type (ex: "image/png"). (Although the media type appears optional above, it defaults to "text/plain" when absent - which is unsuitable for most common data URI scenarios.) Pretty much the only interesting thing you can do with data URIs on the server is write them, so the &lt;code&gt;DataUri&lt;/code&gt; web helper exposes a single &lt;code&gt;Write&lt;/code&gt; method with five flavors. The media type is always passed as a string (feel free to use the &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.mime.mediatypenames.aspx"&gt;MediaTypeNames&lt;/a&gt; class to help here), but the data can be provided as a file name &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;byte[]&lt;/code&gt;, &lt;code&gt;IEnumerable&amp;lt;byte&amp;gt;&lt;/code&gt;, or &lt;code&gt;Stream&lt;/code&gt;. That's four methods; the fifth one takes &lt;strong&gt;just&lt;/strong&gt; the file name &lt;code&gt;string&lt;/code&gt; and &lt;em&gt;infers&lt;/em&gt; the media type from the file's extension (ex: ".png" &lt;nobr&gt;-&amp;gt;&lt;/nobr&gt; "image/png"). &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: Technically, it would be possible for the other methods to infer media type as well by examining the bytes of data. However, doing so would require quite a bit more work and would always be subject to error. On the other hand, inferring media type from the file's extension is computationally trivial and much more likely to be correct in practice. &lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For an example of the &lt;code&gt;DataUri&lt;/code&gt; helper in action, here's the Razor code to implement the "image from the database" scenario that started it all: &lt;/p&gt;
&lt;pre style="color:#0000ff"&gt;&lt;span style="color:#000000;background-color:yellow"&gt;@{&lt;/span&gt;
    &lt;span style="color:#2b91af"&gt;IEnumerable&lt;/span&gt;&lt;span style="color:#000000"&gt;&amp;lt;&lt;/span&gt;dynamic&lt;span style="color:#000000"&gt;&amp;gt; databaseImages;
    &lt;/span&gt;using&lt;span style="color:#000000"&gt; (&lt;/span&gt;var&lt;span style="color:#000000"&gt; database = &lt;/span&gt;&lt;span style="color:#2b91af"&gt;Database&lt;/span&gt;&lt;span style="color:#000000"&gt;.Open(&lt;/span&gt;&lt;span style="color:#a31515"&gt;"Delay.Web.Helpers.Sample.Database"&lt;/span&gt;&lt;span style="color:#000000"&gt;))
    {
        databaseImages = database.Query(&lt;/span&gt;&lt;span style="color:#a31515"&gt;"SELECT * FROM Images"&lt;/span&gt;&lt;span style="color:#000000"&gt;);
    }

    &lt;/span&gt;&lt;span style="color:#008000"&gt;// ...&lt;/span&gt;

    foreach&lt;span style="color:#000000"&gt;(&lt;/span&gt;var&lt;span style="color:#000000"&gt; image &lt;/span&gt;in&lt;span style="color:#000000"&gt; databaseImages)
    {
        &lt;/span&gt;&amp;lt;&lt;span style="color:#800000"&gt;p&lt;/span&gt;&amp;gt;
            &amp;lt;&lt;span style="color:#800000"&gt;img&lt;/span&gt;&lt;span style="color:#ff0000"&gt; src&lt;/span&gt;="&lt;span style="color:#000000"&gt;@&lt;/span&gt;DataUri.Write(image.Content, image.MediaType)"&lt;span style="color:#ff0000"&gt; alt&lt;/span&gt;="&lt;span style="color:#000000"&gt;@&lt;/span&gt;image.Name"&lt;span style="color:#ff0000"&gt;
                 width&lt;/span&gt;="&lt;span style="color:#000000"&gt;@&lt;/span&gt;image.Width"&lt;span style="color:#ff0000"&gt; height&lt;/span&gt;="&lt;span style="color:#000000"&gt;@&lt;/span&gt;image.Height"&lt;span style="color:#ff0000"&gt; style&lt;/span&gt;="&lt;span style="color:#ff0000"&gt;vertical-align&lt;/span&gt;:middle"/&amp;gt;&lt;span style="color:#000000"&gt;
            @image.Name
        &lt;/span&gt;&amp;lt;/&lt;span style="color:#800000"&gt;p&lt;/span&gt;&amp;gt;&lt;span style="color:#000000"&gt;
    }&lt;/span&gt;
&lt;span style="color:#000000;background-color:yellow"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Easy-peasy lemon-squeezy! &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And here's an example of using the file name-only override for media type inference: &lt;/p&gt;
&lt;pre style="color:#0000ff"&gt;&amp;lt;&lt;span style="color:#800000"&gt;script&lt;/span&gt;&lt;span style="color:#ff0000"&gt; src&lt;/span&gt;="&lt;span style="color:#000000"&gt;@&lt;/span&gt;DataUri.Write(Server.MapPath(&lt;span style="color:#a31515"&gt;"Sample-Script.js"&lt;/span&gt;))"&lt;span style="color:#ff0000"&gt; type&lt;/span&gt;="text/javascript"&amp;gt;&amp;lt;/&lt;span style="color:#800000"&gt;script&lt;/span&gt;&amp;gt;&lt;/pre&gt;
&lt;p&gt;Which comes out like this in the HTML that's sent to the browser: &lt;/p&gt;
&lt;pre style="color:#0000ff"&gt;&amp;lt;&lt;span style="color:#800000"&gt;script&lt;/span&gt;&lt;span style="color:#ff0000"&gt; src&lt;/span&gt;="data:text/javascript;base64,77u/ZG9j...PicpOw=="&lt;span style="color:#ff0000"&gt; type&lt;/span&gt;="text/javascript"&amp;gt;&amp;lt;/&lt;span style="color:#800000"&gt;script&lt;/span&gt;&amp;gt;&lt;/pre&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: This particular example (using a data URI for a script file) doesn't render in all browsers. Specifically, Internet Explorer 8 (and earlier) blocks script delivered like this because of security concerns. Fortunately, &lt;a href="http://microsoft.com/ie9"&gt;Internet Explorer 9&lt;/a&gt; has addressed those concerns and renders as expected. &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cesso.org/Samples/DelayWebHelpers/Delay.Web.Helpers.zip"&gt;[Click here to download the Delay.Web.Helpers assembly, complete source code, automated tests, and the sample web site.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.nuget.org/List/Packages/Delay.Web.Helpers"&gt;[Click here to go to the NuGet page for Delay.Web.Helpers which includes the DLL and its associated documentation/IntelliSense XML file.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.nuget.org/List/Packages/Delay.Web.Helpers.SampleWebSite"&gt;[Click here to go to the NuGet page for the Delay.Web.Helpers.SampleWebSite which includes the sample site that demonstrates everything.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Data URIs are pretty neat things - though it's important to be aware they have their drawbacks as well. Fortunately, the &lt;a href="http://en.wikipedia.org/wiki/Data_Uri"&gt;Wikipedia article&lt;/a&gt; does a good job discussing the pros and cons, so I highly recommend looking it over &lt;strong&gt;before&lt;/strong&gt; converting all your content. &lt;nobr&gt;:)&lt;/nobr&gt; Creating a data URI manually isn't rocket science, but it &lt;strong&gt;is&lt;/strong&gt; the kind of thing ASP.NET web helpers are perfectly suited for. If you're a &lt;a href="http://en.wikipedia.org/wiki/Base64"&gt;base-64&lt;/a&gt; nut, maybe you'll continue doing this by hand - but for everyone else, I hope the new &lt;code&gt;DataUri&lt;/code&gt; class in the &lt;code&gt;Delay.Web.Helpers&lt;/code&gt; assembly proves useful! &lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10150550" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Web+Platform/">Web Platform</category></item><item><title>Each one is the best - for different definitions of "best" [The BestFitPanel collection of layout containers provides flexible, easy-to-use options for Silverlight, WPF, and Windows Phone applications]</title><link>http://blogs.msdn.com/b/delay/archive/2011/03/30/each-one-is-the-best-for-different-definitions-of-quot-best-quot-the-bestfitpanel-collection-of-layout-containers-provides-flexible-easy-to-use-options-for-silverlight-wpf-and-windows-phone-applications.aspx</link><pubDate>Wed, 30 Mar 2011 17:32:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10147845</guid><dc:creator>David Anson</dc:creator><slash:comments>13</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10147845</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/03/30/each-one-is-the-best-for-different-definitions-of-quot-best-quot-the-bestfitpanel-collection-of-layout-containers-provides-flexible-easy-to-use-options-for-silverlight-wpf-and-windows-phone-applications.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;Just over a year ago, &lt;a href="http://blogs.msdn.com/b/delay/archive/2010/02/11/this-one-time-at-band-camp-a-banded-stackpanel-implementation-for-silverlight-and-wpf.aspx#9964178"&gt;a couple of readers asked me&lt;/a&gt; about a WPF/Silverlight &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.panel.aspx"&gt;Panel&lt;/a&gt; that arranged things to make "best use" of available space &lt;em&gt;without&lt;/em&gt; requiring the developer to set a bunch of stuff up in advance or know how many child elements there would be. Interestingly, this is not a scenario the default &lt;code&gt;Panel&lt;/code&gt; implementations handle particularly well... &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.grid.aspx"&gt;Grid&lt;/a&gt; [WPF/SL/WP] is capable of pretty much anything, but requires the developer to explicitly specify how everything lines up relative to the rows and columns they must manually define. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.stackpanel.aspx"&gt;StackPanel&lt;/a&gt; [WPF/SL/WP] arranges an arbitrary number of items in a tightly-packed line, but overflows when there are too many and leaves empty space when there are too few. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.canvas.aspx"&gt;Canvas&lt;/a&gt; [WPF/SL/WP] provides the ultimate in flexibility, but contains absolutely &lt;strong&gt;no&lt;/strong&gt; layout logic and pushes all that overhead onto the developer. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.wrappanel.aspx"&gt;WrapPanel&lt;/a&gt; [WPF/&lt;a href="http://silverlight.codeplex.com/"&gt;SLTK&lt;/a&gt;/&lt;a href="http://silverlight.codeplex.com/"&gt;WPTK&lt;/a&gt;] flows its elements "book-style" left-to-right, top-to-bottom, but runs content off the screen when there's not enough room and can size things surprisingly unless you tell it how big items should be. &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: When scrolling content that doesn't fit is acceptable, &lt;code&gt;WrapPanel&lt;/code&gt; can be quite a good choice. And if you like the idea, but want something a little more aesthetically pleasing, please have a look at my &lt;a href="http://blogs.msdn.com/b/delay/archive/2009/12/08/that-s-a-wrappanel-and-i-am-outta-here-a-balanced-wrappanel-implementation-for-silverlight-and-wpf.aspx"&gt;BalancedWrapPanel&lt;/a&gt; &lt;a href="http://blogs.msdn.com/b/delay/archive/2009/12/13/wrap-music-a-more-flexible-balanced-wrappanel-implementation-for-silverlight-and-wpf.aspx"&gt;implementation&lt;/a&gt;... &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/blockquote&gt;
&lt;blockquote&gt;&lt;strong&gt;Further aside&lt;/strong&gt;: On the other hand, if you're looking for something more like a &lt;code&gt;StackPanel&lt;/code&gt; but with multiple columns (or rows), you might instead be interested in my &lt;a href="http://blogs.msdn.com/b/delay/archive/2010/02/11/this-one-time-at-band-camp-a-banded-stackpanel-implementation-for-silverlight-and-wpf.aspx"&gt;BandedStackPanel implementation&lt;/a&gt;. &lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.dockpanel.aspx"&gt;DockPanel&lt;/a&gt; [WPF/SLTK] crams everything against the edge of its layout slot and leaves a big "chunk" in the center for whatever element is lucky enough to end up there. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.uniformgrid.aspx"&gt;UniformGrid&lt;/a&gt; [WPF] does okay at sensible layout without a lot of fuss - but its default behavior can leave a lot of blank space and so it's best if you tell it in advance how many items there are. &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;That said, &lt;em&gt;please&lt;/em&gt; don't get me wrong: I'm not complaining about the default set of layout containers - I think they're all good at what they do! However, in the context of the original "just do the right thing for me" scenario, none of them quite seems &lt;strong&gt;ideal&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;So when this question came up before, I mentioned I'd written some code that seemed pretty relevant, but that it was for &lt;a href="http://en.wikipedia.org/wiki/Windows_Forms"&gt;Windows Forms&lt;/a&gt; and therefore didn't map cleanly to the different layout model used by Silverlight and WPF. Soon thereafter, I created a sample project to implement a "best fit" panel for Silverlight and WPF (and got nearly all the code written!) - but then found myself distracted by other topics and never managed to write it up formally... &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Until now! &lt;/p&gt;
&lt;p&gt;Today I'm sharing the three &lt;code&gt;Panel&lt;/code&gt; classes I originally wrote for Silverlight and WPF, two abstract base classes they're built on, an extra &lt;code&gt;Panel&lt;/code&gt; I wrote just for this post &lt;em&gt;and&lt;/em&gt; a Windows Phone 7 sample application! (Because this code supports Silverlight 3, it works just as well on the phone as on the desktop.) Hopefully the extra goodness in today's release will offset the delay in posting it... &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The foundation for everything, &lt;code&gt;BestFitPanel&lt;/code&gt; is an abstract base class that implements &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.measureoverride.aspx"&gt;MeasureOverride&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.arrangeoverride.aspx"&gt;ArrangeOverride&lt;/a&gt; to arrange its children in a grid that's &lt;em&gt;M&lt;/em&gt; columns wide and &lt;em&gt;N&lt;/em&gt; rows high. What's nice is that the values of &lt;em&gt;M&lt;/em&gt; and &lt;em&gt;N&lt;/em&gt; are left to subclasses to define by overriding the &lt;code&gt;CalculateBestFit&lt;/code&gt; method. Therefore, a subclass only needs to worry about columns/rows and the base class only needs to worry about handling layout. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;MostBigPanel&lt;/code&gt; is a &lt;code&gt;BestFitPanel&lt;/code&gt; subclass that figures out which values of &lt;em&gt;M&lt;/em&gt; and &lt;em&gt;N&lt;/em&gt; maximize the length of the smaller dimension (be it width or height) of each item. In other words, it avoids long, skinny rectangles in favor of more evenly proportioned ones. &lt;/p&gt;
&lt;img height="348" width="614" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/2570.BestFitPanel_2D00_Big.png" alt="MostBigPanel" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;MostFullPanel&lt;/code&gt; is a &lt;code&gt;BestFitPanel&lt;/code&gt; subclass that maximizes the total area occupied by the &lt;code&gt;Panel&lt;/code&gt;'s children. Specifically, an arrangement without any empty cells will be preferred over one with an empty cell or two - even if the shape of the resulting items is less balanced. &lt;/p&gt;
&lt;img height="348" width="614" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/0844.BestFitPanel_2D00_Full.png" alt="MostFullPanel" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Sometimes it's nice to optimize for the "shape" of individual items - and for that there's the &lt;code&gt;BestAnglePanel&lt;/code&gt; abstract base class which chooses the combination of &lt;em&gt;M&lt;/em&gt; and &lt;em&gt;N&lt;/em&gt; that yields items with a diagonal closest to some angle &lt;em&gt;A&lt;/em&gt; determined by the &lt;code&gt;GetIdealAngle&lt;/code&gt; override. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;MostSquarePanel&lt;/code&gt; is a &lt;code&gt;BestAnglePanel&lt;/code&gt; subclass that uses a value of 45&amp;deg; for &lt;em&gt;A&lt;/em&gt; and therefore prefers arrangements where items are closest to being square. &lt;/p&gt;
&lt;img height="348" width="614" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/6708.BestFitPanel_2D00_Square.png" alt="MostSquarePanel" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;MostGoldenPanel&lt;/code&gt;, on the other hand, is a &lt;code&gt;BestAnglePanel&lt;/code&gt; subclass that uses a value for &lt;em&gt;A&lt;/em&gt; that matches that of a horizontally-oriented &lt;a href="http://en.wikipedia.org/wiki/Golden_rectangle"&gt;golden rectangle&lt;/a&gt;. Golden rectangles are said to be among the most aesthetically pleasing shapes, and this class makes it easy to create layouts based around them. &lt;/p&gt;
&lt;img height="348" width="614" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/0028.BestFitPanel_2D00_Golden.png" alt="MostGoldenPanel" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Of course, there are very few values of &lt;em&gt;M&lt;/em&gt; and &lt;em&gt;N&lt;/em&gt; to choose from, so it's not uncommon that all the implementations above choose the &lt;strong&gt;same&lt;/strong&gt; values. The interesting differences tend to show up at various "special" sizes where each &lt;code&gt;BestFitPanel&lt;/code&gt; selects a &lt;em&gt;different&lt;/em&gt; layout. This is why the sample application allows you to enable all the panels at once: the sample content is translucent, so you can see where things differ and how each implementation is handling a particular configuration. I made sure all the arrangements above were unique - here's how it looks when they're all shown at once: &lt;/p&gt;
&lt;img height="348" width="614" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/6327.BestFitPanel_2D00_All.png" alt="All BestFitPanels overlapped" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For a real-world example of &lt;code&gt;BestFitPanel&lt;/code&gt; in action, I've adapted the "ImageLoading" sample from &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/03/03/quot-your-feedback-is-important-to-us-please-stay-on-the-line-quot-improving-windows-phone-7-application-performance-is-even-easier-with-these-lowprofileimageloader-and-deferredloadlistbox-updates.aspx"&gt;my Windows Phone 7 PhonePerformance project&lt;/a&gt; to use &lt;code&gt;MostBigPanel&lt;/code&gt; (which is what I would have used if I'd written this post beforehand!). If you're not familiar with that sample, it finds all the followers of an arbitrary &lt;a href="https://twitter.com/"&gt;Twitter&lt;/a&gt; account and shows their images. Because it's impossible to know in advance how many followers an account has, trying to use one of the "in-box" &lt;code&gt;Panel&lt;/code&gt; implementations is likely to be tricky or require writing code to configure things at run-time. But &lt;code&gt;BestFitPanel&lt;/code&gt; makes this scenario &lt;strong&gt;easy&lt;/strong&gt; by automatically showing all the items &lt;em&gt;and&lt;/em&gt; optimizing for the most important attribute ("bigness" in this case). Here's the &lt;strong&gt;same&lt;/strong&gt; code/XAML with different numbers of followers (400, 200, and 100) to show how things "just work": &lt;/p&gt;
&lt;img height="400" width="240" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/4846.BestFitPanel_2D00_400.jpg" alt="BestFitPanel with 400 items" /&gt; &lt;img height="400" width="240" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/7673.BestFitPanel_2D00_200.jpg" alt="BestFitPanel with 200 items" /&gt; &lt;img height="400" width="240" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/4034.BestFitPanel_2D00_100.jpg" alt="BestFitPanel with 100 items" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cesso.org/Samples/BestFitPanel/BestFitPanel.zip"&gt;[Click here to download the complete source code for all the BestFitPanels along with sample projects for Silverlight, WPF, and Windows Phone 7.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The concept of a reusable, container-agnostic &lt;code&gt;Panel&lt;/code&gt; for layout is tremendously powerful. The "stock" implementations for Silverlight, WPF, and Windows Phone are all quite useful, but sometimes you'll find that writing a custom &lt;code&gt;Panel&lt;/code&gt; is the only way to get &lt;strong&gt;exactly&lt;/strong&gt; the layout you're looking for. Fortunately, layout code is pretty straightforward - and classes like &lt;code&gt;BestFitPanel&lt;/code&gt; and &lt;code&gt;BestAnglePanel&lt;/code&gt; make it even easier. So the next time you're looking for a flexible container that works sensibly &lt;em&gt;without&lt;/em&gt; requiring a bunch of prior knowledge or hand-holding, I hope you'll remember this post and consider using a &lt;code&gt;BestFitPanel&lt;/code&gt; - or a custom subclass! &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10147845" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Silverlight/">Silverlight</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/WPF/">WPF</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Windows+Phone/">Windows Phone</category></item><item><title>What next, a DOS version?? [Free tool and source code to temporarily prevent a computer from entering sleep mode - 32-bit and 64-bit versions now support Windows XP!]</title><link>http://blogs.msdn.com/b/delay/archive/2011/03/23/what-next-a-dos-version-free-tool-and-source-code-to-temporarily-prevent-a-computer-from-entering-sleep-mode-32-bit-and-64-bit-versions-now-support-windows-xp.aspx</link><pubDate>Wed, 23 Mar 2011 17:21:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10144913</guid><dc:creator>David Anson</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10144913</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/03/23/what-next-a-dos-version-free-tool-and-source-code-to-temporarily-prevent-a-computer-from-entering-sleep-mode-32-bit-and-64-bit-versions-now-support-windows-xp.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/b/delay/archive/2009/09/30/give-your-computer-insomnia-free-tool-and-source-code-to-temporarily-prevent-a-machine-from-going-to-sleep.aspx"&gt;I used .NET 3.5 to write the first version of Insomnia about a year and a half ago.&lt;/a&gt; Its purpose in life is to make it easy for anyone to temporarily prevent their computer from going to sleep without having to futz with system-wide power options every time. Insomnia did its job well and people used it in ways I didn't expect: &lt;a href="http://blogs.msdn.com/b/delay/archive/2010/02/01/the-customer-is-always-right-updated-free-tool-and-source-code-to-prevent-a-machine-from-going-to-sleep.aspx"&gt;there were requests to allow the window to be minimized to the notification area, so I posted an update a few months later which allowed that&lt;/a&gt;. As a result, some people leave Insomnia running for extended periods of time (e.g., many days) and seemed likely to benefit from a version that didn't include the overhead of the .NET Framework, &lt;a href="http://blogs.msdn.com/b/delay/archive/2010/12/14/no-rest-for-the-weary-free-tool-and-source-code-to-temporarily-prevent-a-computer-from-entering-sleep-mode-now-available-for-net-32-bit-and-64-bit.aspx"&gt;so I created new, native-code 32- and 64-bit versions of Insomnia late last year&lt;/a&gt;. These new versions did exactly what they were intended to and were also well received - but there's a catch... &lt;/p&gt;
&lt;p&gt;Every couple of weeks or so, Insomnia gets featured by one of those "cool app of the day" sites (which is awesome, so thanks for that!). I never know when it's going to happen, but I can tell exactly when it &lt;strong&gt;does&lt;/strong&gt; because I suddenly get a flurry of comments telling me the native-code versions don't run on Windows XP... &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: Many of you may be too young to remember; &lt;a href="http://en.wikipedia.org/wiki/Windows_XP"&gt;Windows XP&lt;/a&gt; is an operating system Microsoft released about &lt;em&gt;ten years ago&lt;/em&gt; - practically an eternity in computing terms! And yet, a lot of people are &lt;strong&gt;still&lt;/strong&gt; running XP... &lt;nobr&gt;;)&lt;/nobr&gt; &lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Although I didn't set out to &lt;strong&gt;not&lt;/strong&gt; support Windows XP, I also didn't make a specific effort &lt;strong&gt;to&lt;/strong&gt; support it - and as the saying goes, "if you don't test it, it won't work". Well it &lt;em&gt;didn't&lt;/em&gt; work, so &lt;a href="http://blogs.msdn.com/b/delay/archive/2009/09/30/give-your-computer-insomnia-free-tool-and-source-code-to-temporarily-prevent-a-machine-from-going-to-sleep.aspx#10110834"&gt;I investigated and summarized my findings in a reply on my blog&lt;/a&gt;: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I've looked into the Windows XP (SP3) issue just now - the "ordinal 380" error is due to the fact that the LoadIconMetric API isn't supported on OSes prior to Windows Vista. It's easy enough to use the more general LoadIcon API and then native Insomnia starts successfully on XP - but it doesn't show any text. The missing text is because the LM_GETIDEALSIZE message isn't supported prior to Vista, either - and in this case the simpler LM_GETIDEALHEIGHT message isn't a direct substitute. What's more, the current icon doesn't seem to be recognized by XP, either (it shows the generic application icon in Explorer and nothing in the tray). Neither of these issues (text measurement and icon) are overly difficult to fix, but they're also not trivial and I'm not sure how worthwhile it is to spend time and effort to support native Insomnia on Windows XP when the .NET version is reported to work just fine... &lt;/p&gt;
&lt;p&gt;That said, I'm open to input here. If a lot of people think this is useful, I'll look into doing the work - but if everyone's happy to use the .NET version on XP, I'm happy to let them. &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For what it's worth, I don't recall anybody coming back with a compelling reason why XP support is &lt;em&gt;necessary&lt;/em&gt; - but after getting another round of XP feedback recently, I decided it was something I should do simply because it comes up so often. &lt;strong&gt;Therefore, I'm happy to announce that Insomnia's native 32-bit and 64-bit versions now support Windows XP!&lt;/strong&gt; &lt;/p&gt;
&lt;img height="396" width="528" src="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-60-92-metablogapi/8284.Insomnia_2D00_XP.jpg" alt="Insomnia running on Windows XP" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Note&lt;/strong&gt;: With today's update (and in lieu of feedback to the contrary), the native versions of Insomnia are believed to run everywhere the .NET version does. Because there's no functional difference between the native- and managed-code implementations, I'll probably deprecate the .NET version soon. (Please don't get me wrong: I &lt;strong&gt;love&lt;/strong&gt; the significant productivity benefits of using .NET! They're just moot here because I'm already doing the work to maintain the native implementations.) &lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;By far the biggest change with this release is the replacement of the &lt;a href="http://msdn.microsoft.com/en-us/library/bb760706.aspx"&gt;SysLink&lt;/a&gt; control with one I wrote called &lt;code&gt;IdealSizeStatic&lt;/code&gt;. &lt;a href="http://blogs.msdn.com/b/delay/archive/2010/12/14/no-rest-for-the-weary-free-tool-and-source-code-to-temporarily-prevent-a-computer-from-entering-sleep-mode-now-available-for-net-32-bit-and-64-bit.aspx"&gt;Recall from the previous post that there were two things I liked about SysLink&lt;/a&gt;: its ability to return an "ideal size" and its ability to render hyperlinks. Both of these features worked like I wanted, but the lack of support for &lt;a href="http://msdn.microsoft.com/en-us/library/bb760718.aspx"&gt;LM_GETIDEALSIZE&lt;/a&gt; on XP was a deal-breaker. When creating &lt;code&gt;IdealSizeStatic&lt;/code&gt;, I kept things as simple as possible while also being consistent with how &lt;code&gt;SysLink&lt;/code&gt; operates (ex: the use of &lt;a href="http://msdn.microsoft.com/en-us/library/bb787524.aspx"&gt;WM_CTLCOLORSTATIC&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/ms632642.aspx"&gt;WM_SETFONT&lt;/a&gt;) &lt;em&gt;just in case&lt;/em&gt; I decide to switch back some day. &lt;code&gt;IdealSizeStatic&lt;/code&gt; ends up being a pretty general-purpose control that offers &lt;code&gt;WM_GETIDEALSIZE&lt;/code&gt; for querying the bounds (width and height) of its text - which is handy for the WPF-like layout pass I implemented in Insomnia. &lt;/p&gt;
&lt;p&gt;Despite my goal of keeping &lt;code&gt;IdealSizeStatic&lt;/code&gt; as simple as possible, I didn't want to give up on the hyperlink functionality Insomnia already used, so I did the work to support that scenario. Specifically, if the first character of its window title is '_', &lt;code&gt;IdealSizeStatic&lt;/code&gt; assumes it's showing a link, strips off the '_' prefix, and renders the control text in blue. Assuming &lt;a href="http://msdn.microsoft.com/en-us/library/ms632600.aspx"&gt;WS_TABSTOP&lt;/a&gt; has also been set, it will show a focus rectangle when relevant and respond to mouse left-button clicks and space bar presses by calling &lt;a href="http://msdn.microsoft.com/en-us/library/bb762154.aspx"&gt;ShellExecuteEx&lt;/a&gt; to open the link in the user's preferred web browser. &lt;/p&gt;
&lt;p&gt;&lt;code&gt;IdealSizeStatic&lt;/code&gt; won't win any awards for "Win32 control of the year", but it seems to do &lt;em&gt;just&lt;/em&gt; enough to be an adequate replacement for &lt;code&gt;SysLink&lt;/code&gt;. &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Having purged the &lt;code&gt;SysLink&lt;/code&gt; control, Insomnia no longer has a dependency on the &lt;a href="http://msdn.microsoft.com/en-us/library/bb775493.aspx"&gt;COMCTL32 common control DLL&lt;/a&gt; and the corresponding code to initialize it and &lt;a href="http://msdn.microsoft.com/en-us/library/bb773175.aspx#using_manifests"&gt;incorporate the necessary manifest&lt;/a&gt; has been removed. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The other problem with running on XP was the use of the &lt;a href="http://msdn.microsoft.com/en-us/library/bb775701.aspx"&gt;LoadIconMetric&lt;/a&gt; API to retrieve the application icon for the &lt;a href="http://msdn.microsoft.com/en-us/library/aa511448.aspx"&gt;notification area&lt;/a&gt;. Fortunately, it's pretty simple to fall back to the &lt;a href="http://msdn.microsoft.com/en-us/library/ms648045.aspx"&gt;LoadImage&lt;/a&gt; API instead - though it doesn't offer the same "auto-scaling" magic the original function does. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Speaking of icons, one curious problem with XP was that Windows Explorer showed the default application icon instead of the custom one embedded in the Insomnia executable. This ends up being because the custom &lt;a href="http://en.wikipedia.org/wiki/ICO_(file_format)"&gt;ICO file&lt;/a&gt; generator I wrote/use outputs icon images in the 32-bit alpha-blended &lt;a href="http://en.wikipedia.org/wiki/Portable_Network_Graphics"&gt;PNG format&lt;/a&gt; and that format isn't supported on Windows XP. This time around, I've &lt;strong&gt;also&lt;/strong&gt; embedded 16x16 and 32x32 icons with the older 24-bit image+mask format. Because this type &lt;strong&gt;is&lt;/strong&gt; recognized by XP, the icon shows up correctly. &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: Unfortunately, XP still has a bit of trouble rendering the bottom-most pixels of the 32x32 icon in the application's property page. But that property page seems to have a &lt;em&gt;variety&lt;/em&gt; of troubles with icons - there was a similar issue with the previous version even under Windows 7! &lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I've also fixed a couple of minor issues I noticed along the way - none of which should matter much in practice. The new version of the 32-bit and 64-bit builds of Insomnia is &lt;strong&gt;2011-03-19&lt;/strong&gt;. The version number of the .NET build has not changed and remains 2010-01-29. &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cesso.org/Samples/Insomnia/Insomnia.zip"&gt;[Click here to download the 32-bit, 64-bit, and .NET builds of Insomnia along with the complete source code for everything.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I initially put off supporting XP because I figured very few people still used it. However, the steady stream of feedback from XP users finally convinced me there's enough interest to make the effort worthwhile. Windows 7 and Windows Vista users won't see functional differences with this release, but they &lt;strong&gt;will&lt;/strong&gt; benefit from the slightly reduced footprint that comes from breaking the ties to &lt;code&gt;COMCTL32.dll&lt;/code&gt;. My &lt;code&gt;IdealSizeStatic&lt;/code&gt; control isn't a &lt;em&gt;perfect&lt;/em&gt; replacement for the &lt;code&gt;SysLink&lt;/code&gt; control, but it gets close enough - and does so without being overly complex. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Windows XP users&lt;/strong&gt;: I hope you like the new support. Thanks for your patience! &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10144913" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/Utilities/">Utilities</category></item><item><title>MEF lab [How to: Keep implementation details out of a MEF contract assembly by implementing an interface-based event handler]</title><link>http://blogs.msdn.com/b/delay/archive/2011/03/16/mef-lab-how-to-keep-implementation-details-out-of-a-mef-contract-assembly-by-implementing-an-interface-based-event-handler.aspx</link><pubDate>Wed, 16 Mar 2011 17:19:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10142165</guid><dc:creator>David Anson</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10142165</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/03/16/mef-lab-how-to-keep-implementation-details-out-of-a-mef-contract-assembly-by-implementing-an-interface-based-event-handler.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;In the previous post, I showed &lt;a href="http://blogs.msdn.com/b/delay/archive/2011/03/09/mef-addict-combining-net-4-s-type-embedding-and-mef-to-enable-a-smooth-upgrade-story-for-applications-and-their-extensions.aspx"&gt;how to combine .NET 4's "type embedding" capability with the Managed Extensibility Framework (MEF) to create an application that can be upgraded without breaking existing extensions&lt;/a&gt;. In that post, I described the notion of a MEF "contract assembly" thusly: &lt;/p&gt;
&lt;blockquote&gt;&lt;em&gt;The contract assembly is the place where the public interfaces of an application live. Because interfaces are generally the &lt;strong&gt;only&lt;/strong&gt; thing in a contract assembly, both the application and its extensions can reference it &lt;strong&gt;and&lt;/strong&gt; it can be published as part of an &lt;a href="http://en.wikipedia.org/wiki/Sdk"&gt;SDK&lt;/a&gt; without needing to include implementation details, too. &lt;/em&gt;&lt;/blockquote&gt;
&lt;p&gt;The idea is pretty straightforward: an application's public &lt;a href="http://en.wikipedia.org/wiki/Api"&gt;API&lt;/a&gt; should be constant even if the underlying implementation changes dramatically. Similarly, the act of servicing an application (e.g., patching it, fixing bugs, etc.) should never require updates to its public contract assembly. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Fortunately it's pretty easy to ensure a contract assembly contains &lt;strong&gt;only&lt;/strong&gt; interfaces and .NET Framework classes (which are safe because they're automatically versioned for you). But things get a little tricky when you decide to expose a custom event... &lt;/p&gt;
&lt;p&gt;Imagine your application defines an event that needs to pass specific information in its &lt;a href="http://msdn.microsoft.com/en-us/library/system.eventargs.aspx"&gt;EventArgs&lt;/a&gt;. The first thing you'd do is create a subclass - something like &lt;code&gt;MyEventArgs&lt;/code&gt; - and store the custom data there. Because the custom event is part of a public interface, it's part of the contract assembly - and because the contract assembly is always self-contained, the definition of &lt;code&gt;MyEventArgs&lt;/code&gt; needs to be in there as well. &lt;strong&gt;However&lt;/strong&gt;, while &lt;code&gt;MyEventArgs&lt;/code&gt; is probably quite simple, its implementation is... um... an implementation detail [ &lt;nobr&gt;:)&lt;/nobr&gt; ] and does &lt;strong&gt;not&lt;/strong&gt; belong in the contract assembly. &lt;/p&gt;
&lt;p&gt;Okay, no problem, create an &lt;code&gt;IMyEventArgs&lt;/code&gt; interface for the custom properties/methods (which is perfectly acceptable for a contract assembly) and then add something like the following to the application (or an extension): &lt;/p&gt;
&lt;pre style="color:#2b91af"&gt;&lt;span style="color:#0000ff"&gt;class&lt;/span&gt; MyEventArgs&lt;span style="color:#000000"&gt; : &lt;/span&gt;EventArgs&lt;span style="color:#000000"&gt;, &lt;/span&gt;IMyEventArgs&lt;/pre&gt;
&lt;p&gt;The public interface (in the contract assembly) only needs to expose the following and all will be well: &lt;/p&gt;
&lt;pre style="color:#2b91af;font-style:italic"&gt;&lt;span style="color:#0000ff"&gt;event&lt;/span&gt; EventHandler&lt;span style="color:#000000"&gt;&amp;lt;&lt;/span&gt;IMyEventArgs&lt;span style="color:#000000"&gt;&amp;gt; MyEvent;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Oops, sorry! No can do: &lt;/p&gt;
&lt;pre&gt;The type 'IMyEventArgs' cannot be used as type parameter 'TEventArgs' in
the generic type or method 'System.EventHandler&amp;lt;TEventArgs&amp;gt;'. There is no
implicit reference conversion from 'IMyEventArgs' to 'System.EventArgs'.&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The compiler is complaining there's no way for it to know that an arbitrary implementation of &lt;code&gt;IMyEventArgs&lt;/code&gt; can &lt;strong&gt;always&lt;/strong&gt; be converted to an &lt;code&gt;EventArgs&lt;/code&gt; instance (which is what the &lt;code&gt;TEventArgs&lt;/code&gt; generic type parameter of &lt;a href="http://msdn.microsoft.com/en-us/library/db0etb8x.aspx"&gt;EventHandler&amp;lt;TEventArgs&amp;gt;&lt;/a&gt; is constrained to). Because there's not an obvious way to resolve this ambiguity (the &lt;a href="http://msdn.microsoft.com/en-us/library/z5z9kes2.aspx"&gt;implicit keyword&lt;/a&gt; doesn't help because "user-defined conversions to or from an interface are not allowed"), you &lt;em&gt;might&lt;/em&gt; be tempted to move the definition of &lt;code&gt;MyEventArgs&lt;/code&gt; into the contract assembly and pass &lt;strong&gt;that&lt;/strong&gt; for &lt;code&gt;TEventArgs&lt;/code&gt; instead. That will certainly work (and it's not the &lt;em&gt;worst&lt;/em&gt; thing in the world) but it feels like there ought to be a better way... &lt;/p&gt;
&lt;p&gt;And there is! Instead of using a new-fangled generic event handler, we could instead use a classic .NET 1.0-style &lt;a href="http://msdn.microsoft.com/en-us/library/system.delegate.aspx"&gt;delegate&lt;/a&gt; in our contract assembly: &lt;/p&gt;
&lt;pre style="color:#808080"&gt;/// &amp;lt;summary&amp;gt;
///&lt;span style="color:#008000"&gt; Interface for extensions to MyApplication.
&lt;/span&gt;/// &amp;lt;/summary&amp;gt;
&lt;span style="color:#0000ff"&gt;public interface&lt;/span&gt;&lt;span style="color:#2b91af"&gt; IMyContract
&lt;/span&gt;&lt;span style="color:#000000"&gt;{
    &lt;/span&gt;/// &amp;lt;summary&amp;gt;
    ///&lt;span style="color:#008000"&gt; Simple method.
&lt;/span&gt;    /// &amp;lt;/summary&amp;gt;
&lt;span style="color:#0000ff"&gt;    void&lt;/span&gt;&lt;span style="color:#000000"&gt; MyMethod();

    &lt;/span&gt;/// &amp;lt;summary&amp;gt;
    ///&lt;span style="color:#008000"&gt; Simple event with custom interface-based EventArgs.
&lt;/span&gt;    /// &amp;lt;/summary&amp;gt;
&lt;span style="color:#0000ff"&gt;    event&lt;/span&gt;&lt;span style="color:#2b91af"&gt; MyEventHandler&lt;/span&gt;&lt;span style="color:#000000"&gt; MyEvent;
}

&lt;/span&gt;/// &amp;lt;summary&amp;gt;
///&lt;span style="color:#008000"&gt; Delegate for events of type IMyEventArgs.
&lt;/span&gt;/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name="o"&amp;gt;&lt;span style="color:#008000"&gt;Event source.&lt;/span&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name="e"&amp;gt;&lt;span style="color:#008000"&gt;Event arguments.&lt;/span&gt;&amp;lt;/param&amp;gt;
&lt;span style="color:#0000ff"&gt;public delegate void&lt;/span&gt;&lt;span style="color:#2b91af"&gt; MyEventHandler&lt;/span&gt;&lt;span style="color:#000000"&gt;(&lt;/span&gt;&lt;span style="color:#0000ff"&gt;object&lt;/span&gt;&lt;span style="color:#000000"&gt; o, &lt;/span&gt;&lt;span style="color:#2b91af"&gt;IMyEventArgs&lt;/span&gt;&lt;span style="color:#000000"&gt; e);

&lt;/span&gt;/// &amp;lt;summary&amp;gt;
///&lt;span style="color:#008000"&gt; Interface for custom EventArgs.
&lt;/span&gt;/// &amp;lt;/summary&amp;gt;
&lt;span style="color:#0000ff"&gt;public interface&lt;/span&gt;&lt;span style="color:#2b91af"&gt; IMyEventArgs
&lt;/span&gt;&lt;span style="color:#000000"&gt;{
    &lt;/span&gt;/// &amp;lt;summary&amp;gt;
    ///&lt;span style="color:#008000"&gt; Simple property.
&lt;/span&gt;    /// &amp;lt;/summary&amp;gt;
&lt;span style="color:#0000ff"&gt;    string&lt;/span&gt;&lt;span style="color:#000000"&gt; Message { &lt;/span&gt;&lt;span style="color:#0000ff"&gt;get&lt;/span&gt;&lt;span style="color:#000000"&gt;; }
}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;With this approach, the contract assembly no longer needs to include the concrete &lt;code&gt;MyEventArgs&lt;/code&gt; implementation: the delegate above is strongly-typed and doesn't have the same constraint as &lt;code&gt;EventHandler&amp;lt;TEventArgs&amp;gt;&lt;/code&gt;, so it works great! With that in place, the implementation details of the &lt;code&gt;MyEventArgs&lt;/code&gt; class can be safely hidden inside the extension (or application) assembly like so: &lt;/p&gt;
&lt;pre style="color:#000000"&gt;&lt;span style="color:#808080"&gt;/// &amp;lt;summary&amp;gt;
///&lt;/span&gt;&lt;span style="color:#008000"&gt; Implementation of a custom extension for MyApplication.
&lt;/span&gt;&lt;span style="color:#808080"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;[&lt;span style="color:#2b91af"&gt;Export&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;IMyContract&lt;/span&gt;))]
&lt;span style="color:#0000ff"&gt;public class&lt;/span&gt;&lt;span style="color:#2b91af"&gt; MyExtension&lt;/span&gt; : &lt;span style="color:#2b91af"&gt;IMyContract
&lt;/span&gt;{
    &lt;span style="color:#808080"&gt;/// &amp;lt;summary&amp;gt;
    ///&lt;/span&gt;&lt;span style="color:#008000"&gt; Simple method outputs the extension's name and invokes its event.
&lt;/span&gt;&lt;span style="color:#808080"&gt;    /// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color:#0000ff"&gt;    public void&lt;/span&gt; MyMethod()
    {
        &lt;span style="color:#2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515"&gt;"MyExtension.MyMethod"&lt;/span&gt;);
        &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; handler = MyEvent;
        &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;null&lt;/span&gt; != handler)
        {
            handler(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;new&lt;/span&gt;&lt;span style="color:#2b91af"&gt; MyEventArgs&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"MyEventArgs"&lt;/span&gt;));
        }
    }

    &lt;span style="color:#808080"&gt;/// &amp;lt;summary&amp;gt;
    ///&lt;/span&gt;&lt;span style="color:#008000"&gt; Simple event.
&lt;/span&gt;&lt;span style="color:#808080"&gt;    /// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color:#0000ff"&gt;    public event&lt;/span&gt;&lt;span style="color:#2b91af"&gt; MyEventHandler&lt;/span&gt; MyEvent;
}

&lt;span style="color:#808080"&gt;/// &amp;lt;summary&amp;gt;
///&lt;/span&gt;&lt;span style="color:#008000"&gt; Implementation of a custom interface-based EventArgs.
&lt;/span&gt;&lt;span style="color:#808080"&gt;/// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color:#0000ff"&gt;class&lt;/span&gt;&lt;span style="color:#2b91af"&gt; MyEventArgs&lt;/span&gt; : &lt;span style="color:#2b91af"&gt;EventArgs&lt;/span&gt;, &lt;span style="color:#2b91af"&gt;IMyEventArgs
&lt;/span&gt;{
    &lt;span style="color:#808080"&gt;/// &amp;lt;summary&amp;gt;
    ///&lt;/span&gt;&lt;span style="color:#008000"&gt; Simple property.
&lt;/span&gt;&lt;span style="color:#808080"&gt;    /// &amp;lt;/summary&amp;gt;
&lt;/span&gt;&lt;span style="color:#0000ff"&gt;    public string&lt;/span&gt; Message { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff"&gt;private set&lt;/span&gt;; }

    &lt;span style="color:#808080"&gt;/// &amp;lt;summary&amp;gt;
    ///&lt;/span&gt;&lt;span style="color:#008000"&gt; Initializes a new instance of the MyEventArgs class.
&lt;/span&gt;&lt;span style="color:#808080"&gt;    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="message"&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Property value.&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;
&lt;/span&gt;&lt;span style="color:#0000ff"&gt;    public&lt;/span&gt; MyEventArgs(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; message)
    {
        Message = message;
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The sample application I've created to demonstrate this practice in action (a simple executable/contract assembly/extension assembly trio) is quite simple and works just as you'd expect. Here's the output: &lt;/p&gt;
&lt;pre&gt;MyApplication.Run
MyExtension.MyMethod
MyEventArgs&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cesso.org/Samples/MefContractTricks/MefContractTricks.zip"&gt;[Click here to download the complete source code for the MefContractTricks sample.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Keeping a MEF application's contract assemblies as pure and implementation-free as possible is a good and noble goal. There may be times when it is necessary to make compromises and allow implementation details to sneak into the contract assembly, but the use of custom event arguments does &lt;strong&gt;not&lt;/strong&gt; need to be one of them! &lt;/p&gt;
&lt;p&gt;So instead of being generic - and failing - go retro for the win! &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10142165" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/MEF/">MEF</category></item><item><title>MEF addict [Combining .NET 4's type embedding and MEF to enable a smooth upgrade story for applications and their extensions]</title><link>http://blogs.msdn.com/b/delay/archive/2011/03/09/mef-addict-combining-net-4-s-type-embedding-and-mef-to-enable-a-smooth-upgrade-story-for-applications-and-their-extensions.aspx</link><pubDate>Wed, 09 Mar 2011 18:18:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10138798</guid><dc:creator>David Anson</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/delay/rsscomments.aspx?WeblogPostID=10138798</wfw:commentRss><comments>http://blogs.msdn.com/b/delay/archive/2011/03/09/mef-addict-combining-net-4-s-type-embedding-and-mef-to-enable-a-smooth-upgrade-story-for-applications-and-their-extensions.aspx#comments</comments><description>&lt;div class="delay"&gt;
&lt;p&gt;One of the neat new features in version 4 of the .NET Framework is something called "type equivalence" or "type embedding". The basic idea is to embed &lt;strong&gt;at compile time&lt;/strong&gt; all the type information about a particular reference assembly into a dependent assembly. Once this is done, the resulting assembly no longer maintains a reference to the other assembly, so it does &lt;strong&gt;not&lt;/strong&gt; need to be present at run time. You can read more about type embedding in the MSDN article &lt;a href="http://msdn.microsoft.com/en-us/library/dd997297.aspx"&gt;Type Equivalence and Embedded Interop Types&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Although type equivalence was originally meant for use with &lt;a href="http://en.wikipedia.org/wiki/Component_Object_Model"&gt;COM&lt;/a&gt; to make it easier to work against multiple versions of a native assembly, it can be used successfully without involving COM at all! The MSDN article &lt;a href="http://msdn.microsoft.com/en-us/library/dd409610.aspx"&gt;Walkthrough: Embedding Types from Managed Assemblies (C# and Visual Basic)&lt;/a&gt; explains more about the requirements for this along with explicit steps to use type embedding with an assembly. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here's a simple interface that is enabled for type embedding: &lt;/p&gt;
&lt;pre style="color:#000000"&gt;&lt;span style="color:#0000ff"&gt;using&lt;/span&gt; System.Runtime.InteropServices;

&lt;span style="background-color:yellow"&gt;[&lt;span style="color:#0000ff"&gt;assembly&lt;/span&gt;:&lt;span style="color:#2b91af"&gt;ImportedFromTypeLib&lt;/span&gt;(&lt;span style="color:#a31515"&gt;""&lt;/span&gt;)]&lt;/span&gt;

&lt;span style="color:#0000ff"&gt;namespace&lt;/span&gt; MyNamespace
{
    &lt;span style="background-color:yellow"&gt;[&lt;span style="color:#2b91af"&gt;ComImport&lt;/span&gt;, &lt;span style="color:#2b91af"&gt;Guid&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"1F9BD720-DFB3-4698-A3DC-05E40EDC69F1"&lt;/span&gt;)]&lt;/span&gt;
    &lt;span style="color:#0000ff"&gt;public interface&lt;/span&gt;&lt;span style="color:#2b91af"&gt; MyInterface&lt;/span&gt;
    {
        &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Name { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; }
        &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; GetVersion();
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Another thing that's new with .NET 4 (though it had previously been &lt;a href="http://www.codeplex.com/mef"&gt;available on CodePlex&lt;/a&gt;) is the &lt;a href="http://msdn.microsoft.com/en-us/library/dd460648.aspx"&gt;Managed Extensibility Framework (MEF)&lt;/a&gt;. MEF makes it easy to implement a "plug-in" architecture for applications where assemblies are loosely coupled and can be added or removed without explicit configuration. While there have been a variety of not-so-successful attempts to create a viable extensibility framework before this, there's general agreement that MEF is a &lt;strong&gt;good&lt;/strong&gt; solution and it's already being used by prominent applications like Visual Studio. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here's a simple MEF-enabled extension that implements - and &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.exportattribute.aspx"&gt;exports&lt;/a&gt; - the interface above: &lt;/p&gt;
&lt;pre style="color:#000000"&gt;[&lt;span style="color:#2b91af"&gt;Export&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;MyInterface&lt;/span&gt;))]
&lt;span style="color:#0000ff"&gt;public class&lt;/span&gt;&lt;span style="color:#2b91af"&gt; MyExtension&lt;/span&gt; : &lt;span style="color:#2b91af"&gt;MyInterface
&lt;/span&gt;{
    &lt;span style="color:#0000ff"&gt;public string&lt;/span&gt; Name
    {
        &lt;span style="color:#0000ff"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt;&lt;span style="color:#a31515"&gt; "MyExtension"&lt;/span&gt;; }
    }

    ...
}&lt;/pre&gt;
&lt;p&gt;And here's a simple MEF-enabled application that uses that extension by &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.importmanyattribute.aspx"&gt;importing&lt;/a&gt; its interface: &lt;/p&gt;
&lt;pre style="color:#000000"&gt;&lt;span style="color:#0000ff"&gt;class&lt;/span&gt;&lt;span style="color:#2b91af"&gt; MyApplication
&lt;/span&gt;{
    [&lt;span style="color:#2b91af"&gt;ImportMany&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;MyInterface&lt;/span&gt;))]
    &lt;span style="color:#0000ff"&gt;private&lt;/span&gt;&lt;span style="color:#2b91af"&gt; IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af"&gt;MyInterface&lt;/span&gt;&amp;gt; Extensions { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff"&gt;set&lt;/span&gt;; }

    &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; MyApplication()
    {
        &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; catalog = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt;&lt;span style="color:#2b91af"&gt; DirectoryCatalog&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;Path&lt;/span&gt;.GetDirectoryName(&lt;span style="color:#2b91af"&gt;Assembly&lt;/span&gt;.GetEntryAssembly().Location));
        &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; container = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt;&lt;span style="color:#2b91af"&gt; CompositionContainer&lt;/span&gt;(catalog);
        container.SatisfyImportsOnce(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt;);
    }

    &lt;span style="color:#0000ff"&gt;private void&lt;/span&gt; Run()
    {
        &lt;span style="color:#2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515"&gt;"Application: Version={0}"&lt;/span&gt;, &lt;span style="color:#2b91af"&gt;Assembly&lt;/span&gt;.GetEntryAssembly().GetName().Version.ToString());
        &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;var&lt;/span&gt; extension &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; Extensions)
        {
            &lt;span style="color:#2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515"&gt;"Extension: Name={0} Version={1}"&lt;/span&gt;, extension.Name, extension.GetVersion());
        }
    }

    ...
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The resulting behavior is just what you'd expect: &lt;/p&gt;
&lt;pre&gt;P:\MefAndTypeEmbedding&amp;gt;Demo

Building...
Staging V1...
Running V1 scenario...

Application: Version=1.0.0.0
Extension: Name=MyExtension Version=1.0.0.0

...&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;However, it's important to note that MEF does &lt;strong&gt;not&lt;/strong&gt; isolate an application from versioning issues! Ideally, extensions written for version 1 of an application will automatically load and run under version 2 of that application &lt;em&gt;without needing to be recompiled&lt;/em&gt; - but you don't get that for free. There is an easy way to do this, though: avoid making &lt;strong&gt;any&lt;/strong&gt; changes to the contract assembly after v1 is released. &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: The contract assembly is the place where the public interfaces of an application live. Because interfaces are generally the &lt;strong&gt;only&lt;/strong&gt; thing in a contract assembly, both the application and its extensions can reference it &lt;strong&gt;and&lt;/strong&gt; it can be published as part of an &lt;a href="http://en.wikipedia.org/wiki/Sdk"&gt;SDK&lt;/a&gt; without needing to include implementation details, too. &lt;/blockquote&gt;
&lt;p&gt;But because the whole point of version 2 is to improve upon version 1, it's quite likely the contract assembly will undergo some changes along the way. This is where problems come up: assuming the contract assembly was &lt;a href="http://msdn.microsoft.com/en-us/library/wd40t7ad.aspx"&gt;strongly-named&lt;/a&gt; and its assembly version updated (as it &lt;em&gt;should&lt;/em&gt; be if its contents have changed!), v1 extensions will &lt;strong&gt;not&lt;/strong&gt; load for the v2 application because they won't be able to find the same version of the contract assembly they were compiled against... &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: If the contract assembly was &lt;strong&gt;not&lt;/strong&gt; strongly-named, then v1 extensions &lt;em&gt;might&lt;/em&gt; be able to load the v2 version - but it won't be what they're expecting and that can lead to problems. &lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here's an updated version of the original interface with a new &lt;code&gt;Author&lt;/code&gt; property for version 2: &lt;/p&gt;
&lt;pre style="color:#000000"&gt;&lt;span style="color:#0000ff"&gt;using&lt;/span&gt; System.Runtime.InteropServices;

[&lt;span style="color:#0000ff"&gt;assembly&lt;/span&gt;:&lt;span style="color:#2b91af"&gt;ImportedFromTypeLib&lt;/span&gt;(&lt;span style="color:#a31515"&gt;""&lt;/span&gt;)]

&lt;span style="color:#0000ff"&gt;namespace&lt;/span&gt; MyNamespace
{
    [&lt;span style="color:#2b91af"&gt;ComImport&lt;/span&gt;, &lt;span style="color:#2b91af"&gt;Guid&lt;/span&gt;(&lt;span style="color:#a31515"&gt;"1F9BD720-DFB3-4698-A3DC-05E40EDC69F1"&lt;/span&gt;)]
    &lt;span style="color:#0000ff"&gt;public interface&lt;/span&gt;&lt;span style="color:#2b91af"&gt; MyInterface&lt;/span&gt;
    {
        &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Name { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; }
        &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; GetVersion();
        &lt;span style="background-color:yellow"&gt;&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; Author { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; }&lt;/span&gt;
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;One way to solve the versioning problem is to ship the v1 contract assembly &lt;strong&gt;and&lt;/strong&gt; the v2 contract assembly along with the v2 application. (Of course, this can be tricky if both assemblies have the same file name, so you'll probably also want to name them uniquely.) Shipping multiple versions of a contract assembly works well enough (it's pretty typical for COM components), but it can also cause some confusion for Visual Studio when it sees multiple same-named interfaces referenced by the v2 application - not to mention the developer burden of managing multiple distinct versions of the "same" interface... &lt;/p&gt;
&lt;p&gt;Fortunately, there's another way that doesn't require the v2 application to include the v1 contract assembly at all: &lt;strong&gt;type embedding&lt;/strong&gt;. If the contract assembly is enabled for type embedding and v1 extension authors enable that when compiling, all the relevant bits of the contract assembly will be included with the v1 extension and there will be &lt;strong&gt;no&lt;/strong&gt; need for the v1 contract assembly to be present. What that means is "reasonable" interface changes during development of the v2 application will &lt;strong&gt;automatically&lt;/strong&gt; be handled by .NET and v1 extensions will work properly without any need to recompile/upgrade/etc.! &lt;/p&gt;
&lt;blockquote&gt;&lt;strong&gt;Aside&lt;/strong&gt;: By "reasonable" interface changes, I mean &lt;em&gt;removing&lt;/em&gt; properties or methods (and therefore not calling the v1 implementations) or &lt;em&gt;adding&lt;/em&gt; them (which will throw &lt;a href="http://msdn.microsoft.com/en-us/library/system.missingmethodexception.aspx"&gt;MissingMethodException&lt;/a&gt; for v1 extensions that don't support the new property/method). Changes to &lt;strong&gt;existing&lt;/strong&gt; properties and methods are trickier and probably best avoided as a general rule. &lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The v2 version of the sample application uses the &lt;code&gt;Author&lt;/code&gt; property when it's present (for v2 extensions), but gracefully handles the case where it's not (as for v1 extensions): &lt;/p&gt;
&lt;pre style="color:#000000"&gt;&lt;span style="color:#0000ff"&gt;private void&lt;/span&gt; Run()
{
    &lt;span style="color:#2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515"&gt;"Application: Version={0}"&lt;/span&gt;, &lt;span style="color:#2b91af"&gt;Assembly&lt;/span&gt;.GetEntryAssembly().GetName().Version.ToString());
    &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;var&lt;/span&gt; extension &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; Extensions)
    {
        &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; author;
        &lt;span style="color:#0000ff"&gt;try
&lt;/span&gt;        {
            author = extension.Author;
        }
        &lt;span style="color:#0000ff"&gt;catch&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;MissingMethodException&lt;/span&gt;)
        {
            author = &lt;span style="color:#a31515"&gt;"[Undefined]"&lt;/span&gt;;
        }
        &lt;span style="color:#2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515"&gt;"Extension: Name={0} Version={1} Author={2}"&lt;/span&gt;, extension.Name, extension.GetVersion(), author);
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here's the v2 version in action: &lt;/p&gt;
&lt;pre&gt;...

Staging V2...
Running V2 scenario...

Application: Version=2.0.0.0
Extension: Name=MyExtension Version=1.0.0.0 Author=[Undefined]
Extension: Name=MyExtension Version=2.0.0.0 Author=Me&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cesso.org/Samples/MefAndTypeEmbedding/MefAndTypeEmbedding.zip"&gt;[Click here to download the complete source code for the sample application/contract assembly/extensions and demo script used here.]&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Type embedding and MEF are both fairly simple concepts that add a layer of flexibility to enable some pretty powerful scenarios. As is sometimes the case, &lt;a href="http://en.wikipedia.org/wiki/Gestalt_psychology"&gt;the whole is greater than the sum of its parts&lt;/a&gt; and &lt;strong&gt;combining&lt;/strong&gt; these two technologies provides an elegant solution to the tricky problem of upgrading an application without breaking existing plug-ins. &lt;/p&gt;
&lt;p&gt;If you aren't already familiar with MEF or type embedding, maybe now is a good time to learn! &lt;nobr&gt;:)&lt;/nobr&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;PS - My thanks go out to &lt;strong&gt;Kevin Ransom&lt;/strong&gt; on the CLR team for providing feedback on a draft of this post. (Of course, any errors are entirely my own!) &lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10138798" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/delay/archive/tags/Technical/">Technical</category><category domain="http://blogs.msdn.com/b/delay/archive/tags/MEF/">MEF</category></item></channel></rss>