<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Aaron Lerch &#187; programming</title>
	<atom:link href="http://www.aaronlerch.com/blog/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.aaronlerch.com/blog</link>
	<description></description>
	<lastBuildDate>Sun, 04 Dec 2011 03:27:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Coderetreatin&#8217;</title>
		<link>http://www.aaronlerch.com/blog/2011/12/03/coderetreatin/</link>
		<comments>http://www.aaronlerch.com/blog/2011/12/03/coderetreatin/#comments</comments>
		<pubDate>Sun, 04 Dec 2011 03:27:07 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[community]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/?p=257</guid>
		<description><![CDATA[Today, the Global Day of Coderetreat came to Indianapolis. And it was great. 13 people chose to spend the whole day on Saturday, December 3rd, in the &#8220;common area&#8221; at Interactive Intelligence honing their skillz. By the way, I want to extend a huge thanks to Interactive Intelligence for providing the space, a catered lunch, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.aaronlerch.com/blog/wp-content/uploads/2011/12/coderetreat-session-1.jpg"><img class="alignleft size-medium wp-image-258" title="Session 1 at Global Day of Coderetreat" src="http://www.aaronlerch.com/blog/wp-content/uploads/2011/12/coderetreat-session-1-300x224.jpg" alt="Session 1 at Global Day of Coderetreat" width="300" height="224" /></a>Today, the Global Day of Coderetreat came to Indianapolis. <em>And it was great.</em></p>
<p>13 people chose to spend the whole day on Saturday, December 3rd, in the &#8220;common area&#8221; at Interactive Intelligence honing their skillz.</p>
<p>By the way, I want to extend a huge <strong>thanks</strong> to Interactive Intelligence for providing the space, a catered lunch, and some breakfast! It was awesome!</p>
<p>This was my first coderetreat, not to mention the first one I&#8217;ve hosted and facilitated. I was trusting <a title="Corey Haines" href="http://coreyhaines.com/">Corey Haines&#8217;</a> experience when it came to the format, and I was very pleased with how it went. We did 6 45-minute sessions, each time pairing up and implementing Conway&#8217;s Game of Life. People used a wide variety of languages throughout the day: ruby, python, C#, java, javascript, even some C++.</p>
<p>Many of the people were new to practices like pairing, and TDD. We also got to explore a lot of design ideas and look at different ways to approach a problem. I really enjoyed being able to throw in various constraints during each session and then to see how it affected the approaches or designs that people came up with.</p>
<p>Overall, I got very positive feedback &#8211; it really seemed like a valuable day for everybody, for a wide variety of reasons. By far, people said that the pairing and the <a title="Ping Pong Programming" href="http://c2.com/cgi/wiki?PairProgrammingPingPongPattern">ping/pong TDD</a> were the most enlightening aspects of the day. It was great to have a structured and guided environment for people to explore those concepts that can otherwise be difficult to dig into ad-hoc.</p>
<p>Other things people learned or enjoyed were designing with the <a title="Tell, Don't Ask" href="http://pragprog.com/articles/tell-dont-ask">Tell, Don&#8217;t Ask</a> approach, and getting exposed to some new languages.</p>
<p>Overall I think it was a huge success. Or at least, I was very pleased with how it went and how it seemed to affect people. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  People grew as software developers today! That&#8217;s awesome in and of itself. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Thanks to all who attended!!</p>
<p><a href="http://www.aaronlerch.com/blog/wp-content/uploads/2011/12/coderetreaters.jpg"><img class="alignleft size-medium wp-image-259" title="Coderetreaters" src="http://www.aaronlerch.com/blog/wp-content/uploads/2011/12/coderetreaters-300x224.jpg" alt="Coderetreaters" width="300" height="224" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2011/12/03/coderetreatin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Analyzing Code with NDepend</title>
		<link>http://www.aaronlerch.com/blog/2010/04/03/analyzing-code-with-ndepend/</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>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2010/04/03/analyzing-code-with-ndepend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Design Pattern Resources</title>
		<link>http://www.aaronlerch.com/blog/2009/04/02/design-pattern-resources/</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>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2009/04/02/design-pattern-resources/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Are Twitter Clients the new Hello World app?</title>
		<link>http://www.aaronlerch.com/blog/2008/03/13/are-twitter-clients-the-new-hello-world-app/</link>
		<comments>http://www.aaronlerch.com/blog/2008/03/13/are-twitter-clients-the-new-hello-world-app/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 15:48:35 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[misc]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/03/13/are-twitter-clients-the-new-hello-world-app/</guid>
		<description><![CDATA[There&#8217;s been a bit of talk on Twitter recently about the various twitter clients that exist, with more being created practically every day. One view was that everybody is trying to create the ultimate twitter client. Maybe. Certainly there are a lot of new twitter client apps being made, some with lofty aspirations, but more [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s been a bit of talk on <a href="http://twitter.com/">Twitter</a> recently about the various twitter clients that exist, with more being created practically every day. <a href="http://twitter.com/shanselman/statuses/770579191">One view</a> was that everybody is trying to create the ultimate twitter client.</p>
<p><img src="http://s3.amazonaws.com:80/aaronlerch.com/images/hanselman-tweet-twitter-client.png" /></p>
<p>Maybe.</p>
<p>Certainly there are a lot of new twitter client apps being made, some with lofty aspirations, but more importantly I see a twitter client as the new &quot;<a href="http://en.wikipedia.org/wiki/Hello_world_program">Hello World</a>&quot; for desktop applications. And I think it&#8217;s a great choice. The days of a Hello World application consisting of a Console.WriteLine are long past. To dig in and learn something new, you have to implement something with at least a little substance to it.</p>
<p>A twitter client has the key components one needs when learning a new technology:</p>
<p><strong>Simple</strong></p>
<p>In terms of base functionality, a twitter client has a very simple task. Heck, Twitter itself is built around the simple premise of asking &quot;What are you doing right now?&quot; and letting you answer. A twitter client, at it&#8217;s core, needs to do two things: display your timeline and let you update your &quot;status&quot;. Simple as that.</p>
<p><strong>Easy and intuitive API</strong></p>
<p>Twitter&#8217;s <a href="http://groups.google.com/group/twitter-development-talk/web/api-documentation">API</a> is easy. Really easy. When you&#8217;re writing a real-world Hello World application, you want to focus on what you&#8217;re trying to learn, which is the technology, and not a complex API or other things that simply distract.</p>
<p><strong>Options</strong></p>
<p>Like most applications that have a user interface (and even those that don&#8217;t), there&#8217;s always room for choices. Depending on what you&#8217;re trying to learn (I&#8217;m a UI guy) you have different approaches you can take. If you&#8217;re learning WinForms or WPF, you can play with different presentation models, learning how to accomplish what you want. If you&#8217;re learning deeper back-end programming, you could play with the windows services APIs, or WCF, or whatever. It&#8217;s flexible.</p>
<p><strong>Room for expansion</strong></p>
<p>A twitter client can move beyond the basics I mentioned above and incorporate more features, with the limit practically being your imagination. Just look at <a href="http://twittervision.com/">twittervision</a>.</p>
<p><a href="http://s3.amazonaws.com:80/aaronlerch.com/images/bitter-gray.png"><img height="134" alt="Bitter" src="http://s3.amazonaws.com:80/aaronlerch.com/images/bitter-gray.png" width="72" align="right" /></a>My friend <a href="http://ilikeellipses.com/">Mike</a> has been diving head first into .NET (he&#8217;s an MFC guru), and decided to create a great twitter client (<a href="http://mikehallsite.com/bitter/">Bitter</a>) not to create the ultimate one, but to learn the technology. Which is good, because an ultimate twitter client has already been created. It&#8217;s called <a href="http://iconfactory.com/software/twitterrific">Twitterific</a>. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/03/13/are-twitter-clients-the-new-hello-world-app/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Confessions of a Software Developer*</title>
		<link>http://www.aaronlerch.com/blog/2008/01/30/confessions-of-a-software-developer/</link>
		<comments>http://www.aaronlerch.com/blog/2008/01/30/confessions-of-a-software-developer/#comments</comments>
		<pubDate>Wed, 30 Jan 2008 15:00:18 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/01/30/confessions-of-a-software-developer/</guid>
		<description><![CDATA[I&#8217;m ready to confess. It&#8217;s time to lay it all on the table. Ready? I can&#8217;t keep up! Wow, that was liberating! I think I should start a taxi service for developers. There is so much going on in the world of software, how can I keep up with it all, while still making progress [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/mdumlao98/976279763/"><img src="http://aaronlerch.com.s3.amazonaws.com/images/tech-taxi.jpg" align="right" /></a> I&#8217;m ready to confess. It&#8217;s time to lay it all on the table. Ready?</p>
<p><strong><font size="4">I can&#8217;t keep up!</font></strong></p>
<p>Wow, that was liberating! I think I should start a <a href="http://www.hbo.com/docs/programs/taxicab10/">taxi service for developers</a>.</p>
<p>There is so much going on in the world of software, how can I keep up with it all, while still making progress in my job? I can&#8217;t shift with the winds of what&#8217;s new or popular&#8211;even if it makes sense&#8211;they just shift too fast, it seems, and there&#8217;s no way I can be productive at work <em>and</em> keep up with all the new stuff. Goodness knows I try.</p>
<p>Here&#8217;s a list of things/buzzwords I really want to learn or use but haven&#8217;t had the time, or more importantly, haven&#8217;t had a real project that I could <em>practice</em> on. Growing in your software development abilities and experience relies on <a href="http://www.codinghorror.com/blog/archives/000446.html">mentoring and apprenticing</a>, after all. I wholeheartedly believe that. That&#8217;s why I work to surround myself with <a href="http://ilikeellipses.com/">incredible</a> <a href="http://www.moserware.com/">people</a>.</p>
<p><strong>1. TDD &#8211; <a href="http://en.wikipedia.org/wiki/Test-driven_development">Test Driven Development</a></strong>     <br />For a while now I&#8217;ve been at the point where I see the great benefits to TDD, and would love to do it, I just don&#8217;t know where to start. I need to really <em>learn</em> it. And by learn, I mean &quot;be mentored&quot;. I can read about it, but implementing it on a project takes it to a &#8216;<a href="http://en.wikipedia.org/wiki/MADtv_(season_12)">hole nutha level</a>&#8216;. And if I don&#8217;t know what I&#8217;m doing, I can&#8217;t implement it on a real project at work.</p>
<p><strong>2. DDD &#8211; <a href="http://domaindrivendesign.org/">Domain Driven Design</a></strong>     <br />This is a tough one, as it&#8217;s not really a technology or methodology, but more of a way of thinking. Which always makes me wonder: am I thinking this way? Should I be, if I&#8217;m not? How can I apply this way of thinking to my projects, considering that in many cases I&#8217;m adding features to existing products that haven&#8217;t necessarily been designed this way?</p>
<p><strong>3. BDD &#8211; <a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development">Behavior Driven Development</a></strong>     <br />No comment. I think I just need one or two more xDD acronyms to investigate.</p>
<p><strong>4. DI/IoC &#8211; <a href="http://en.wikipedia.org/wiki/Dependency_injection">Dependency Injection</a>/<a href="http://en.wikipedia.org/wiki/Inversion_of_control">Inversion of Control</a></strong>     <br />This feels pretty basic, and I understand the concepts and at least grok the list of <a href="http://en.wikipedia.org/wiki/Dependency_injection">available frameworks</a>. But in my experience it&#8217;s an architectural decision that if you don&#8217;t make from the start of an enterprise project, well, good luck getting it in later without a significant effort. And doing this right plus learning one of the existing frameworks takes a large investment that frequently I don&#8217;t have. At the moment we&#8217;ve chosen to use <a href="http://msdn2.microsoft.com/en-us/library/aa480450.aspx">CAB</a> (and related technologies) at work for our new projects, and I&#8217;m on the learning curve for it right now. I wish I was more well-rounded.</p>
<p><strong>5. ORM &#8211; <a href="http://en.wikipedia.org/wiki/Object-relational_mapping">Object Relational Mapping</a></strong>     <br />Basic stuff, right? Not for me. I work on a real-time system, not so much a database driven one, although I have done a lot of database-related work in the past. ORM doesn&#8217;t apply to me as much right now, but if you work on anything but a real-time system you&#8217;re probably using one. I&#8217;ve been learning <a href="http://www.hibernate.org/343.html">NHibernate</a> lately with <a href="http://code.google.com/p/codecampserver/">CodeCampServer</a>, and it&#8217;s definitely a stretch for me. I think the real problem is combining the ORM with DDD. ASAP, PDQ. FYI.</p>
<p><strong>6. AOP &#8211; <a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming">Aspect Oriented Programming</a></strong>     <br />Another &quot;nice to learn&quot; idea, but I have trouble making time to learn it, not to mention how to apply it.</p>
<p><strong>7. A bunch of stuff from </strong><a href="http://msmvps.com/blogs/kathleen/archive/2007/11/13/why-your-development-is-crazy.aspx"><strong>this list</strong></a><strong> (though not nearly everything)</strong>     <br />Stuff like refactoring (specifically how to apply it successfully to large projects), proper and structured integration of LINQ and dynamic languages (if at all), what I&#8217;ll call &quot;reasonable agile&quot; &#8212; non-extreme agile practices, visual modeling/model-driven design, evolving architectures, etc.</p>
<p>You might notice that some of these things on my list aren&#8217;t exactly new or groundbreaking. This <em>is</em> a confession, after all. Would it be confessing to say that I don&#8217;t know much about <a href="http://blogs.msdn.com/pablo/archive/2007/04/30/codename-astoria-data-services-for-the-web.aspx">Astoria</a>? Nah, most people don&#8217;t. So&#8230; does anybody else struggle to learn and incorporate stuff like this? What about those who don&#8217;t? Got any suggestions for me, and people like me? What are some good sources that a random developer on the Internet can find for being mentored in practices like TDD?</p>
<p><strong>* Disclaimer:</strong> I have to limit the term &quot;software developer&quot; to what I am: a non-consultant, full-time developer leading a team of 8 (within a dev organization of 130+) working on a mature and complex product with a release cycle of 12-18 months, and handling escalated support cases&#8211;you can&#8217;t <em>not</em> mention support! Oh, and I have a <a href="http://picasaweb.google.com/aaronlerch">family</a> and a life. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http://www.aaronlerch.com/blog/2008/01/30/confessions-of-a-software-developer/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.aaronlerch.com/blog/2008/01/30/confessions-of-a-software-developer/" border="0" alt="kick it on DotNetKicks.com" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/01/30/confessions-of-a-software-developer/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Refactoring C# with PowerShell</title>
		<link>http://www.aaronlerch.com/blog/2008/01/04/refactoring-c-with-powershell/</link>
		<comments>http://www.aaronlerch.com/blog/2008/01/04/refactoring-c-with-powershell/#comments</comments>
		<pubDate>Fri, 04 Jan 2008 18:06:07 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2008/01/04/refactoring-c-with-powershell/</guid>
		<description><![CDATA[Visual Studio 2005 and 2008 have built-in support for refactoring code, including renaming namespaces, classes, variables, and more. Add-ins like Resharper also have support for refactoring by renaming. These tools work great, and have good integration into the Visual Studio IDE, for example being able to preview each change and exclude false positive matches. I [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.aaronlerch.com/files/blog/RefactoringCwithPowerShell_E201/image.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" alt="image" src="http://aaronlerch.com.s3.amazonaws.com/images/refactoring_with_powershell_screenshot_thumb.png" width="222" align="right" border="0" /></a>Visual Studio 2005 and 2008 have built-in <a href="http://msdn2.microsoft.com/en-us/library/ms379618(VS.80).aspx#vs05_refac_topic8">support for refactoring code</a>, including renaming namespaces, classes, variables, and more. Add-ins like <a href="http://www.jetbrains.com/resharper/">Resharper</a> also have support for <a href="http://www.jetbrains.com/resharper/features/code_refactoring.html#Rename_Symbol_full">refactoring by renaming</a>. These tools work great, and have good integration into the Visual Studio IDE, for example being able to preview each change and exclude false positive matches. I know many people swear by Resharper in particular (for more features than the refactoring alone).</p>
<p>Unfortunately all of these tools are restricted in one normally insignificant way: they only operate on the currently loaded project(s). For most software this really is insignificant. The entire application can be loaded into the IDE all at once. Sometimes, though, it is a problem&#8211;usually when there&#8217;s another problem at play: <a href="http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html">code &quot;bloat&quot;</a> (<a href="http://www.moserware.com/2007/12/how-legacy-of-dead-mathematician-can.html">via Jeff</a>).</p>
<p>If you&#8217;ve ever changed a namespace and wanted to simply push the change into every code file in an entire directory branch, PowerShell comes to our rescue with it&#8217;s search-and-replace capabilities. I wrote the following &quot;Move-Namespace&quot; function to do just that.</p>
<p>Invoke the function like so: &quot;Move-Namespace *.cs &quot;[current namespace]&quot; &quot;[current class name]&quot; &quot;[new namespace]&quot;.</p>
<p>After it completes, any explicit reference will be changed, and any implicit references (using traditional &quot;using [namespace];&quot; statements) will have a new &quot;using [new namespace];&quot; line inserted after the last existing using statement.</p>
<p>Let&#8217;s hope you don&#8217;t have a code base that requires this function. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  But if you do, I hope it helps!</p>
<p><em>Note that this function relies on my &quot;Replace-String&quot; function, </em><a href="http://www.aaronlerch.com/blog/2007/03/28/powershell-replace-string-function/"><em>found here</em></a><em>.</em></p>
<pre class="csharpcode"><span class="kwrd">function</span> Move-Namespace(
    $includes = $(<span class="kwrd">throw</span> <span class="str">'Specify a file filter to use'</span>),
    $oldNamespace = $(<span class="kwrd">throw</span> <span class="str">'The namespace to replace - i.e. MyCompany.Product'</span>),
    $className = $(<span class="kwrd">throw</span> <span class="str">'The class name to search for - i.e. MyClass'</span>),
    $newNamespace = $(<span class="kwrd">throw</span> <span class="str">'The new namespace to add - i.e. MyCompany.Product.Feature'</span>))
{
    <span class="rem"># Look for cases of $className</span>
    <span class="rem"># or $oldNamespace.$className</span>
    <span class="rem"># and replace as necessary</span>

    <span class="rem"># First check for assumed &quot;using&quot; statements, and add the using statement</span>
    $results = @{}
    $files = get-childitem -r -i $includes | select-string <span class="str">&quot;(?&lt;!$oldNamespace\.)\b$className\b&quot;</span> -list |% { $_.Path }
    select-string <span class="str">&quot;^using.*;&quot;</span> -path $files | group-object Path | select-object Name, @{Expression={ ($_.Group | measure-object -property LineNumber -max).Maximum }; Name=<span class="str">&quot;LastUsingStatement&quot;</span> } |% { $results[$_.Name] = $_.LastUsingStatement }
    <span class="kwrd">foreach</span> ($key <span class="kwrd">in</span> $results.keys)
    {
      $processFile = $true
      $lastUsingIndex = $results[$key]
      $fileContents = get-content $key
      <span class="rem"># look for existing using statement and cancel processing this file</span>
      <span class="kwrd">for</span> ($i = 0; $i <span class="preproc">-lt</span> $lastUsingIndex; $i++)
      {
        <span class="kwrd">if</span> ($fileContents[$i] <span class="preproc">-match</span> <span class="str">&quot;using $newNamespace;&quot;</span>)
        {
          <span class="rem"># this file already has the correct using statement, stop processing</span>
          Write-Warning <span class="str">&quot;File $key already has the required using statement, ignoring&quot;</span>
          $processFile = $false
          <span class="kwrd">break</span>;
        }
      }

      <span class="kwrd">if</span> ($processFile)
      {
        $newContents = $fileContents[0..($lastUsingIndex-1)] + <span class="str">&quot;using $newNamespace;&quot;</span> + $fileContents[$lastUsingIndex..$fileContents.Length]
        set-content -path $key -value $newContents
        Write-Host <span class="str">&quot;Successfully updated file $key&quot;</span> -foregroundcolor Green
      }
    }

    <span class="rem"># Next check for explicit references</span>
    replace-string <span class="str">&quot;\b$oldNamespace\.$className\b&quot;</span> <span class="str">&quot;$newNamespace.$className&quot;</span> $includes
}</pre>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2008/01/04/refactoring-c-with-powershell/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Targeting .NET 2.0 and using C# 3.0 language features</title>
		<link>http://www.aaronlerch.com/blog/2007/12/02/targeting-net-20-and-using-c-30-language-features/</link>
		<comments>http://www.aaronlerch.com/blog/2007/12/02/targeting-net-20-and-using-c-30-language-features/#comments</comments>
		<pubDate>Sun, 02 Dec 2007 21:13:23 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[tips and tricks]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2007/12/02/targeting-net-20-and-using-c-30-language-features/</guid>
		<description><![CDATA[Did you know you can use most of the new C# 3.0 language features in VS2008 under a project that&#8217;s targeted at .NET 2.0? How cool is that? And it makes sense, too, since there&#8217;s nothing new for the 2.0 runtime, it&#8217;s all compiler magic. I found it by accident &#8211; I found Daniel Moth&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.danielmoth.com/Blog/2007/05/using-c-30-from-net-20.html">Did you know</a> you can use most of the new C# 3.0 language features in VS2008 under a project that&#8217;s targeted at .NET 2.0? How cool is that? And it makes sense, too, since there&#8217;s nothing new for the 2.0 runtime, it&#8217;s all compiler magic. I found it by accident &#8211; I found Daniel Moth&#8217;s post after the fact &#8211; I typed &#8220;prop&#8221; to access the snippet for generating a property. In VS2008, that snippet generates an <a href="http://weblogs.asp.net/scottgu/archive/2007/03/08/new-c-orcas-language-features-automatic-properties-object-initializers-and-collection-initializers.aspx">Automatic Property</a> by default.</p>
<p><a href="http://www.aaronlerch.com/files/blog/Targeting.NET2.0andusi.0languagefeatures_E3D4/image.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="74" alt="image" src="http://www.aaronlerch.com/files/blog/Targeting.NET2.0andusi.0languagefeatures_E3D4/image_thumb.png" width="383" border="0"></a> </p>
<p>I can&#8217;t decide whether this post should be categorized as a tip/trick or a warning, though. It&#8217;s both, probably.</p>
<p>In many development environments you won&#8217;t care &#8211; if you upgrade to Visual Studio 2008 then your build environment is upgraded also. But in some places, such as my company, we have large code bases that span many different technologies, and we have a specially created build system to handle all that. It uses specific compilers &#8211; VS7.1 for C++, for example, and the .NET 2.0 SDK compiler for C#.</p>
<p>You can <a href="http://www.west-wind.com/weblog/posts/122975.aspx">use Visual Studio 2008 for Visual Studio 2005 project files</a>, and with multi-targeting, you can use it in a .NET 2.0 environment. So, back to me as an example, I can transparently use VS2008 as my new IDE of choice &#8211; <em>on my local machine</em>. That means when I build from VS2008 locally, the new C# 3.0 language features will work seamlessly, but will fail when our automated builds pick up my changes.</p>
<p>Thus the warning &#8211; if you&#8217;re not careful (if you&#8217;re on &#8220;autopilot&#8221;) you can write code that will compile in the IDE but not with an SDK.</p>
<p>So, use VS2008, and be careful. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> <br />In my case, I always build from the command line anyway &#8211; that way I <em>know</em> that what I check in will build everywhere.</p>
<p>I did have a note to myself to get the .NET 3.5 SDK integrated into our build system, but I see that <a href="http://blogs.msdn.com/windowssdk/archive/2007/06/12/what-is-net-3-5.aspx">a stand-alone version doesn&#8217;t exist</a> &#8211; it&#8217;s being rolled into the Windows SDK which would have far too wide an impact. &lt;sigh&gt;</p>
<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:5fa73dbc-5264-40f7-a42e-45ad2b133f22" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tags: <a href="http://technorati.com/tags/.NET" rel="tag">.NET</a>, <a href="http://technorati.com/tags/Visual%20Studio" rel="tag">Visual Studio</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2007/12/02/targeting-net-20-and-using-c-30-language-features/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Watermarked edit controls</title>
		<link>http://www.aaronlerch.com/blog/2007/12/01/watermarked-edit-controls/</link>
		<comments>http://www.aaronlerch.com/blog/2007/12/01/watermarked-edit-controls/#comments</comments>
		<pubDate>Sat, 01 Dec 2007 21:58:48 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[ui]]></category>
		<category><![CDATA[windows forms]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2007/12/01/watermarked-edit-controls/</guid>
		<description><![CDATA[Recently I wanted to use a WinForms TextBox with some &#8220;watermark text&#8221;, but had some trouble finding anything existing on the web. Which was surprising because of how ubiquitous they are. Turns out the terminology varies: cue, prompt, or watermark. And &#8220;watermark&#8221; is the least used. Once I got my ducks in a row (by [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I wanted to use a WinForms TextBox with some &#8220;watermark text&#8221;, but had some trouble finding anything existing on the web. Which was surprising because of how ubiquitous they are. Turns out the terminology varies: cue, prompt, or watermark. And &#8220;watermark&#8221; is the least used.</p>
<p>Once I got my ducks in a row (by perusing the <a href="http://msdn2.microsoft.com/en-us/library/bb775458.aspx">MSDN documentation on the Win32 edit control</a>, which is the foundation of the .NET TextBox anyway) I found a few resources online, but they either a) didn&#8217;t wrap the exact Win32 edit control behavior, or b) were just a one-off &#8220;send a message to the control like this&#8221;, when I&#8217;d prefer a more polished derived control with designer support, etc.</p>
<p>So I present <a href="http://www.aaronlerch.com/files/blog/CueTextBox.cs">CueTextBox.cs</a>, <a href="http://www.aaronlerch.com/files/blog/CueComboBox.cs">CueComboBox.cs</a>, and <a href="http://www.aaronlerch.com/files/blog/CueToolStripTextBox.cs">CueToolStripTextBox.cs</a>. Here&#8217;s a simple example that hosts all 3 of them:</p>
<p><a href="http://www.aaronlerch.com/files/blog/Watermarkededitcontrols_EEC3/image.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="217" alt="image" src="http://www.aaronlerch.com/files/blog/Watermarkededitcontrols_EEC3/image_thumb.png" width="233" border="0"></a></p>
<p>And, in the interest of making this as easy as possible to get, here is the code. It&#8217;s really a very simple extension &#8211; I&#8217;m not sure why this wasn&#8217;t included in the BCF (but I can guess: this will only work on Windows XP and higher, and only if visual styles are enabled).<br />Note that the downloaded versions have the license text, but I&#8217;ve left it off this page (the license from the downloaded files applies). Why do you care? <a href="http://www.codinghorror.com/blog/archives/000833.html">Let Jeff Atwood tell you.</a></p>
<div class="wlWriterSmartContent" id="scid:C16BAC14-9A3D-4c50-9394-FBFEF7A93539:2e8d23c8-9c84-48bd-85d7-d65507fa38e0" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"><a href="http://www.dotnetkicks.com/kick/?url=http://www.aaronlerch.com/blog/2007/12/01/watermarked-edit-controls/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.aaronlerch.com/blog/2007/12/01/watermarked-edit-controls/" border="0" alt="kick it on DotNetKicks.com" /></a></div>
<p>CueTextbox.cs</p>
<pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Collections.Generic;
<span class="kwrd">using</span> System.ComponentModel;
<span class="kwrd">using</span> System.Data;
<span class="kwrd">using</span> System.Drawing;
<span class="kwrd">using</span> System.Text;
<span class="kwrd">using</span> System.Windows.Forms;
<span class="kwrd">using</span> System.Runtime.InteropServices;

<span class="kwrd">namespace</span> Lerch.Samples
{
    <span class="kwrd">public</span> <span class="kwrd">class</span> CueTextBox : TextBox
    {
        <span class="preproc">#region</span> PInvoke Helpers

        <span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">uint</span> ECM_FIRST = 0x1500;
        <span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">uint</span> EM_SETCUEBANNER = ECM_FIRST + 1;

        [DllImport(<span class="str">"user32.dll"</span>, CharSet = CharSet.Auto, SetLastError = <span class="kwrd">false</span>)]
        <span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">extern</span> IntPtr SendMessage(HandleRef hWnd, <span class="kwrd">uint</span> Msg, IntPtr wParam, String lParam);

        <span class="preproc">#endregion</span> PInvoke Helpers

        <span class="preproc">#region</span> CueText

        <span class="kwrd">private</span> <span class="kwrd">string</span> _cueText = String.Empty;

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// Gets or sets the text the &lt;see cref="TextBox"/&gt; will display as a cue to the user.</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        [Description(<span class="str">"The text value to be displayed as a cue to the user."</span>)]
        [Category(<span class="str">"Appearance"</span>)]
        [DefaultValue(<span class="str">""</span>)]
        [Localizable(<span class="kwrd">true</span>)]
        <span class="kwrd">public</span> <span class="kwrd">string</span> CueText
        {
            get { <span class="kwrd">return</span> _cueText; }
            set
            {
                <span class="kwrd">if</span> (<span class="kwrd">value</span> == <span class="kwrd">null</span>)
                {
                    <span class="kwrd">value</span> = String.Empty;
                }

                <span class="kwrd">if</span> (!_cueText.Equals(<span class="kwrd">value</span>, StringComparison.CurrentCulture))
                {
                    _cueText = <span class="kwrd">value</span>;
                    UpdateCue();
                    OnCueTextChanged(EventArgs.Empty);
                }
            }
        }

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// Occurs when the &lt;see cref="CueText"/&gt; property value changes.</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        <span class="kwrd">public</span> <span class="kwrd">event</span> EventHandler CueTextChanged;

        [EditorBrowsable(EditorBrowsableState.Advanced)]
        <span class="kwrd">protected</span> <span class="kwrd">virtual</span> <span class="kwrd">void</span> OnCueTextChanged(EventArgs e)
        {
            EventHandler handler = CueTextChanged;
            <span class="kwrd">if</span> (handler != <span class="kwrd">null</span>)
            {
                handler(<span class="kwrd">this</span>, e);
            }
        }

        <span class="preproc">#endregion</span> CueText

        <span class="preproc">#region</span> ShowCueTextOnFocus

        <span class="kwrd">private</span> <span class="kwrd">bool</span> _showCueTextWithFocus = <span class="kwrd">false</span>;

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// Gets or sets a value indicating whether the &lt;see cref="TextBox"/&gt; will display the &lt;see cref="CueText"/&gt;</span>
        <span class="rem">/// even when the control has focus.</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        [Description(<span class="str">"Indicates whether the CueText will be displayed even when the control has focus."</span>)]
        [Category(<span class="str">"Appearance"</span>)]
        [DefaultValue(<span class="kwrd">false</span>)]
        [Localizable(<span class="kwrd">true</span>)]
        <span class="kwrd">public</span> <span class="kwrd">bool</span> ShowCueTextWithFocus
        {
            get { <span class="kwrd">return</span> _showCueTextWithFocus; }
            set
            {
                <span class="kwrd">if</span> (_showCueTextWithFocus != <span class="kwrd">value</span>)
                {
                    _showCueTextWithFocus = <span class="kwrd">value</span>;
                    UpdateCue();
                    OnShowCueTextWithFocusChanged(EventArgs.Empty);
                }
            }
        }

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// Occurs when the &lt;see cref="ShowCueTextWithFocus"/&gt; property value changes.</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        <span class="kwrd">public</span> <span class="kwrd">event</span> EventHandler ShowCueTextWithFocusChanged;

        [EditorBrowsable(EditorBrowsableState.Advanced)]
        <span class="kwrd">protected</span> <span class="kwrd">virtual</span> <span class="kwrd">void</span> OnShowCueTextWithFocusChanged(EventArgs e)
        {
            EventHandler handler = ShowCueTextWithFocusChanged;
            <span class="kwrd">if</span> (handler != <span class="kwrd">null</span>)
            {
                handler(<span class="kwrd">this</span>, e);
            }
        }

        <span class="preproc">#endregion</span> ShowCueTextOnFocus

        <span class="preproc">#region</span> Overrides

        <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnHandleCreated(EventArgs e)
        {
            UpdateCue();

            <span class="kwrd">base</span>.OnHandleCreated(e);
        }

        <span class="preproc">#endregion</span> Overrides

        <span class="kwrd">private</span> <span class="kwrd">void</span> UpdateCue()
        {
            <span class="rem">// If the handle isn't yet created, </span>
            <span class="rem">// this will be called when it is created</span>
            <span class="kwrd">if</span> (<span class="kwrd">this</span>.IsHandleCreated)
            {
                SendMessage(<span class="kwrd">new</span> HandleRef(<span class="kwrd">this</span>, <span class="kwrd">this</span>.Handle), EM_SETCUEBANNER, (_showCueTextWithFocus) ? <span class="kwrd">new</span> IntPtr(1) : IntPtr.Zero, _cueText);
            }
        }
    }
}</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>CueComboBox.cs</p>
<pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Collections.Generic;
<span class="kwrd">using</span> System.ComponentModel;
<span class="kwrd">using</span> System.Data;
<span class="kwrd">using</span> System.Drawing;
<span class="kwrd">using</span> System.Text;
<span class="kwrd">using</span> System.Windows.Forms;
<span class="kwrd">using</span> System.Runtime.InteropServices;

<span class="kwrd">namespace</span> Lerch.Samples
{
    <span class="kwrd">public</span> <span class="kwrd">class</span> CueComboBox : ComboBox
    {
        <span class="preproc">#region</span> PInvoke Helpers

        <span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">uint</span> CB_SETCUEBANNER = 0x1703;

        [DllImport(<span class="str">"user32.dll"</span>, CharSet = CharSet.Auto, SetLastError = <span class="kwrd">false</span>)]
        <span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">extern</span> IntPtr SendMessage(HandleRef hWnd, <span class="kwrd">uint</span> Msg, IntPtr wParam, String lParam);

        <span class="preproc">#endregion</span> PInvoke Helpers

        <span class="preproc">#region</span> CueText

        <span class="kwrd">private</span> <span class="kwrd">string</span> _cueText = String.Empty;

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// Gets or sets the text the &lt;see cref="ComboBox"/&gt; will display as a cue to the user.</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        [Description(<span class="str">"The text value to be displayed as a cue to the user."</span>)]
        [Category(<span class="str">"Appearance"</span>)]
        [DefaultValue(<span class="str">""</span>)]
        [Localizable(<span class="kwrd">true</span>)]
        <span class="kwrd">public</span> <span class="kwrd">string</span> CueText
        {
            get { <span class="kwrd">return</span> _cueText; }
            set
            {
                <span class="kwrd">if</span> (<span class="kwrd">value</span> == <span class="kwrd">null</span>)
                {
                    <span class="kwrd">value</span> = String.Empty;
                }

                <span class="kwrd">if</span> (!_cueText.Equals(<span class="kwrd">value</span>, StringComparison.CurrentCulture))
                {
                    _cueText = <span class="kwrd">value</span>;
                    UpdateCue();
                    OnCueTextChanged(EventArgs.Empty);
                }
            }
        }

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// Occurs when the &lt;see cref="CueText"/&gt; property value changes.</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        <span class="kwrd">public</span> <span class="kwrd">event</span> EventHandler CueTextChanged;

        [EditorBrowsable(EditorBrowsableState.Advanced)]
        <span class="kwrd">protected</span> <span class="kwrd">virtual</span> <span class="kwrd">void</span> OnCueTextChanged(EventArgs e)
        {
            EventHandler handler = CueTextChanged;
            <span class="kwrd">if</span> (handler != <span class="kwrd">null</span>)
            {
                handler(<span class="kwrd">this</span>, e);
            }
        }

        <span class="preproc">#endregion</span> CueText

        <span class="preproc">#region</span> Overrides

        <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnHandleCreated(EventArgs e)
        {
            UpdateCue();

            <span class="kwrd">base</span>.OnHandleCreated(e);
        }

        <span class="preproc">#endregion</span> Overrides

        <span class="kwrd">private</span> <span class="kwrd">void</span> UpdateCue()
        {
            <span class="rem">// If the handle isn't yet created, </span>
            <span class="rem">// this will be called when it is created</span>
            <span class="kwrd">if</span> (<span class="kwrd">this</span>.IsHandleCreated)
            {
                SendMessage(<span class="kwrd">new</span> HandleRef(<span class="kwrd">this</span>, <span class="kwrd">this</span>.Handle), CB_SETCUEBANNER, IntPtr.Zero, _cueText);
            }
        }
    }
}</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>CueToolStripTextBox.cs</p>
<pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Collections.Generic;
<span class="kwrd">using</span> System.ComponentModel;
<span class="kwrd">using</span> System.Data;
<span class="kwrd">using</span> System.Drawing;
<span class="kwrd">using</span> System.Text;
<span class="kwrd">using</span> System.Windows.Forms;
<span class="kwrd">using</span> System.Runtime.InteropServices;

<span class="kwrd">namespace</span> Lerch.Samples
{
    <span class="kwrd">public</span> <span class="kwrd">class</span> CueToolStripTextBox : ToolStripTextBox
    {
        <span class="kwrd">public</span> CueToolStripTextBox()
            : <span class="kwrd">base</span>()
        {
            <span class="kwrd">if</span> (<span class="kwrd">this</span>.Control != <span class="kwrd">null</span>)
            {
                <span class="kwrd">this</span>.Control.HandleCreated += <span class="kwrd">new</span> EventHandler(OnControlHandleCreated);
            }
        }

        <span class="kwrd">public</span> CueToolStripTextBox(<span class="kwrd">string</span> name)
            : <span class="kwrd">base</span>(name)
        {
            <span class="kwrd">if</span> (<span class="kwrd">this</span>.Control != <span class="kwrd">null</span>)
            {
                <span class="kwrd">this</span>.Control.HandleCreated += <span class="kwrd">new</span> EventHandler(OnControlHandleCreated);
            }
        }

        <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Dispose(<span class="kwrd">bool</span> disposing)
        {
            <span class="kwrd">if</span> (disposing)
            {
                <span class="kwrd">if</span> (<span class="kwrd">this</span>.Control != <span class="kwrd">null</span>)
                {
                    <span class="kwrd">this</span>.Control.HandleCreated -= <span class="kwrd">new</span> EventHandler(OnControlHandleCreated);
                }
            }

            <span class="kwrd">base</span>.Dispose(disposing);
        }

        <span class="kwrd">void</span> OnControlHandleCreated(<span class="kwrd">object</span> sender, EventArgs e)
        {
            UpdateCue();
        }

        <span class="preproc">#region</span> PInvoke Helpers

        <span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">uint</span> ECM_FIRST = 0x1500;
        <span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">uint</span> EM_SETCUEBANNER = ECM_FIRST + 1;

        [DllImport(<span class="str">"user32.dll"</span>, CharSet = CharSet.Auto, SetLastError = <span class="kwrd">false</span>)]
        <span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">extern</span> IntPtr SendMessage(HandleRef hWnd, <span class="kwrd">uint</span> Msg, IntPtr wParam, String lParam);

        <span class="preproc">#endregion</span> PInvoke Helpers

        <span class="preproc">#region</span> CueText

        <span class="kwrd">private</span> <span class="kwrd">string</span> _cueText = String.Empty;

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// Gets or sets the text the &lt;see cref="TextBox"/&gt; will display as a cue to the user.</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        [Description(<span class="str">"The text value to be displayed as a cue to the user."</span>)]
        [Category(<span class="str">"Appearance"</span>)]
        [DefaultValue(<span class="str">""</span>)]
        [Localizable(<span class="kwrd">true</span>)]
        <span class="kwrd">public</span> <span class="kwrd">string</span> CueText
        {
            get { <span class="kwrd">return</span> _cueText; }
            set
            {
                <span class="kwrd">if</span> (<span class="kwrd">value</span> == <span class="kwrd">null</span>)
                {
                    <span class="kwrd">value</span> = String.Empty;
                }

                <span class="kwrd">if</span> (!_cueText.Equals(<span class="kwrd">value</span>, StringComparison.CurrentCulture))
                {
                    _cueText = <span class="kwrd">value</span>;
                    UpdateCue();
                    OnCueTextChanged(EventArgs.Empty);
                }
            }
        }

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// Occurs when the &lt;see cref="CueText"/&gt; property value changes.</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        <span class="kwrd">public</span> <span class="kwrd">event</span> EventHandler CueTextChanged;

        [EditorBrowsable(EditorBrowsableState.Advanced)]
        <span class="kwrd">protected</span> <span class="kwrd">virtual</span> <span class="kwrd">void</span> OnCueTextChanged(EventArgs e)
        {
            EventHandler handler = CueTextChanged;
            <span class="kwrd">if</span> (handler != <span class="kwrd">null</span>)
            {
                handler(<span class="kwrd">this</span>, e);
            }
        }

        <span class="preproc">#endregion</span> CueText

        <span class="preproc">#region</span> ShowCueTextOnFocus

        <span class="kwrd">private</span> <span class="kwrd">bool</span> _showCueTextWithFocus = <span class="kwrd">false</span>;

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// Gets or sets a value indicating whether the &lt;see cref="TextBox"/&gt; will display the &lt;see cref="CueText"/&gt;</span>
        <span class="rem">/// even when the control has focus.</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        [Description(<span class="str">"Indicates whether the CueText will be displayed even when the control has focus."</span>)]
        [Category(<span class="str">"Appearance"</span>)]
        [DefaultValue(<span class="kwrd">false</span>)]
        [Localizable(<span class="kwrd">true</span>)]
        <span class="kwrd">public</span> <span class="kwrd">bool</span> ShowCueTextWithFocus
        {
            get { <span class="kwrd">return</span> _showCueTextWithFocus; }
            set
            {
                <span class="kwrd">if</span> (_showCueTextWithFocus != <span class="kwrd">value</span>)
                {
                    _showCueTextWithFocus = <span class="kwrd">value</span>;
                    UpdateCue();
                    OnShowCueTextWithFocusChanged(EventArgs.Empty);
                }
            }
        }

        <span class="rem">/// &lt;summary&gt;</span>
        <span class="rem">/// Occurs when the &lt;see cref="ShowCueTextWithFocus"/&gt; property value changes.</span>
        <span class="rem">/// &lt;/summary&gt;</span>
        <span class="kwrd">public</span> <span class="kwrd">event</span> EventHandler ShowCueTextWithFocusChanged;

        [EditorBrowsable(EditorBrowsableState.Advanced)]
        <span class="kwrd">protected</span> <span class="kwrd">virtual</span> <span class="kwrd">void</span> OnShowCueTextWithFocusChanged(EventArgs e)
        {
            EventHandler handler = ShowCueTextWithFocusChanged;
            <span class="kwrd">if</span> (handler != <span class="kwrd">null</span>)
            {
                handler(<span class="kwrd">this</span>, e);
            }
        }

        <span class="preproc">#endregion</span> ShowCueTextOnFocus

        <span class="kwrd">private</span> <span class="kwrd">void</span> UpdateCue()
        {
            <span class="rem">// If the handle isn't yet created, </span>
            <span class="rem">// this will be called when it is created</span>
            <span class="kwrd">if</span> ((<span class="kwrd">this</span>.Control != <span class="kwrd">null</span>) &amp;&amp; (<span class="kwrd">this</span>.Control.IsHandleCreated))
            {
                SendMessage(<span class="kwrd">new</span> HandleRef(<span class="kwrd">this</span>.Control, <span class="kwrd">this</span>.Control.Handle), EM_SETCUEBANNER, (_showCueTextWithFocus) ? <span class="kwrd">new</span> IntPtr(1) : IntPtr.Zero, _cueText);
            }
        }
    }
}</pre>
<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e2e2dc60-4112-4f74-a361-e496f9980058" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tags: <a href="http://technorati.com/tags/Windows%20Forms" rel="tag">Windows Forms</a>, <a href="http://technorati.com/tags/UI" rel="tag">UI</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2007/12/01/watermarked-edit-controls/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Cmdlets vs. APIs</title>
		<link>http://www.aaronlerch.com/blog/2007/11/24/cmdlets-vs-apis/</link>
		<comments>http://www.aaronlerch.com/blog/2007/11/24/cmdlets-vs-apis/#comments</comments>
		<pubDate>Sun, 25 Nov 2007 02:53:29 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[powershell]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2007/11/24/cmdlets-vs-apis/</guid>
		<description><![CDATA[I&#8217;ve been working on a set of Powershell Cmdlets to fully replace the symstore.exe utility that is included with the Debugging Tools for Windows. (To be released as open source when I&#8217;m done.) When I think about writing Cmdlets, I tend to think that the best approach is to create an API and then wrap [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on a set of Powershell Cmdlets to fully replace the symstore.exe utility that is included with the <a href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx">Debugging Tools for Windows</a>. (To be released as open source when I&#8217;m done.) When I think about writing Cmdlets, I tend to think that the best approach is to create an API and then wrap it in a Cmdlet implementation. That enables the best of both worlds&#8211;someone can write an application that uses the API, or people can interact with the Cmdlets via the command line or in an application hosting a Powershell runspace.</p>
<p>But I think I&#8217;ve been very wrong. A while back Jeffrey Snover posted a great &#8220;core dump&#8221; of <a href="http://blogs.msdn.com/powershell/archive/2007/07/03/cmdlets-vs-apis.aspx">cmdlets vs. APIs</a>. He makes some good points, but even after reading it (back when he first posted it) I still thought that API + Cmdlet was the best approach. Experience has changed my mind. Here are, in my opinion, the most important points from his list (paraphrased).</p>
<p><strong>Error handling.</strong> An API can throw exceptions, but a Cmdlet can have terminating and non-terminating errors. With Cmdlets users can easily control the behavior when a non-terminating error occurs as well as get access to the collection of troublemaker objects.</p>
<p><strong>-WhatIf, -Confirm, and -Verbose support.</strong> There simply isn&#8217;t an easy way to have an API support a -WhatIf type of operation, while remaining a good API.</p>
<p><strong>Pipelines and wildcards.</strong> Wildcard support needs to be implemented on a per-API basis, making it a time-consuming (and possibly difficult) task. Working with &#8220;pipelines&#8221; requires specific coding by the user of the API.</p>
<p>The common thread between those three points is that an API simply can&#8217;t provide those services independent of Powershell. You really can&#8217;t create an API and wrap it in a Cmdlet. (If you have a choice.) If my &#8220;Remove-Foo&#8221; Cmdlet simply wraps &#8220;foo.Delete()&#8221;, &#8220;foo.Delete()&#8221; can&#8217;t make use of advanced error handling, or conditional processing (ala &#8220;-WhatIf&#8221; or &#8220;-Confirm&#8221;), or pipeline or wildcard support.</p>
<p>Because applications can host a Powershell runspace, any argument for an API goes away. Your Cmdlets <em>are</em> an API that developers can write code against. The thing that still gets me about this, though, is the verbose code it requires to exercise a Cmdlet&#8217;s &#8220;API&#8221;. Apparently Powershell V2 is going to <a href="http://blogs.msdn.com/powershell/archive/2007/11/06/what-s-new-in-ctp-of-powershell-2-0.aspx">help simplify the runspace hosting story</a>. Maybe that&#8217;s enough to knock the final leg out of my leaning towards an API? Once I finish my work, perhaps I&#8217;ll update the symstore SnapIn for V2 &#8211; in the meantime, I&#8217;d like to release them in a state that people could actually use them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2007/11/24/cmdlets-vs-apis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Having Fun Writing Software</title>
		<link>http://www.aaronlerch.com/blog/2007/10/23/having-fun-writing-software/</link>
		<comments>http://www.aaronlerch.com/blog/2007/10/23/having-fun-writing-software/#comments</comments>
		<pubDate>Wed, 24 Oct 2007 02:22:46 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[humor]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.aaronlerch.com/blog/2007/10/23/having-fun-writing-software/</guid>
		<description><![CDATA[I was exploring symstore.exe with Depends just now and came across a function in dbghelp that&#8217;s clearly not in the documentation. I got a nice chuckle out of it. What sort of &#8220;fun&#8221; (not nasty!) function names do you tend to create? Or do you keep them all boring plain Jane? (Boooo!!) The way metadata [...]]]></description>
			<content:encoded><![CDATA[<p>I was exploring symstore.exe with <a href="http://www.dependencywalker.com/">Depends</a> just now and came across a function in <a href="http://msdn2.microsoft.com/en-us/library/ms679292.aspx">dbghelp</a> that&#8217;s clearly not in the documentation. I got a nice chuckle out of it. <img src='http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a href="http://www.aaronlerch.com/files/blog/HavingFunWritingSoftware_13AB0/image.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="208" alt="image" src="http://www.aaronlerch.com/files/blog/HavingFunWritingSoftware_13AB0/image_thumb.png" width="504" border="0"></a></p>
<p>What sort of &#8220;fun&#8221; (not nasty!) function names do you tend to create? Or do you keep them all boring plain Jane? (Boooo!!) The way metadata is exposed in the .NET world, combined with a tool like <a href="http://www.aisto.com/roeder/dotnet/">Reflector</a>, make function names like this more readily &#8220;available&#8221;. But still, we&#8217;ve gotta have some fun somehow!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.aaronlerch.com/blog/2007/10/23/having-fun-writing-software/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

