<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Aaron Lerch</title>
	
	<link>http://www.aaronlerch.com/blog</link>
	<description />
	<lastBuildDate>Sun, 04 Apr 2010 03:04:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/aaronlerch" /><feedburner:info uri="aaronlerch" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>39.866913</geo:lat><geo:long>-86.123236</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by/2.5/</creativeCommons:license><item>
		<title>Analyzing Code with NDepend</title>
		<link>http://feedproxy.google.com/~r/aaronlerch/~3/9bystspDqaE/</link>
		<comments>http://www.aaronlerch.com/blog/2010/04/03/analyzing-code-with-ndepend/#comments</comments>
		<pubDate>Sat, 03 Apr 2010 19:38:09 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[visualization]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2010/04/03/analyzing-code-with-ndepend/</guid>
		<description><![CDATA[Disclaimer: A long time ago, in a galaxy far away, I helped coordinate the Indy Code Camp. We gave away a few donated copies of NDepend as prizes, and while setting that up, Patrick Smacchia offered me a license if I’d be willing to write about my NDepend experiences on my blog. Having heard about [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p><strong>Disclaimer:</strong> A long time ago, in a galaxy far away, I helped coordinate the <a title="Indy Code Camp" href="http://www.aaronlerch.com/blog/2008/03/05/indy-code-camp-door-prizes/">Indy Code Camp</a>. We gave away a few donated copies of <a title="NDepend" href="http://www.ndepend.com/">NDepend</a> as prizes, and while setting that up, <a href="http://codebetter.com/blogs/patricksmacchia/">Patrick Smacchia</a> offered me a license if I’d be willing to write about my NDepend experiences on my blog. Having <a href="http://www.hanselman.com/blog/ExitingTheZoneOfPainStaticAnalysisWithNDepend.aspx">heard about NDepend</a> in the past, I happily took him up on it – making sure it was clear that I would write about my experience regardless of whether they were positive or negative. So this is a “sponsored” post, in that I received an NDepend license, but the license donation did not purchase any of the content of this post.</p>
</blockquote>
<p>An astute reader will probably look at the date that I helped with the Indy Code Camp and compare it to the date of this post, and figure out that it was about <em>two years ago</em> that Patrick asked me to evaluate NDepend. And I’m not so happy to say that in those two years, I really didn’t use it. But recently <a href="http://www.aaronlerch.com/blog/2010/04/03/staying-sane-as-a-technical-manager-part-2/">I have more time available to me</a> for doing specifically this sort of thing.</p>
<p>I think Scott Hanselman <a href="http://www.hanselman.com/blog/ExitingTheZoneOfPainStaticAnalysisWithNDepend.aspx">summed up the initial NDepend experience quite well</a>.</p>
<blockquote><p>Like PowerShell, the first 10 minutes of NDepend is the hardest. It has to click first. There&#8217;s the whole &quot;what the hell am I looking at&quot; process, often followed by the &quot;screw this&quot; declaration, followed by a quick uninstallation and a sense of &quot;what happened.&quot;</p>
</blockquote>
<p>I’m not going to do a comprehensive overview like Scott or others have done – at this point I just <em>can’t</em> do that as I’m still in kind of the “what the hell is this” phase. But it’s slowly beginning to click. For me, two things that click and help me continue on and work to understand this application.</p>
<p><strong>One</strong>, I know I need the information NDepend can give me. I may not understand it all immediately, but I’ve been deep in the code of some applications long enough to see <em>(and write)</em> the good, the bad, and the ugly. I need ways to root out the bad and ugly, without having to dive into all the code in-depth. I also need metrics to help show that the good really is good. Especially when you’re working on a team of several people, each with varying opinions and each who writes their own flavor of code. Just because I don’t like someone else’s code doesn’t mean it’s <em>bad code</em>. Metrics can help me separate my aesthetic or organizational concerns from real problems or smells. And then I can make them write it my way anyway. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><strong>Two</strong>, and more fun than the first is NDepend’s Code Query Language or CQL. In my opinion, this is an easy “hook” to get someone to look closer at NDepend and get past that 10-minute hump. I have seen a developer’s face literally light up when they hear what CQL can do, especially if they’ve done any work with a database and SQL in the past.</p>
<p>NDepend’s website has the best <a href="http://ndepend.com/CQL.htm">documentation of CQL</a>, even if the docs feel overwhelming at first. There’s also some information about <a href="http://ndepend.com/ConstraintsExtractedFromCode.aspx">embedding CQL into your code</a> as in-line constraints that NDepend can enforce during your build, though as <a href="http://plaureano.blogspot.com/2009/07/ndepend-review.html">others have mentioned</a> it’s not a practical solution.</p>
<p>Of immediate interest to me, due to something I’m doing at <a href="http://www.inin.com/">work</a>, is catching breaking API changes that might accidentally happen during a maintenance release. Patrick covers how to do this <a href="http://codebetter.com/blogs/patricksmacchia/archive/2008/01/20/avoid-api-breaking-changes.aspx">here</a>. But as an example, let’s analyze the breaking API changes in <a href="http://github.com/structuremap/structuremap">StructureMap</a> between version 2.5.4 and 2.6.1.</p>
<blockquote><p><em>Note:</em> I got confused at first, because I put both versions of StructureMap into the same directory and renamed the files to include the version number. NDepend didn’t like this and flagged every single method as removed and added. I’m not sure what I did wrong, but it took a bit to figure out, and it sucks for situations where a version number (or a name change) might cause an assembly name not to match, even though it’s functionally the same.</p>
</blockquote>
<p>The first thing to do is select the two assemblies to compare – here I’m choosing StructureMap 2.5.4 on the left, and 2.6.1 on the right.</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/ndepend/build-comparison.png" width="608" height="346" /></p>
<p>After the NDepend project has been created, I can press ALT+Q to bring up the CQL editor, and enter the following query:</p>
<blockquote><p>WARN IF Count &gt; 0 IN SELECT METHODS WHERE      <br />IsInOlderBuild AND IsPublic AND (VisibilityWasChanged OR WasRemoved)</p>
</blockquote>
<p>It reads pretty well, especially if you’re familiar with SQL. Literally it’s “warn me if methods exist that were in the older build, were public, and the visibility has changed or the method was removed.”</p>
<p>You can see below, 5 methods were “removed” from StructureMap’s public API – in this case, they are literally removed (and not just made internal or private). That means that upgrading from 2.5.4 to 2.6.1 could mean you have to change or recompile your code.</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/ndepend/method-query-results.png" /></p>
<p>Likewise you can see that no public types were removed, thus no breaking change exists and the CQL query isn’t flagged as a warning.</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/ndepend/type-query-results.png" /></p>
<p>This is some powerful stuff, and as I begin to incorporate it more and more into my daily workflow I’ll post about how I’m using it.</p>
</p>
<p>The newest version supports a console runner, a stand-alone GUI, and full integration into Visual Studio 2005, 2008, and 2010. For small projects that can exist within a single Visual Studio solution, it’s perfect. For larger projects that span multiple solutions, NDepend still allows you to analyze a set of assemblies, the UI is just embedded inside Visual Studio – and the integration is pretty usable for me so far.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronlerch?a=9bystspDqaE:hlRX2Pj3bH4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=9bystspDqaE:hlRX2Pj3bH4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=9bystspDqaE:hlRX2Pj3bH4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronlerch?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=9bystspDqaE:hlRX2Pj3bH4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=9bystspDqaE:hlRX2Pj3bH4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=9bystspDqaE:hlRX2Pj3bH4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=9bystspDqaE:hlRX2Pj3bH4:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronlerch/~4/9bystspDqaE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2010/04/03/analyzing-code-with-ndepend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.aaronlerch.com/blog/2010/04/03/analyzing-code-with-ndepend/</feedburner:origLink></item>
		<item>
		<title>Staying Sane as a Technical Manager, Part 2</title>
		<link>http://feedproxy.google.com/~r/aaronlerch/~3/vtAkA8HPhRA/</link>
		<comments>http://www.aaronlerch.com/blog/2010/04/03/staying-sane-as-a-technical-manager-part-2/#comments</comments>
		<pubDate>Sat, 03 Apr 2010 18:18:51 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[misc]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2010/04/03/staying-sane-as-a-technical-manager-part-2/</guid>
		<description><![CDATA[A year and a half ago I wrote about the three little words that are critical for a Technical Manager to understand. Know your limits. As I look back over the past year and a half, plus the years leading up to it, I am more and more convinced that this is an extremely important [...]]]></description>
			<content:encoded><![CDATA[<p>A year and a half ago I <a href="http://www.aaronlerch.com/blog/2008/09/02/staying-sane-as-a-technical-manager/">wrote about</a> the three little words that are critical for a Technical Manager to understand.</p>
<blockquote><p>Know your limits.</p>
</blockquote>
<p>As I look back over the past year and a half, plus the years leading up to it, I am more and more convinced that this is an extremely important concept to put into practice.</p>
<p><img style="display: inline; margin-left: 0px; margin-right: 0px" align="right" src="http://s3.amazonaws.com:80/aaronlerch.com/images/juggle-balls.png" />Over the past year+, my team has almost doubled in size (plus an intern or two in the summers). We are all working on different features, but on the same (or similar) products, so we weren’t as “scattered” as we were before I split us up. However, juggling as many balls as we have, being an <a href="http://www.aaronlerch.com/blog/2008/04/20/from-developer-to-technical-manager/">effective technical manager</a> was becoming more and more difficult for me. Most specifically my organizational skills and managing priorities were lacking. I’ve been working hard to manage the team, manage priorities, <em>and</em> keep my technical chops because like at many software companies that started as a small start-up, the technical manager is implicitly expected to manage <em>and</em> be the technical expert.</p>
<p>Eventually I realized that this lifestyle is ultimately unsustainable, and I couldn’t see a light at the end of the tunnel. That’s bad for me, bad for my family, and bad for the company. I needed to recognize that I was moving well outside my limits. I had to make a decision: stop being a technical expert, and just be a true <a href="http://www.aaronlerch.com/blog/2008/04/20/from-developer-to-technical-manager/">technical manager</a>, or, stop being a manager and remain as a technical expert.</p>
<p>The decision wasn’t hard&#8230; I enjoy code way too much.</p>
<p>Ahhh, this feels so much better! Now I can focus on things that have long interested me but I just plain haven’t had time for. Like, for example, digging deep into <a href="http://www.ndepend.com/">NDepend</a> to help keep that 10,000 foot view of our products that I couldn’t do before.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronlerch?a=vtAkA8HPhRA:X-498h_bZNo:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=vtAkA8HPhRA:X-498h_bZNo:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=vtAkA8HPhRA:X-498h_bZNo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronlerch?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=vtAkA8HPhRA:X-498h_bZNo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=vtAkA8HPhRA:X-498h_bZNo:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=vtAkA8HPhRA:X-498h_bZNo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=vtAkA8HPhRA:X-498h_bZNo:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronlerch/~4/vtAkA8HPhRA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2010/04/03/staying-sane-as-a-technical-manager-part-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.aaronlerch.com/blog/2010/04/03/staying-sane-as-a-technical-manager-part-2/</feedburner:origLink></item>
		<item>
		<title>10 Things You Need to Know About PowerShell at Codemash</title>
		<link>http://feedproxy.google.com/~r/aaronlerch/~3/1wg70cBCSBw/</link>
		<comments>http://www.aaronlerch.com/blog/2010/01/15/10-things-you-need-to-know-about-powershell-at-codemash/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 16:41:30 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2010/01/15/10-things-you-need-to-know-about-powershell-at-codemash/</guid>
		<description><![CDATA[Thanks to everybody who came to the PowerShell talk that Matt Hester and I did at Codemash! If you haven’t heard of Codemash or attended it, it’s an extremely well-done conference in Sandusky, Ohio at a huge indoor waterpark. I brought my whole family (including in-laws) along with to enjoy a vacation. The conference itself [...]]]></description>
			<content:encoded><![CDATA[<p><img style="display: inline; margin-left: 0px; margin-right: 0px" align="left" src="http://s3.amazonaws.com:80/aaronlerch.com/images/speaking-at-codemash.png" /></p>
<p>Thanks to everybody who came to the PowerShell talk that <a href="http://blogs.technet.com/matthewms/">Matt Hester</a> and I did at <a href="http://codemash.org/">Codemash</a>! If you haven’t heard of Codemash or attended it, it’s an extremely well-done conference in Sandusky, Ohio at a huge indoor waterpark. I brought my whole family (including in-laws) along with to enjoy a vacation. The conference itself draws in all sorts of smart people with all sorts of backgrounds, and there have been many interesting sessions, open space sessions, and conversations already. It’s worth way more than the price of admission. (WAY more.)</p>
<p>We tried to tailor our talk to people who have only heard of PowerShell, and people who have limited experience with it. And that worked great because I think that described the majority of people there. We got a lot of great questions, and of course we went well over our 1-hour timeslot. There’s so much to talk about! I wish we could’ve gotten into more advanced topics like the type system, etc.</p>
<p>For my part of the talk, I presented a few demos. You can download them and the slides below. Briefly, the demos were the following:</p>
<p><strong>Using PowerShell from within applications.</strong> I extended the <a href="http://familyshow.codeplex.com/">Family.Show</a> example application that Vertigo Software wrote by adding “scripting support” using PowerShell. You can see a screenshot I <a href="http://twitpic.com/xkmwf">posted here</a>. I also wrote a simple WPF application that gets a list of processes running on the computer, only including those who have a handle count less than 200.</p>
<p><strong>Simple Cmdlet.</strong> I wrote a simple Cmdlet as an example. It’s completely non-functional but I included it here for completeness. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Build Scripts with PSake.</strong> I have a simple build script with <a href="http://code.google.com/p/psake/">PSake</a> that doesn’t actually build anything, but shows how to define dependencies, prerequisites, etc.</p>
<p><strong>Windows Troubleshooting Platform + Reference Application.</strong> Not included in the download (because you can get the source as-is from codeplex), I briefly covered the <a href="http://pssymbolstore.codeplex.com/">PSSymbolStore application</a>. It demos using the Windows Troubleshooting Platform, defining more advanced Cmdlets, and building an application on top of PowerShell at the core. You can browse (and/or download) the code <a href="http://pssymbolstore.codeplex.com/sourcecontrol/changeset/view/33254?projectName=PSSymbolStore">here</a>.    <br /><em>As a note</em>, because of the signing requirements of the Windows Troubleshooting Framework, I will leave the code in the application but will remove any UI that invokes the Troubleshooter. It won’t work on any machine but mine unless I have a trusted certificate, which I don’t. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a title="Code and Slides from our PowerShell talk" href="http://s3.amazonaws.com:80/aaronlerch.com/files/CodeMash-2010-Powershell.zip">Download the code and slides from our presentation.</a></p>
<p>See you next year (hopefully)!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronlerch?a=1wg70cBCSBw:oP62x_h1tic:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=1wg70cBCSBw:oP62x_h1tic:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=1wg70cBCSBw:oP62x_h1tic:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronlerch?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=1wg70cBCSBw:oP62x_h1tic:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=1wg70cBCSBw:oP62x_h1tic:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=1wg70cBCSBw:oP62x_h1tic:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=1wg70cBCSBw:oP62x_h1tic:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronlerch/~4/1wg70cBCSBw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2010/01/15/10-things-you-need-to-know-about-powershell-at-codemash/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.aaronlerch.com/blog/2010/01/15/10-things-you-need-to-know-about-powershell-at-codemash/</feedburner:origLink></item>
		<item>
		<title>Two Components for your Toolbox</title>
		<link>http://feedproxy.google.com/~r/aaronlerch/~3/6CN3pRZFoPg/</link>
		<comments>http://www.aaronlerch.com/blog/2009/09/25/two-components-for-your-toolbox/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 06:36:11 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2009/09/25/two-components-for-your-toolbox/</guid>
		<description><![CDATA[Any desktop application I write from now on will contain these two interfaces. They’re useful enough I thought I should share. Also note, with upcoming improvements in .NET 4.0 (or higher) they might be rendered moot. So far, I don’t think they are, as it’s still difficult to test the code itself that performs asynchronous [...]]]></description>
			<content:encoded><![CDATA[<p>Any desktop application I write from now on will contain these two interfaces. They’re useful enough I thought I should share. Also note, with upcoming improvements in .NET 4.0 (or higher) they might be rendered moot. So far, I don’t think they are, as it’s still difficult to test the code itself that performs asynchronous operations.</p>
<p>First, is an abstraction around the User Interface thread, IUserInterfaceContext. This exists today in the form of <a href="http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.aspx">SynchronizationContext</a>, but I favor this specific interface because</p>
<ol>
<li>It’s more explicit (the SynchronizationContext applies to more than just the main UI thread) whereas this is very clear what its purpose is.</li>
<li>The API is cleaner – passing a “state” is unnecessary with nested closures.</li>
<li>It’s easier to grab out of an IoC container. Because a SynchronizationContext is only specific to the context it was created in (which could be a background thread) it’s not meaningful to put a SynchronizationContext argument in your constructor. Which one do you want?</li>
</ol>
<pre class="brush: csharp;">public interface IUserInterfaceContext
{
    void Execute(Action action);
    void ExecuteAndBlock(Action action);
}</pre>
<p>Now, any component in my application can execute code on the UI thread extremely easily. I just register the implementation of IUserInterfaceContext (which does use a SynchronizationContext) when my application is started, which is on the UI thread.</p>
<p>The implementation could look something like this:</p>
<pre class="brush: csharp;">public class UserInterfaceContext : IUserInterfaceContext
{
    private readonly SynchronizationContext _syncContext;

    public UserInterfaceContext(SynchronizationContext syncContext)
    {</pre>
<pre class="brush: csharp;">        /* Ensure the SynchronizationContext passed in is the main UI thread context */
        _syncContext = syncContext;
    }

    public void ExecuteAndBlock(Action action)
    {
        if (_syncContext != null)
        {
            _syncContext.Send(s =&gt; action(), null);
        }
        else
        {
            action();
        }
    }

    /// &lt;inheritdoc /&gt;
    public void Execute(Action action)
    {
        if (_syncContext != null)
        {
            _syncContext.Post(s =&gt; action(), null);
        }
        else
        {
            ThreadPool.QueueUserWorkItem(s =&gt; action(), null);
        }
    }
}</pre>
<p>Secondly, is a more generalized example of Jeremy Miller’s <a href="http://codebetter.com/blogs/jeremy.miller/archive/2008/02/15/build-your-own-cab-18-the-command-executor.aspx">ICommandExecutor</a>, which is even more generalized as the <a href="http://blog.gurock.com/postings/active-objects-and-futures-a-concurrency-abstraction-implemented-for-c-and-net/290/">Active Object pattern</a>. I named mine “IAsyncExecutor” because it executes any code asynchronously. The advantage with this approach is that it drastically simplifies test activities to be able abstract multithreading (to a point) and allow a test to run single threaded. That is nothing but pure win. We’ve also found that using the interface makes the code read better than using a bunch of BeginInvoke/EndInvoke’s or the ThreadPool, or an async pattern such as &#8220;void FooAsync(AsyncCallback callback, object state);</p>
<pre class="brush: csharp;">public interface IAsyncExecutor
{
    void Execute(Action action);
    void Execute(Action action, Action after, bool callbacksOnUIThread);
    void Execute(Action action, Action after, Action&lt;Exception&gt; error, bool callbacksOnUIThread);
}</pre>
<p>You’ll notice that IAsyncExecutor looks a lot like IUserInterfaceContext, and in fact, it can use it under the covers if the callbacksOnUIThread is true.</p>
<p>Both of these are simple interfaces, with trivial implementations, but you’d be surprised how often I’ve wished I’ve had them in the past. What are some “core” interfaces/services/etc that you <strong>*must have*</strong> in your toolbox?</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronlerch?a=6CN3pRZFoPg:PXW4s84Kla0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=6CN3pRZFoPg:PXW4s84Kla0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=6CN3pRZFoPg:PXW4s84Kla0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronlerch?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=6CN3pRZFoPg:PXW4s84Kla0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=6CN3pRZFoPg:PXW4s84Kla0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=6CN3pRZFoPg:PXW4s84Kla0:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=6CN3pRZFoPg:PXW4s84Kla0:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronlerch/~4/6CN3pRZFoPg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2009/09/25/two-components-for-your-toolbox/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.aaronlerch.com/blog/2009/09/25/two-components-for-your-toolbox/</feedburner:origLink></item>
		<item>
		<title>The Importance of Context</title>
		<link>http://feedproxy.google.com/~r/aaronlerch/~3/82BrLMDASC8/</link>
		<comments>http://www.aaronlerch.com/blog/2009/08/22/the-importance-of-context/#comments</comments>
		<pubDate>Sun, 23 Aug 2009 01:58:08 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[misc]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2009/08/22/the-importance-of-context/</guid>
		<description><![CDATA[The importance of context was brought jarringly to my attention the other day. This week was my intern’s last week, and as such he needed to fill out a “self evaluation” for HR. The first part of the eval was a simple 5-column table: various categories for evaluation, 3 boxes for “Did Not Meet”, “Met”, [...]]]></description>
			<content:encoded><![CDATA[<p>The importance of context was brought jarringly to my attention the other day. This week was my intern’s last week, and as such he needed to fill out a “self evaluation” for HR. The first part of the eval was a simple 5-column table: various categories for evaluation, 3 boxes for “Did Not Meet”, “Met”, or “Exceeded” expectations, and finally a box for comments. I personally think that’s a pretty hideous way to do a self evaluation, but I’ll ignore that for now. (I’d give myself a “Did Not Meet” for this post!)</p>
<p>My intern, being a pretty humble guy, put an “X” in each “Met” column and left no comments for himself, unsure of what to put. It looked something like this:</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/self-eval-original.png" alt="" /></p>
<p>So I decided to “help him out” and provide some feedback since I think he did a very good job this summer. I made my edits and sent it back to him with a note saying we’d review it together the next day.</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/self-eval-edited.png" alt="" /></p>
<p>At our daily standup the next morning he looked pretty depressed and dejected, which I noted, but didn’t think too much about. He sheepishly slipped into my office later that morning for our meeting, and only after we started talking did we realize that something was amiss. You see, I’m a native English-speaker who has spent my entire life in North America. As such, I have learned to read and process information from left to right. When I think about data, I put the lower value on the left and the higher on the right: lower &lt; higher.</p>
<p>Unfortunately, while filling out the review I had skimmed the table and just started editing. So what my intern received from me looked like this:</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/self-eval-full.png" alt="" /></p>
<p>After my intern started breathing again, we had a good laugh about it. Well, I apologized and laughed and he laughed with relief in the “just got a last-minute pardon” kind of way. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
There are two lessons here:</p>
<ol>
<li>Don’t make assumptions. (I should’ve read the document more thoroughly.)</li>
<li>Understand your user’s context. Present information in a way that flows with how they naturally think.</li>
</ol>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronlerch?a=82BrLMDASC8:34qnV56IWQk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=82BrLMDASC8:34qnV56IWQk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=82BrLMDASC8:34qnV56IWQk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronlerch?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=82BrLMDASC8:34qnV56IWQk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=82BrLMDASC8:34qnV56IWQk:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=82BrLMDASC8:34qnV56IWQk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=82BrLMDASC8:34qnV56IWQk:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronlerch/~4/82BrLMDASC8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2009/08/22/the-importance-of-context/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.aaronlerch.com/blog/2009/08/22/the-importance-of-context/</feedburner:origLink></item>
		<item>
		<title>Say Hello to My Little Internet</title>
		<link>http://feedproxy.google.com/~r/aaronlerch/~3/geXEMJwmI5U/</link>
		<comments>http://www.aaronlerch.com/blog/2009/08/20/say-hello-to-my-little-internet/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 07:20:42 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[services]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2009/08/20/say-hello-to-my-little-internet/</guid>
		<description><![CDATA[Recently I’ve been thinking about options for exposing an application automation API for inter process integration scenarios. For example, a desktop application that exposes the ability for other applications to programmatically query information from it and/or invoke commands. I also had a few requirements. Whatever I choose should: Let me inject core application services (or [...]]]></description>
			<content:encoded><![CDATA[<p><img style="display: inline; margin-left: 0px; margin-right: 0px" align="right" src="http://s3.amazonaws.com:80/aaronlerch.com/Scarface.png" />Recently I’ve been thinking about options for exposing an application automation API for inter process integration scenarios. For example, a desktop application that exposes the ability for other applications to programmatically query information from it and/or invoke commands. I also had a few requirements. Whatever I choose should:</p>
<ul>
<li>Let me inject core application services (or higher level aggregated services, or ANYTHING I WANT) by pulling them out of my IoC container </li>
<li>Not require the service to run in a new AppDomain </li>
<li>Be easy to use, configure, and integrate into my application </li>
<li>Be testable </li>
</ul>
<p>I’m going down the path of exposing a Web API (I would call it a RESTful service, but really it’s not). Of course my first stop was to investigate hosting ASP.NET MVC in a desktop application (which really just means hosing ASP.NET). There are a few <a href="http://www.west-wind.com/presentations/aspnetruntime/aspnetruntime.asp">articles</a> <a href="http://www.codeproject.com/KB/dotnet/usingaspruntime.aspx">out</a> there about how to do this, and for the “intended” scenario, it’s pretty easy.</p>
<p>Unfortunately the “intended” scenario is web hosting, which loads everything into a new AppDomain. And aside from some of the outer classes and factories, everything is marked private or internal so I can’t get at it without doing a bunch of reflection. Bah.</p>
<p>I’ve ended up taking a long look at <a href="http://www.openrasta.com/">OpenRasta</a>. OpenRasta was written with DI/IoC in mind, and it actually uses an internal IoC container for configuring the framework. More on that in a future post. It also has it’s own hosting support and API that have out-of-the-box implementations for ASP.NET, <a href="http://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx">HttpListener</a>, and “In Memory”. But you could always implement your own hosting code and integrate it.</p>
<p>The key word in that entire paragraph was “HttpListener”. That’s built-in .NET support for for web request processing that is baked into Windows via the kernel-mode http.sys driver. It’s relatively easy to use, and it’s wonderful. OpenRasta integrates with my existing application infrastructure, and marries it up with support for a REST-style web API, enabling me to very quickly expose a web API that allows third parties to integrate with my application. This is going to be more and more important as things like Windows Gadgets are implemented which are restricted in terms of the kinds of ways they can communicate (web requests) and with whom they can communicate (localhost, etc.)</p>
<p>Unfortunately OpenRasta doesn’t support <a href="http://ninject.org/">Ninject</a>, which I use, so I’m implementing the support for it and will submit the patch soon.</p>
<p>So far I’m extremely happy with the solution as I think developer productivity will be through the roof (compared to other more invasive solutions like WCF) and client-side integrations won’t be that difficult (POX). For my scenario, it’s all right up my alley. The internetz work for ME now!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronlerch?a=geXEMJwmI5U:Kz3RBKSW5q4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=geXEMJwmI5U:Kz3RBKSW5q4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=geXEMJwmI5U:Kz3RBKSW5q4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronlerch?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=geXEMJwmI5U:Kz3RBKSW5q4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=geXEMJwmI5U:Kz3RBKSW5q4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=geXEMJwmI5U:Kz3RBKSW5q4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=geXEMJwmI5U:Kz3RBKSW5q4:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronlerch/~4/geXEMJwmI5U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2009/08/20/say-hello-to-my-little-internet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.aaronlerch.com/blog/2009/08/20/say-hello-to-my-little-internet/</feedburner:origLink></item>
		<item>
		<title>#3!</title>
		<link>http://feedproxy.google.com/~r/aaronlerch/~3/3Rxda__-84A/</link>
		<comments>http://www.aaronlerch.com/blog/2009/04/02/3/#comments</comments>
		<pubDate>Fri, 03 Apr 2009 00:58:58 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2009/04/02/3/</guid>
		<description><![CDATA[No, that’s not a bash command or a regular expression. #3 will be joining #2 and #1, and we are pumped. Well, I’m pumped, my wife is just trying not to feel too sick. She’ll be pumped later, like in 5 years.]]></description>
			<content:encoded><![CDATA[<p>No, that’s not a bash command or a regular expression. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/ultrasound-3.jpg" /></p>
<p>#3 will be joining <a href="http://picasaweb.google.com/aaronlerch/FromHalloweenToThanksgiving#5275445275518695186">#2 and #1</a>, and we are pumped.    <br />Well, I’m pumped, my wife is just trying not to feel too sick. She’ll be pumped later, like in 5 years. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronlerch?a=3Rxda__-84A:SkQzsGtWTpI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=3Rxda__-84A:SkQzsGtWTpI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=3Rxda__-84A:SkQzsGtWTpI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronlerch?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=3Rxda__-84A:SkQzsGtWTpI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=3Rxda__-84A:SkQzsGtWTpI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=3Rxda__-84A:SkQzsGtWTpI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=3Rxda__-84A:SkQzsGtWTpI:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronlerch/~4/3Rxda__-84A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2009/04/02/3/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://www.aaronlerch.com/blog/2009/04/02/3/</feedburner:origLink></item>
		<item>
		<title>Design Pattern Resources</title>
		<link>http://feedproxy.google.com/~r/aaronlerch/~3/7yKmcsAIcuo/</link>
		<comments>http://www.aaronlerch.com/blog/2009/04/02/design-pattern-resources/#comments</comments>
		<pubDate>Fri, 03 Apr 2009 00:51:10 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2009/04/02/design-pattern-resources/</guid>
		<description><![CDATA[I’ve had a few people ask me for a recommendation of some resources to learn design patterns. There’s a lot of good stuff “out there”, of course, but my response usually says just three things: Read pretty much anything this guy writes, Learn SOLID, and lern it güd. I recommend starting here. and Let me [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve had a few people ask me for a recommendation of some resources to learn design patterns. There’s a lot of good stuff “out there”, of course, but my response usually says just three things:</p>
<p><a href="http://codebetter.com/blogs/jeremy.miller/"><strong>Read pretty much anything this guy writes</strong></a>,    <br /><strong>Learn </strong><a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod"><strong>SOLID</strong></a><strong>, and lern it güd. </strong><a href="http://www.lostechies.com/blogs/chad_myers/archive/2008/03/07/pablo-s-topic-of-the-month-march-solid-principles.aspx"><strong>I recommend starting here.</strong></a>    <br /><em>and</em>    <br /><strong>Let me know if you have any questions and let’s chat.</strong></p>
<p>If you’re anything like me, you’ll find yourself up until 4 AM reading, reading, and reading as you link from post to post and article to article. I swear one of these days I will find <a href="http://www.shibumi.org/eoti.htm">the end of the internet</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/aaronlerch?a=7yKmcsAIcuo:UXIyKNoBpLQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=7yKmcsAIcuo:UXIyKNoBpLQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=7yKmcsAIcuo:UXIyKNoBpLQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/aaronlerch?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=7yKmcsAIcuo:UXIyKNoBpLQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=7yKmcsAIcuo:UXIyKNoBpLQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/aaronlerch?a=7yKmcsAIcuo:UXIyKNoBpLQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/aaronlerch?i=7yKmcsAIcuo:UXIyKNoBpLQ:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronlerch/~4/7yKmcsAIcuo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2009/04/02/design-pattern-resources/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.aaronlerch.com/blog/2009/04/02/design-pattern-resources/</feedburner:origLink></item>
		<item>
		<title>Debugging UI</title>
		<link>http://feedproxy.google.com/~r/aaronlerch/~3/_k_77YFOC1Y/</link>
		<comments>http://www.aaronlerch.com/blog/2008/12/15/debugging-ui/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 19:01:09 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[windows forms]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/12/15/debugging-ui/</guid>
		<description><![CDATA[I&#8217;ve talked before about System.Threading.SynchronizationContext, as well as BeginInvoke/InvokedRequired/IsHandleCreated. In a multi-threaded Windows Forms application they can easily be mis-used, introducing difficult to find bugs. One such not-so-subtle bug (application hang) is particularly nasty, and is described fairly well here. Distilled down, the application hangs, usually when the computer comes out of sleep mode, unlocks, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve talked before about <a href="http://www.aaronlerch.com/blog/2007/05/19/net-20-winforms-multithreading-and-a-few-long-days/">System.Threading.SynchronizationContext</a>, as well as <a href="http://www.aaronlerch.com/blog/2006/12/15/controltrifecta-invokerequired-ishandlecreated-and-isdisposed/">BeginInvoke/InvokedRequired/IsHandleCreated</a>. In a multi-threaded Windows Forms application they can easily be mis-used, introducing difficult to find bugs.</p>
<p>One such not-so-subtle bug (application hang) is particularly nasty, and is <a href="http://ikriv.com:8765/en/prog/info/dotnet/MysteriousHang.html">described fairly well here</a>. Distilled down, the application hangs, usually when the computer comes out of sleep mode, unlocks, or another similar event occurs. The hang happens in the firing of an event handler, called from &#8220;SystemEvents.OnUserPreferenceChanged&#8221;. The cause is that OnUserPreferenceChanged is trying to be super nice, and invoke the event in the appropriate context for each event subscriber. That means that if a Control subscribes to the event, the handler will be called on the UI thread. If user code (on a background thread) subscribes, the handler will be called on an arbitrary thread, etc. The problem occurs when, at some point in the past, a Form or Control was created on a background thread. The creation of the control &#8220;installed&#8221; a WindowsFormsSynchronizationContext as the current SynchronizationContext (this is default behavior). When OnUserPreferenceChanged attempts to Send (Invoke) to the appropriate thread context, it hangs because the WindowsFormsSynchronizationContext is on the wrong thread, and thus has no message pump with which to process messages.</p>
<p>Blah blah blah. Right now you&#8217;re thinking &#8220;Whatever dude, I&#8217;m a web developer, man, I&#8217;m just trying to fix this bug in that <strong>other</strong> jerk&#8217;s code.&#8221; Fair enough, you can read the linked post for more gory details. What you care about is the hard part. Well, hard for <em>web developers</em> anyway. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  By the time the app hangs, it&#8217;s too late to find out where the problem occurred. In a medium-to-large application, how do you find the control that was created on the wrong thread? Here&#8217;s how to do it in a matter of seconds.</p>
<p><strong>1. Name your UI thread.</strong> If you&#8217;re not already doing this, it&#8217;s a good idea in general. I like to call mine &#8220;UI&#8221;, personally. In your &#8220;static void Main()&#8221; add this single line of code:</p>
<pre class="c#" name="code">Thread.CurrentThread.Name = "UI";</pre>
<p><strong>2. Set a breakpoint deep in the bowels of the BCL.</strong> What we want to do is cause our application to break when a WindowsFormsSynchronizationContext gets assigned to the current thread. I cracked open Reflector to look at the constructor for WindowsFormsSynchronizationContext:</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/winforms_synccontext_ctor.png"></p>
<p>And I see that there&#8217;s a call to &#8220;Application.ThreadContext.FromCurrent()&#8221;. Close enough for government work, it&#8217;ll do for what I want. I didn&#8217;t feel like figuring out how to specify a constructor call when setting a breakpoint. (If you know how, leave a comment so we can all learn!) Add a breakpoint to that method call. In Visual Studio, go to the &#8220;Debug&#8221; &gt; &#8220;New Breakpoint&#8221; &gt; &#8220;Break at Function&#8230;&#8221; menu. In the &#8220;Function&#8221; area type the full path to the function: System.Windows.Forms.Application.ThreadContext.FromCurrent()</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/new_breakpoint_threadcontext.png"></p>
<p>When you hit &#8220;OK&#8221; you&#8217;ll get a warning about IntelliSense not finding the specified location. Hit &#8220;Yes&#8221; to set the breakpoint anyway.</p>
<p><strong>3. Run your application.</strong> Depending on what version of Visual Studio you&#8217;re running, and whether you&#8217;ve got source-level debugging for the Framework turned on, you&#8217;ll either get the breakpoint on some code, or you&#8217;ll get this message box:</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/no_source_code_msgbox.png"></p>
<p>It doesn&#8217;t matter, you can press &#8220;OK&#8221; or &#8220;Show Disassembly&#8221;, whatever floats your boat. Go to the &#8220;Call Stack&#8221; debugging window, right-click on the red breakpoint circle located at the top of the stack frame, and select &#8220;Breakpoint&#8221; &gt; &#8220;Filter&#8230;&#8221;</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/breakpoint_filter.png"></p>
<p><strong>4. Add a filter to this breakpoint so that it only breaks when the current threads&#8217; name isn&#8217;t &#8220;UI&#8221;.</strong></p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/breakpoint_filter_non_ui_thread.png"></p>
<p>After you hit &#8220;OK&#8221;, continue running your application in the debugger. The first time a WindowsFormsSynchronizationContext is created and it&#8217;s not on the UI thread, BAM. There&#8217;s your problem, and there&#8217;s your stack trace allowing you to find the bad code.</p>
<p>This worked like a champ for me today, hopefully you have as much success with it too.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/aaronlerch?a=nlVZUEkD"><img src="http://feeds.feedburner.com/~f/aaronlerch?i=nlVZUEkD" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/aaronlerch?a=R1GvNCfT"><img src="http://feeds.feedburner.com/~f/aaronlerch?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/aaronlerch?a=WsPR7hMV"><img src="http://feeds.feedburner.com/~f/aaronlerch?i=WsPR7hMV" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/aaronlerch?a=N6Ak9kd8"><img src="http://feeds.feedburner.com/~f/aaronlerch?i=N6Ak9kd8" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronlerch/~4/_k_77YFOC1Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/12/15/debugging-ui/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.aaronlerch.com/blog/2008/12/15/debugging-ui/</feedburner:origLink></item>
		<item>
		<title>Case insensitive string comparisons with LINQ Dynamic Query</title>
		<link>http://feedproxy.google.com/~r/aaronlerch/~3/GuPfw2sI3PA/</link>
		<comments>http://www.aaronlerch.com/blog/2008/12/15/case-insensitive-string-comparisons-with-linq-dynamic-query/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 07:46:37 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[tips and tricks]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/12/15/case-insensitive-string-comparisons-with-linq-dynamic-query/</guid>
		<description><![CDATA[LINQ rocks. It really does. One down-side to LINQ is that, out of the box, it&#8217;s geared towards knowing your query structure at compile-time. The values can be dynamic, of course, but it&#8217;s assumed that the structure of your query is static. For example, if you want to select a set of &#34;Person&#34; objects from [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://msdn.microsoft.com/en-us/vbasic/aa904594.aspx">LINQ</a> rocks. It really does.</p>
<p>One down-side to LINQ is that, out of the box, it&#8217;s geared towards knowing your query structure at compile-time. The values can be dynamic, of course, but it&#8217;s assumed that the structure of your query is static. For example, if you want to select a set of &quot;Person&quot; objects from the &quot;People&quot; collection where Person.FirstName starts with &quot;Aar&quot;, you could write it as such:</p>
<pre class="c#" name="code">var results = from person in People
              where person.FirstName.StartsWith(&quot;Aar&quot;)
              select person;</pre>
<p>That&#8217;s all fine and good, but what about scenarios where you want to dynamically build up your query structure? In <a href="http://www.inin.com/">our</a> client application we have address books (directories) that include the ability to filter them on any, or nearly any, column:</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/client_directory_filter.png" /></p>
<p>How would I accomplish this with LINQ? Not easily. Just ask <a href="http://www.google.com/search?q=expression+tree+site:ayende.com">Ayende</a> or <a href="http://www.google.com/search?q=expression+tree+site:blog.wekeroad.com">Rob Conery</a>, both of whom have blogged about some of their adventures in advanced usage scenarios. Enter the LINQ Dynamic Query sample from Microsoft. As usual, <a href="http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx">ScottGu&#8217;s got a good write-up</a>. In a nutshell, it&#8217;s a custom expression tree generator based on a limited (but useful) string-based query grammar. With Dynamic Query I could write the query above like this:</p>
<pre class="c#" name="code">var results = from person in People
              select person;
results = results.Where(&quot;FirstName.StartsWith(\&quot;Aar\&quot;)&quot;);</pre>
<p>It solved my problem nicely. Almost. As with my example above about matching FirstName&#8217;s, let me ask: how often does a user enter an exact case-sensitive match for what they&#8217;re looking for? I can save you the trouble and tell you: it doesn&#8217;t matter. It&#8217;s an unacceptable requirement for a user to have to match something exactly. It&#8217;s already questionable that we don&#8217;t automatically use fuzzy matching algorithms.</p>
<p>So what I really want is to specify a StringComparison enum value on the call to &quot;StartsWith&quot;:</p>
<pre class="c#" name="code">var results = from person in People
              select person;
results = results.Where(&quot;FirstName.StartsWith(\&quot;Aar\&quot;, System.StringComparison.OrdinalIgnoreCase)&quot;);</pre>
<p>Alas, this breaks. LINQ Dynamic Query doesn&#8217;t support enum values as parameters to methods. <em>So I added it.</em> I won&#8217;t redistribute the sample (I&#8217;m pretty sure I can&#8217;t, but I don&#8217;t care to anyway) so here&#8217;s what you need to do to add support for enum parsing. Note that I&#8217;ve only tested it with calls to string&#8217;s StartsWith(string, StringComparison) method. I don&#8217;t know what will happen if you sprinkle enum values in random places throughout your dynamic query. Work on My Machine, your mileage may vary, etc. etc. etc.</p>
<p><strong>1.</strong> <a href="http://msdn2.microsoft.com/en-us/vcsharp/bb894665.aspx">Download the sample.</a></p>
<p><strong>2.</strong> Crack open the Dynamic.cs source file. It&#8217;s scary, but you can do it. Modify it like so (I added the &quot;if (ParseEnumType&#8230;&quot;</p>
<pre class="c#" name="code">Expression ParseIdentifier() {
    ValidateToken(TokenId.Identifier);
    object value;
    if (keywords.TryGetValue(token.text, out value)) {
        if (value is Type) return ParseTypeAccess((Type)value);
        if (value == (object)keywordIt) return ParseIt();
        if (value == (object)keywordIif) return ParseIif();
        if (value == (object)keywordNew) return ParseNew();
        NextToken();
        return (Expression)value;
    }
    if (symbols.TryGetValue(token.text, out value) ||
        externals != null &amp;&amp; externals.TryGetValue(token.text, out value)) {
        Expression expr = value as Expression;
        if (expr == null) {
            expr = Expression.Constant(value);
        }
        else {
            LambdaExpression lambda = expr as LambdaExpression;
            if (lambda != null) return ParseLambdaInvocation(lambda);
        }
        NextToken();
        return expr;
    }
    // ADD THIS IF STATEMENT
    if (ParseEnumType(out value))
    {
        Expression expr = Expression.Constant(value);
        NextToken();
        return expr;
    }
    if (it != null) return ParseMemberAccess(null, it);
    throw ParseError(Res.UnknownIdentifier, token.text);
}</pre>
<p><strong>3.</strong> Add the definition for ParseEnumType. This little bit of nastiness is essentially doing a look-ahead to resolve a type name, since most of the parser&#8217;s rules are built to process more contextual information (such as a property name of a type, etc.) In our case, we need to attempt to match &quot;Foo.Foo.Foo&quot; to a type name, and if it doesn&#8217;t end up resolving, we need to reset the parser back to the beginning of &quot;Foo&quot; to continue parsing.</p>
<pre class="c#" name="code">bool ParseEnumType(out object value)
{
    value = null;

    ValidateToken(TokenId.Identifier);
    Type enumType = null;
    int position = token.pos;
    string typeName = token.text;
    while (enumType == null)
    {
        // Loop until we stop processing identifiers and/or dots
        enumType = Type.GetType(typeName, false, true);
        if (enumType == null)
        {
            NextToken();
            if (token.id == TokenId.Dot)
            {
                typeName += token.text;
                NextToken();
                if (token.id == TokenId.Identifier)
                {
                    typeName += token.text;
                }
                else
                {
                    break;
                }
            }
            else
            {
                break;
            }
        }
    }

    if ((enumType != null) &amp;&amp; IsEnumType(enumType))
    {
        NextToken();
        ValidateToken(TokenId.Dot, Res.DotExpected);
        NextToken();
        ValidateToken(TokenId.Identifier, Res.IdentifierExpected);
        value = Enum.Parse(enumType, token.text, true);
        return true;
    }
    else
    {
        SetTextPos(position);
        NextToken();
    }

    return false;
}</pre>
<p><strong>4.</strong> Add an error &quot;resource&quot; string (but not really a true resource string) to the &quot;Res&quot; static class. We added a new condition, so we need an error message to match.</p>
<pre class="c#" name="code">public const string DotExpected = &quot;'.' expected&quot;;</pre>
<p>Voila! Make sure your enum values are fully-qualified type names and you&#8217;ll be good to go.</p>
<p>Hopefully this works for you as well as it did for me, and I have to say I can&#8217;t believe I couldn&#8217;t find this on the &#8216;net, as I imagine this is a very common use-case.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/aaronlerch?a=mtRL0RCP"><img src="http://feeds.feedburner.com/~f/aaronlerch?i=mtRL0RCP" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/aaronlerch?a=NP7fJsWl"><img src="http://feeds.feedburner.com/~f/aaronlerch?d=41" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/aaronlerch?a=HUaSypAn"><img src="http://feeds.feedburner.com/~f/aaronlerch?i=HUaSypAn" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/aaronlerch?a=3ZHQ96Fc"><img src="http://feeds.feedburner.com/~f/aaronlerch?i=3ZHQ96Fc" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/aaronlerch/~4/GuPfw2sI3PA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/12/15/case-insensitive-string-comparisons-with-linq-dynamic-query/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.aaronlerch.com/blog/2008/12/15/case-insensitive-string-comparisons-with-linq-dynamic-query/</feedburner:origLink></item>
	</channel>
</rss>
