<?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>Brian Sullivan</title>
	<atom:link href="http://www.sullivansoftdev.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sullivansoftdev.com/blog</link>
	<description>From one geek to another</description>
	<lastBuildDate>Fri, 13 Aug 2010 04:06:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>DevLink Retrospective</title>
		<link>http://www.sullivansoftdev.com/blog/2010/08/12/devlink-retrospective/</link>
		<comments>http://www.sullivansoftdev.com/blog/2010/08/12/devlink-retrospective/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 04:06:57 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.sullivansoftdev.com/blog/?p=227</guid>
		<description><![CDATA[I had a great experience at DevLink last week. For one thing, I got to hang out with a bunch of really smart people, some of whom I only knew through Twitter or their blogs.  I noticed during the dinner conversations and various Open Spaces sessions was that these guys read&#8230; a lot.  I used [...]]]></description>
			<content:encoded><![CDATA[<p>I had a great experience at DevLink last week.</p>
<p>For one thing, I got to hang out with a bunch of really smart people, some of whom I only knew through Twitter or their blogs.  I noticed during the dinner conversations and various Open Spaces sessions was that these guys read&#8230; <em>a lot</em>.  I used to be a pretty voracious reader, but that seems to have changed in the last few years.  Personal programming projects, research, and experimentation have taken the place of books in my evening routine.  While those activities may help me stay up-to-date technically, I think I&#8217;ve been missing out on bigger picture concepts that will only come from reading.  One of the takeaways from the conference for me was that I need to work on the balance between the two types of learning.  I plan to start going to bed earlier so I can read more.</p>
<p>Another thing that really started to crystallize in my mind at DevLink was that the primary value for me at conferences is networking and discussion with peers.  That&#8217;s not to say that the sessions weren&#8217;t valuable. On the contrary, there was a ton of great content, and I wish I had been able to see more of it.  But I&#8217;m a smart enough guy that I can usually pick up what I need about technical topics online through blog posts, articles, and tutorials.  What I <em>can&#8217;t</em> do every day is meet my peers face-to-face and begin to form relationships that are not only personally rewarding, but that can lead to career enrichment as well.  The various Open Spaces sessions I attended played a big part in this mind shift for me.  Kudos to <a href="http://netcave.org/">Alan Stevens</a> for helping facilitate such a great experience for the DevLink attendees.</p>
<p>I also got to hang out with some former co-workers from Praeses.  They took me to a restaurant where I watched my first UFC fight.  It wasn&#8217;t nearly as barbaric as I had expected, and I honestly enjoyed it a lot.  I may have to start attending the UFC-watching gatherings that those guys have from time to time.</p>
<p>My Mercurial session went pretty well, I think.  Based on the feedback, it definitely needs some polish in places, but I have a little bit of time to do that before I give it again at the <a href="http://nwacodecamp.org/">Northwest Arkansas Code Camp</a> and <a href="http://www.houstontechfest.com">Houston Tech Fest</a>.  If anybody who attended my session would like the slide deck, you can find it on my BitBucket account <a href="http://bitbucket.org/bmsullivan/mercurialpresentation/">here</a>.</p>
<p>All in all, it was definitely worth the trip up to Nashville, and I hope to make it back next year.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sullivansoftdev.com/blog/2010/08/12/devlink-retrospective/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speaking in August</title>
		<link>http://www.sullivansoftdev.com/blog/2010/08/01/speaking-in-august/</link>
		<comments>http://www.sullivansoftdev.com/blog/2010/08/01/speaking-in-august/#comments</comments>
		<pubDate>Sun, 01 Aug 2010 18:27:04 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Community]]></category>

		<guid isPermaLink="false">http://www.sullivansoftdev.com/blog/?p=225</guid>
		<description><![CDATA[This month, I&#8217;m speaking at not one, but two conferences! The first will be DevLink, next week on the 5th thru the 7th in Nashville, TN.  I&#8217;ll be giving a presentation on &#8220;Distributed Version Control with Mercurial&#8221;.  I&#8217;m looking forward to catching up with a bunch of friends who are planning to attend.  If you&#8217;re [...]]]></description>
			<content:encoded><![CDATA[<p>This month, I&#8217;m speaking at not one, but two conferences!</p>
<p>The first will be <a href="http://www.devlink.net">DevLink</a>, next week on the 5th thru the 7th in Nashville, TN.  I&#8217;ll be giving a presentation on &#8220;Distributed Version Control with Mercurial&#8221;.  I&#8217;m looking forward to catching up with a bunch of friends who are planning to attend.  If you&#8217;re going to be there, come see my session at 11:30 on Saturday!</p>
<p>The next one will be <a href="http://www.sqlsaturday.com/28/eventhome.aspx">SQL Saturday</a> in Baton Rouge on the 14th, where I&#8217;ll be giving my &#8220;Introduction to NHibernate and Fluent NHibernate&#8221; presentation again at 2:45.  I&#8217;ve done that one so many times lately, I think I could just about do it in my sleep at this point.  ;-)</p>
<p>Hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sullivansoftdev.com/blog/2010/08/01/speaking-in-august/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using PowerShell to Ease the Pain of Branch-per-feature in Web Applications</title>
		<link>http://www.sullivansoftdev.com/blog/2010/05/10/using-powershell-to-ease-the-pain-of-branch-per-feature-in-web-applications/</link>
		<comments>http://www.sullivansoftdev.com/blog/2010/05/10/using-powershell-to-ease-the-pain-of-branch-per-feature-in-web-applications/#comments</comments>
		<pubDate>Tue, 11 May 2010 01:43:42 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.sullivansoftdev.com/blog/?p=218</guid>
		<description><![CDATA[I’m currently using Mercurial for source control at work, and I absolutely love it.  I love the cheap branching, fast operations, and merging that actually works.  One of the side effects of using a branch-per-feature workflow in Mercurial is that you’re constantly creating new copies of your project structure in the file system.  Unlike Git, [...]]]></description>
			<content:encoded><![CDATA[<p>I’m currently using Mercurial for source control at work, and I absolutely love it.  I love the cheap branching, fast operations, and merging that actually <em>works</em>.  One of the side effects of using a branch-per-feature workflow in Mercurial is that you’re constantly creating new copies of your project structure in the file system.  Unlike Git, where the guidance is to create branches within one working copy of the repository and switch between them, the Mercurial community recommends creating full clones instead.</p>
<p>Even when doing development work, I like to use IIS for serving my web applications rather than the Visual Studio web server (Cassini), so my development environment is as close to production as possible.  I’ve gotten bitten a couple of times when transitioning from Cassini during development to IIS in production, so I decided to just use IIS from the start.</p>
<p>Using these technologies in combination, I started to run into a problem.  Every time I created a clone of my web app’s repository, I had to set up the directory as an IIS application, plus add the permissions required for IIS to read static files (and in my case, write to a temp images directory, since I’m using the Microsoft charting tool).  To make this process easier, I whipped up a couple of PowerShell scripts to take care of all those tasks in one fell swoop.</p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">
<pre style="text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum1" style="color: #606060;">   1:</span> <span style="color: #008000;"># New-App.ps1</span></pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum2" style="color: #606060;">   2:</span> <span style="color: #008000;"># usage: New-App "VirtualDirectoryName"</span></pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum3" style="color: #606060;">   3:</span> <span style="color: #0000ff;">param</span>([string]$appName = <span style="color: #006080;">"appName"</span>)</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum4" style="color: #606060;">   4:</span> $path = $pwd.Path</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum5" style="color: #606060;">   5:</span> $fullAppName = 'IIS:\Sites\Default Web Site\' + $appName</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum6" style="color: #606060;">   6:</span> pushd</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum7" style="color: #606060;">   7:</span> cd iis:</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum8" style="color: #606060;">   8:</span> ni $fullAppName -physicalPath $path -type Application</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum9" style="color: #606060;">   9:</span> cd c:</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum10" style="color: #606060;">  10:</span> popd</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum11" style="color: #606060;">  11:</span> $acl = Get-Acl $pwd.Path</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum12" style="color: #606060;">  12:</span> $inherit = [system.security.accesscontrol.InheritanceFlags]<span style="color: #006080;">"ContainerInherit, ObjectInherit"</span></pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum13" style="color: #606060;">  13:</span> $propagation = [system.security.accesscontrol.PropagationFlags]<span style="color: #006080;">"None"</span></pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum14" style="color: #606060;">  14:</span> $arIUSR = New-Object system.security.AccessControl.FileSystemAccessRule(<span style="color: #006080;">"IUSR"</span>, <span style="color: #006080;">"FullControl"</span>, $inherit, $propagation, <span style="color: #006080;">"Allow"</span>)</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum15" style="color: #606060;">  15:</span> $arIISIUSRS = New-Object system.security.AccessControl.FileSystemAccessRule(<span style="color: #006080;">"IIS_IUSRS"</span>, <span style="color: #006080;">"FullControl"</span>, $inherit, $propagation, <span style="color: #006080;">"Allow"</span>)</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum16" style="color: #606060;">  16:</span> $acl.SetAccessRule($arIUSR)</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum17" style="color: #606060;">  17:</span> $acl.SetAccessRule($arIISIUSRS)</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum18" style="color: #606060;">  18:</span> Set-Acl $pwd.Path $acl</pre>
<p><!--CRLF--></p>
</div>
</div>
<p>A couple of things about this one. A few things are hard-coded, like the site name (this will probably be “Default Web Site” on your machine, too unless you’re running a server OS) and the “FullControl” access, which can be changed to whatever minimum level of access you need the IIS accounts to have, like “Read” or “ReadAndExecute”.</p>
<p>I wish there was an easier way to set the permissions on the directory, but the System.Security .NET API was the only way that I found.  I’ve always felt that calling .NET code from PowerShell was a little bit kludgey, but I’m glad it’s at least possible to fill in the gaps in functionality.</p>
<p>In order to not leave an orphaned IIS virtual directory when I’m done with a branch, I use this script, which will search for the app by the physical path. This one could be fleshed out a little more.  It assumes that the virtual directory exists at the root of the default web site, and that you’re executing the script from the directory itself.</p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">
<pre style="text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum1" style="color: #606060;">   1:</span> <span style="color: #008000;">#Remove-App.ps1</span></pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum2" style="color: #606060;">   2:</span> $path = $pwd.Path</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum3" style="color: #606060;">   3:</span> pushd</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum4" style="color: #606060;">   4:</span> cd iis:</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum5" style="color: #606060;">   5:</span> cd <span style="color: #006080;">'IIS:\sites\Default Web Site'</span></pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum6" style="color: #606060;">   6:</span> $site = ls | Where-Object {$_.PhysicalPath <span style="color: #cc6633;">-eq</span> $path}</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum7" style="color: #606060;">   7:</span> ri $site.Name</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum8" style="color: #606060;">   8:</span> cd c:</pre>
<p><!--CRLF--></p>
<pre style="text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum9" style="color: #606060;">   9:</span> popd</pre>
<p><!--CRLF--></p>
</div>
</div>
<p>One more note: you&#8217;ll need to import the &#8220;WebAdministration&#8221; PowerShell module to get this to work. If you&#8217;re on Windows 7 and you&#8217;ve got PowerShell docked on your task bar, you can just right click and choose &#8220;Import System Modules&#8221;, the web admin module (along with a few others) will be imported into your PS session.  Otherwise, you can execute &#8220;Import-Module WebAdministration&#8221; at the PowerShell prompt or in your profile script.</p>
<p>Hope this helps somebody!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sullivansoftdev.com/blog/2010/05/10/using-powershell-to-ease-the-pain-of-branch-per-feature-in-web-applications/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Customer-Specific Behaviors in a Multi-Tenant Web Application Using Windsor</title>
		<link>http://www.sullivansoftdev.com/blog/2010/03/20/customer-specific-behaviors-in-a-multi-tenant-web-application-using-windsor/</link>
		<comments>http://www.sullivansoftdev.com/blog/2010/03/20/customer-specific-behaviors-in-a-multi-tenant-web-application-using-windsor/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 04:13:57 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.sullivansoftdev.com/blog/?p=194</guid>
		<description><![CDATA[The main application that I work on is a multi-tennant web application, and we&#8217;ve always struggled a bit with the best way to separate the different behaviors and features required by the different customers who use our application.  Right now, it&#8217;s accomplished by a mixture of database lookups, subclasses, and the dreaded switch statement. Lately, [...]]]></description>
			<content:encoded><![CDATA[<p>The main application that I work on is a multi-tennant web application, and we&#8217;ve always struggled a bit with the best way to separate the different behaviors and features required by the different customers who use our application.  Right now, it&#8217;s accomplished by a mixture of database lookups, subclasses, and the dreaded switch statement.</p>
<p>Lately, I&#8217;ve been working on a proof of concept for a new architecture.  We&#8217;re introducing several new things, including the Windsor inversion of control container.  After working with it a little bit and starting to get my mind around the benefits of leaving the responsibility of object construction to the container, I started to think that there must be a way to use the container to separate customer-specific behavior into different implementations of the same interface.  That way customers&#8217; rules would be nicely isolated and easy to find.  In order to do that I needed to find a way to inject a particular interface implementation based on a run-time value, in my case the organization to which the logged-on user belongs.</p>
<p>After quite a bit Googling, I finally came across <a href="http://ayende.com/Blog/archive/2008/10/05/windsor-ihandlerselector.aspx">this post</a> by Ayende Rahien.  The IHandlerSelector was exactly what I was looking for.  It works like this:  each time an object is constructed, Windsor calls the HasOpinionAbout method on each of the handler selectors you&#8217;ve defined, where you can determine based on the interface that&#8217;s being requested whether you want to decide yourself which implementation to use.  If you decide that you do, Windsor will call the SelectHandler method of your handler selector, giving you a full list of all the implementations of the interface that&#8217;s being requested that are registered with the container.  Based on whatever logic you want, you just return one of those implementations.</p>
<p>It&#8217;s a bit more clear with a concrete example.  One of the core concepts in my application is the inspection of certain kinds of machinery.  However, each organization that uses the application has different rules and processes around inspections.  So, I&#8217;ll define an interface called IInspectionService, and have an implementation per customer.  Let&#8217;s say we have two customers that use the app, Acme and ServiceCo (note: totally made-up business names).</p>
<p><script src="http://gist.github.com/317884.js?file=IInspectionService.cs"></script> <script src="http://gist.github.com/317911.js?file=ServiceCoInspectionService.cs"></script></p>
<p><script src="http://gist.github.com/317911.js?file=AcmeInspectionService.cs"></script> Now that we&#8217;ve got those defined, we need to register the interface and implementations with the container, then define our IHandlerSelector.  As with any IoC registration, you&#8217;ll want to do this just once, as your application is starting (the simplest way is to do it inside the Global.ascx.cs of your web app).  <script src="http://gist.github.com/339054.js?file=IHandlerSelector+registration"></script></p>
<p><script src="http://gist.github.com/339055.js?file=InspectionHandlerSelector.cs"></script> The implementation of IHandlerSelector needs a bit of explaining.  Whenever the container is about to create an instance of anything, it will call the HasOpinionAbout method on all IHandlerSelectors that you&#8217;ve registered.  The container&#8217;s basically asking, &#8220;Do you want to get directly involved in choosing which implementation to use?&#8221;  In our case, we only want to get our hands in there if the container is trying to select some implementation of our IInspectionService, so we return &#8220;true&#8221; from HasOpinionAbout if that&#8217;s the case.</p>
<p>If HasOpinionAbout returns &#8220;true&#8221; for an IHandlerSelector, the container will then call that IHandlerSelector&#8217;s implementation of SelectHandler.  The key parameter to that method is the third one, the array of IHandlers.  All the implementations that could possibly satisfy the interface in question (IInspectionService in this case) that have been registered with the container will be inside that array, you just have to pick the one you want to use, using any arbitrary criteria you like.  Since we&#8217;re talking about this in the context of a multi-tenant system, I based the decision here on the group that the currently logged-on user belongs to.</p>
<p>So what does this all this IoC stuff get us?  Well, it particularly shines in an ASP.NET MVC application, where you can have the IoC container take control of creating your controllers, and thusly specify all of your controllers&#8217; dependencies in their constructors.  When you do that in combination with an IHandlerSelector, you completely remove all the messy &#8220;if&#8230;then&#8221; code related to different customers from your controller action methods.    <script src="http://gist.github.com/339069.js?file=InspectionController.cs"></script></p>
<p>In the code above, when the container creates the InspectionController, it will use our IHandlerSelector to pick the appropriate implementation of IInspectionService to pass in to the controller&#8217;s constructor.  So, if a customer from Acme is signed in, _inspectionService will be an AcmeInspectionService, and if a customer from Service Co. is logged in, _inspectionService will be a ServiceCoInspectionService.</p>
<p>I think this is a great way to segregate customer-specific logic.  It&#8217;s all in one class per customer, and doesn&#8217;t clutter up the entirety of your application.  You could also have a base class with operations that needed to happen regardless  of the customer to reduce duplication if needed.</p>
<p>I hope this is useful to somebody!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sullivansoftdev.com/blog/2010/03/20/customer-specific-behaviors-in-a-multi-tenant-web-application-using-windsor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My First &#8220;Speaking Tour&#8221;</title>
		<link>http://www.sullivansoftdev.com/blog/2010/03/11/my-first-speaking-tour/</link>
		<comments>http://www.sullivansoftdev.com/blog/2010/03/11/my-first-speaking-tour/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 03:56:04 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.sullivansoftdev.com/blog/?p=205</guid>
		<description><![CDATA[I took a trip up to northwest Arkansas earlier this week to speak to several different .NET User Groups in the area about NHibernate.  On Monday evening, I spoke at my user group &#8220;alma mater&#8221;, the Fort Smith .NET User Group.  It was great to see a bunch of my old friends from Data-Tronics, including [...]]]></description>
			<content:encoded><![CDATA[<p>I took a trip up to northwest Arkansas earlier this week to speak to several different .NET User Groups in the area about NHibernate.  On Monday evening, I spoke at my user group &#8220;alma mater&#8221;, the <a href="http://www.fsdnug.org">Fort Smith .NET User Group</a>.  It was great to see a bunch of my old friends from Data-Tronics, including group president <a href="http://www.mohundro.com/blog/">David Mohundro</a>.</p>
<p>The next day, I was quite busy.  I met <a href="http://twitter.com/robbygregory">Robby Gregory</a> and a few other Wal-Mart employees for lunch, and at 1:30 I spoke at the Wal-Mart internal .NET User Group.  I then moved on to the Tyson internal user group (known as &#8220;DevLoop&#8221;) at 4:00, and directly on from there to the <a href="http://nwadnug.org/">Northwest Arkansas .NET User Group</a> at 6:00.  I enjoyed hanging out with <a href="http://jaysmith.us">Jay</a>, <a href="http://letsblogabout.net/">John</a>, <a href="http://devlinliles.com/">Devlin</a>, <a href="http://www.mpaladino.com/">Michael</a>, and several others at Jose&#8217;s afterwards, but by that time I was pretty beat.</p>
<p>I&#8217;m really glad that I&#8217;m getting to start speaking more (big thanks to my new employer Falcon Applications for letting me keep the dates only a week after I started the job!).  I&#8217;ve submitted a session for the <a href="http://dallastechfest.com/">Dallas TechFest</a>, plan to submit one or two for <a href="http://www.devlink.net/">DevLink</a>, and will continue to try to speak at other user groups later this year, as well.  Looks like I&#8217;m well on track to meeting at least one of my <a href="http://www.sullivansoftdev.com/blog/2010/01/07/a-plan-for-2010/">goals</a> for 2010!</p>
<p>Thanks to all the user group leaders who invited me up; I hope to be able to visit again some time!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sullivansoftdev.com/blog/2010/03/11/my-first-speaking-tour/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>I Love Lucy</title>
		<link>http://www.sullivansoftdev.com/blog/2010/02/24/i-love-lucy/</link>
		<comments>http://www.sullivansoftdev.com/blog/2010/02/24/i-love-lucy/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 05:13:38 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.sullivansoftdev.com/blog/?p=197</guid>
		<description><![CDATA[This past Friday, the Sullivan family got a little bit bigger. Mom and baby are both doing fine.  I have to say, at least from the daddy perspective, the prior experience definitely helps.  I feel like things are going much easier than they did with our first daughter, Molly.  We&#8217;re still getting quite a bit [...]]]></description>
			<content:encoded><![CDATA[<p>This past Friday, the Sullivan family got a little bit bigger.</p>
<div id="attachment_198" class="wp-caption alignnone" style="width: 235px"><a href="http://www.sullivansoftdev.com/blog/wp-content/uploads/2010/02/photo-1.jpg"><img class="size-medium wp-image-198" title="Lucy's Eyes" src="http://www.sullivansoftdev.com/blog/wp-content/uploads/2010/02/photo-1-225x300.jpg" alt="" width="225" height="300" /></a><p class="wp-caption-text">Lucy Sullivan</p></div>
<p>Mom and baby are both doing fine.  I have to say, at least from the daddy perspective, the prior experience definitely helps.  I feel like things are going much easier than they did with our first daughter, Molly.  We&#8217;re still getting quite a bit less sleep than normal, but there aren&#8217;t as many unknowns, and we don&#8217;t get stressed out about everything the way we did the first time.</p>
<p>And Lucy herself has been making it pretty easy; she&#8217;s a champion sleeper, just like her daddy!</p>
<p>Needless to say, blogging has taken kind of a back seat, but I hope to start back up again soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sullivansoftdev.com/blog/2010/02/24/i-love-lucy/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Why is the .NET Community Using git?</title>
		<link>http://www.sullivansoftdev.com/blog/2010/02/06/why-is-the-net-community-using-git/</link>
		<comments>http://www.sullivansoftdev.com/blog/2010/02/06/why-is-the-net-community-using-git/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 21:57:02 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.sullivansoftdev.com/blog/?p=186</guid>
		<description><![CDATA[(Disclaimer: I have minimal experience with DVCSs.  The title of this post is an honest question, and if I&#8217;ve made any incorrect asummptions or gotten something just flat-out wrong, I&#8217;d love to be corrected.  Please let me know in the comments!) My friend David Mohundro wrote a post the other day with some great tips [...]]]></description>
			<content:encoded><![CDATA[<p>(Disclaimer: I have minimal experience with DVCSs.  The title of this post is an honest question, and if I&#8217;ve made any incorrect asummptions or gotten something just flat-out wrong, I&#8217;d love to be corrected.  Please let me know in the comments!)</p>
<p>My friend David Mohundro wrote a <a href="http://www.mohundro.com/blog/2010/02/04/SomeTipsOnUsingGitWithWindows.aspx">post</a> the other day with some great tips on using git on Windows.  That got me thinking about why the .NET open-source community has started to coalesce around git as its source control tool of choice.  I know git is the new hotness, but it&#8217;s not the only distributed version control system (DVCS) out there.  In particular, I wonder why <a href="http://mercurial.selenic.com/">Mercurial</a> hasn&#8217;t caught on.  It&#8217;s a DVCS like git, is more compatible with Windows, and is easier for new users to learn (by virtue of simply having fewer commands and using terminology closer to that of older VCSs).</p>
<p>I know that git can be used on Windows using a project called &#8220;msysgit,&#8221; but the fact that that project exists at all should tell us something about git.  Git was developed by Linus Torvalds to be used when working on the Linux kernel, using a combination of C and Linux shell scripts.  The maintainers have very little motivation to make git cross-platform, since it already solves the problem it was designed to solve.  In addition, the maintainers of the msysgit project have not always been very interested in solving the problems of their users, as evidenced by comments like <a href="http://twitter.com/subdigital/status/6775154920">these</a>.</p>
<p>Mercurial, on the other hand, is designed to be cross-platform in the first place  (from the about page on the Mercurial site:  &#8221;Mercurial was designed with platform independence in mind.&#8221;).  It seems to me that it ought to be a more natural fit for people developing on the Windows platform.  And it&#8217;s not as if it&#8217;s some obscure bit of technology used by only a few people; large organizations (e.g. Mozilla and the Python Software Foundation) as well as smaller ones are using it.  On top of that, Codeplex (Microsoft&#8217;s open-source project hosting site) <a href="http://blogs.msdn.com/codeplex/archive/2010/01/22/codeplex-now-supporting-native-mercurial.aspx">now supports Mercurial</a>, and so does <a href="http://googlecode.blogspot.com/2009/04/mercurial-support-for-project-hosting.html">Google Code</a>.  So why git instead of Mercurial?</p>
<p>I have a couple of theories about why lots of .NET devs have made this choice, but please keep in mind the disclaimer at the top of this post.</p>
<ol>
<li><strong>Features</strong> &#8211; Git does have a few features that Mercurial lacks.  Most notably, it has an index or &#8220;staging area&#8221;, which allows you to have more control of what a commit will look like.  Local branching is also a bit different, since git doesn&#8217;t actually create a copy of all the files in the repository when you create a branch.  It would seem to me, though, that the main feature that attracts OSS devs to git is its distributed nature, which fits very well with the OSS workflow, and which Mercurial shares.</li>
<li><strong>A Superior Project Hosting Site in GitHub</strong> &#8211; Almost immediately after its launch, <a href="http://github.com">GitHub</a> became <em>the</em> place to be for open source projects, and for good reason.  The site offers a great user experience, and lots of tools to make maintaining a project easier, such as the network graph and pull requests.  <a href="http://bitbucket.org">Bitbucket</a> aims to do the same for Mercurial, and has some of the same features, but hasn&#8217;t caught on the way GitHub has. (Circular logic there, maybe? Oh, well.)</li>
<li><strong>Rails Envy</strong></li>
</ol>
<p>I hate to say it, but this last one is the one that I suspect may be closest to the truth.   .NET developers, especially ones heavily involved in open source software, have always had a bit of an inferiority complex.  At first we felt inferior to Java devs, who had a big head start on figuring out the limitations of their platform, which led to development of lots of patterns and a plethora of open source tools at their disposal (their culture was a lot more amenable to open source a lot earlier than the Microsoft culture was).  The similarities between the .NET and Java platforms and languages was to the .NET community&#8217;s advantage; it was straightforward to directly port many of the more useful Java tools, and the patterns translated easily.</p>
<p>A few years ago, a shift in who we compared ourselves to began.  We saw how much less friction there was when using a framework like Rails and a malleable language like Ruby.  So, as we did before, the .NET OSS community began adopting the tools and patterns used by those we <del><span style="color: #000000;">envied</span></del> admired.  Some of these things translated pretty well.  The principle of convention over configuration, for example, has nothing to do with platforms; it&#8217;s just a mind shift that .NET OSS devs were willing and eager to make.  The tools, however, can&#8217;t always make the jump.  Windows has always been a second-class citizen when it comes to Rails development (DHH has made his disdain for the platform <a href="http://www.loudthinking.com/arc/000433.html">quite clear</a>), and that tends to create a self-perpetuating cycle.  The existing Rails devs don&#8217;t put much effort into making things like tools and plugins cross-platform, so the experience sucks for devs on Windows, who finally give up and switch to a Mac (or at least do their Rails development on a Linux VM), so nobody&#8217;s clamoring for the tools to work on Windows.  Regardless, many .NET OSS devs tend to use a lot of the same tools as Rails devs.  Things like rake, Cucumber, and, of course, git.  It sometimes seems like we&#8217;re bending over backwards to make tools that weren&#8217;t designed for our environment work for us anyway (e.g. msysgit).</p>
<p>So are the few extra features in git or the better UX on GitHub really enough to justify the friction of using git on Windows, or is it just a cargo-cult mentality?  As I said, I have very little experience with either git or Mercurial, so I may be missing something big.  I&#8217;d love to hear from someone who has experience with both DVCSs to set me straight.</p>
<p>In any case, I hope that at some point, we as .NET developers can get over our inferiority complex and just feel comfortable in our own skin.  That doesn&#8217;t mean using the Microsoft tool every time, but acknowledging that sometimes, just because a tool is useful in one environment, doesn&#8217;t mean it&#8217;s a better fit (let alone the aesthetically superior choice) for ours.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sullivansoftdev.com/blog/2010/02/06/why-is-the-net-community-using-git/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Developing Against Large Databases</title>
		<link>http://www.sullivansoftdev.com/blog/2010/01/30/developing-against-large-databases/</link>
		<comments>http://www.sullivansoftdev.com/blog/2010/01/30/developing-against-large-databases/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:58:29 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.sullivansoftdev.com/blog/?p=179</guid>
		<description><![CDATA[The database for the main application that I work on is fairly large, about 50 Gb or so.  Not the largest SQL Server database I&#8217;ve seen, by far, but one that is non-trivial to move across the network.  This has a significant impact on the development process of our team.  The size of the database [...]]]></description>
			<content:encoded><![CDATA[<p>The database for the main application that I work on is fairly large, about 50 Gb or so.  Not the largest SQL Server database I&#8217;ve seen, by far, but one that is non-trivial to move across the network.  This has a significant impact on the development process of our team.  The size of the database combined with the mediocre size of the hard drives on the laptops we use means that keeping a local copy of production data is unfeasible.</p>
<p>Getting a local database&#8217;s schema in sync with that on production would be easy, but in our case, that&#8217;s not enough to create a working system.  Our application has a large amount what I call &#8220;static data&#8221;, such as menu structures or sets of permissions.  So getting a database that&#8217;s &#8220;up to date&#8221; means not only getting the schema in sync with production, but also ensuring this static data is up to date as well.</p>
<p>Using some sort of tool for evolutionary database design like Rails ActiveRecord migrations would alleviate some of these problems, because schema and static data changes would be a part of the source code. Developers could just run the migrations on their local databases after they updated from source control.  However, this still wouldn&#8217;t solve the whole problem.  In order to effectively develop features within the application, our developers need a reasonable set of test data so that the system isn&#8217;t just completely empty.</p>
<p>There are tools out there, such as Red Gate&#8217;s <a href="http://www.red-gate.com/products/SQL_Data_Generator/index.htm">SQL Data Generator</a> or the <a href="http://msdn.microsoft.com/en-us/library/dd193262(VS.100).aspx">data generators in Visual Studio</a>, that will do a pretty good job creating test data by looking at database column and table names, foreign keys, and such.  This might work out even for such a large system as ours, except that a lot of key tables have &#8220;polymorphic&#8221; relationships, meaning that the foreign key that they contain could point to the primary key in a number of different tables, depending on the particular piece of data.</p>
<p>For example, say we have an &#8220;Invoices&#8221; table.  We have a multi-tenant system, and our customers often base their invoicing on different things.  Some might base invoices based on each individual service they performed for their clients, while others might base them on the amount of time logged in the time and expense module for a client.  In each case, the invoice database record needs to point back to a record in the table that&#8217;s most relevant, given the customer&#8217;s business processes.  Another example of this kind of relationship might be audit records, which might point back to just about any other table in the system.</p>
<p>Since these &#8220;polymorphic&#8221; associations are not defined as proper foreign keys in the database, those data generation tools wouldn&#8217;t be able to figure out that the columns were foreign keys at all, and as far as I&#8217;ve been able to figure, it&#8217;s not possible to define foreign key relationships with a number of different tables manually.  And even if it were, I don&#8217;t think I could prevent the tool from associating and invoice from a company that bases it&#8217;s invoices on services performed with a time and expense entry.</p>
<p>There are a couple of ways that our developers cope with this, neither of which are ideal.  The first, which most of our team members use, is to develop against one of several shared database instances on our data tier servers.  The problems associated with using shared databases for development are well established; developers simply can&#8217;t be as productive when stepping all over each other with data and schema changes.</p>
<p>The second, which I use, is to keep an instance of the database on an external hard drive.  This keeps me isolated from the changes made by other developers, and it&#8217;s a significantly better experience than using a shared database, but problems start to crop up when I get latest from source control.  Developers will check in source code changes that require data or schema changes in order to work, and my local database won&#8217;t have those changes.</p>
<p>So, at the end of the day, the only reliable way to get an up-to-date copy of the schema is to restore a database from the last backup of production.  Since the database is so big, that restore takes multiple hours, which can seriously impede the development process.  This actually impacts developers using shared databases even more than me, because when one of those shared databases has to be refreshed, multiple developers are put out of commission.</p>
<p>The only way I&#8217;ve thought of to make this a little better is to manually create a script that will cherry-pick a certain number of rows from what&#8217;s essentially the &#8220;root&#8221; table of our database, and spider out to include all the data related to those cherry-picked rows, while also including all rows from the tables that contain static data.  The end result would be a much smaller test database that contains a meaningful subset of production data that could me moved around and refreshed in minutes or seconds rather than hours.  The problems with this idea are that it would be onerous to create the script in the first place, since our database contains over 500 tables, and keeping the script up to date with any changes to tables or columns.</p>
<p>I wish there was an easier answer to this.  I have a few ideas in the back of my head about writing a tool that might help me create those scripts, but I think it would still end up being a very manual process of defining relationships that only a human being with knowledge of the system would be able to come up with.  If any readers have experience with this kind of thing, I&#8217;d love to hear how you dealt with it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sullivansoftdev.com/blog/2010/01/30/developing-against-large-databases/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>TFS Installation: No Longer Rocket Science</title>
		<link>http://www.sullivansoftdev.com/blog/2010/01/20/tfs-installation-no-longer-rocket-science/</link>
		<comments>http://www.sullivansoftdev.com/blog/2010/01/20/tfs-installation-no-longer-rocket-science/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 02:35:19 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[TFS]]></category>

		<guid isPermaLink="false">http://www.sullivansoftdev.com/blog/?p=177</guid>
		<description><![CDATA[I think one of the best things that I&#8217;ve observed in playing around with TFS 2010 was how easy it was to install.  This was a pretty big hurdle in previous versions, but 2010 has installation pared down to a &#8220;Next, Next, Finish&#8221; level of complexity in some simple scenarios.  In particular, the &#8220;Basic&#8221; installation, [...]]]></description>
			<content:encoded><![CDATA[<p>I think one of the best things that I&#8217;ve observed in playing around with TFS 2010 was how easy it was to install.  This was a pretty big hurdle in previous versions, but 2010 has installation pared down to a &#8220;Next, Next, Finish&#8221; level of complexity in some simple scenarios.  In particular, the &#8220;Basic&#8221; installation, which doesn&#8217;t include the SharePoint or Reporting Services components, is brain-dead simple.</p>
<p>In addition, TFS can now be installed on client OSes (Vista and above), and use the free SQL Server Express.  It will even go so far as to install SQL Express for you if you don&#8217;t already have it installed (you probably already do if you&#8217;ve installed Visual Studio).  You can download Beta 2 of TFS 2010 from <a href="http://www.microsoft.com/downloads/details.aspx?familyid=6C70FD8F-615E-4203-A028-ACB2C2B8B88F&amp;displaylang=en">here</a>.</p>
<p>However, if you don&#8217;t want to sully your pristine machine with Beta products, there&#8217;s a fully configured Virtual PC image available for download <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=27d91e63-e33b-4cef-a331-f20d343da9de&amp;displaylang=en">here</a>.</p>
<p>In other words, it&#8217;s pretty trivial now to try out TFS yourself if you&#8217;re stuck on SourceSafe and are looking to try out all the other mainstream options, or (like me) if your shop&#8217;s already using TFS and you&#8217;d like to try your hand at some of the administrative features that are behind lock and key.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sullivansoftdev.com/blog/2010/01/20/tfs-installation-no-longer-rocket-science/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A Plan for 2010</title>
		<link>http://www.sullivansoftdev.com/blog/2010/01/07/a-plan-for-2010/</link>
		<comments>http://www.sullivansoftdev.com/blog/2010/01/07/a-plan-for-2010/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 03:33:02 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.sullivansoftdev.com/blog/?p=175</guid>
		<description><![CDATA[Everyone on my blogroll is taking the opportunity of the new year to take stock of 2009 and make public plans for 2010, so I thought I would join in. In 2009, I made an effort to start speaking a little bit more.  I spoke at my first code camp, the Northwest Arkansas Code Camp, on [...]]]></description>
			<content:encoded><![CDATA[<p>Everyone on my blogroll is taking the opportunity of the new year to take stock of 2009 and make public plans for 2010, so I thought I would join in.</p>
<p>In 2009, I made an effort to start speaking a little bit more.  I spoke at my first code camp, the <a href="http://codecamp.nwadnug.org/">Northwest Arkansas Code Camp</a>, on the Harding and LSU campuses for recruiting trips for my employer, as well as the Baton Rouge .NET User Group.  I hope to continue ramping that up in 2010.  I&#8217;m presenting at my home meeting, the Shreveport .NET User Group, later this month, and I have a trip scheduled to the northwest Arkansas area in March.  I&#8217;d like to make it down to southern Louisiana at some point, too; the guys down in Lafayette and New Orleans in particular need some love.</p>
<p>I also need to step up in promoting the SDNUG this year.  I felt like I was able to kind of coast for a lot of 2009 with our current set of attendees, and didn&#8217;t really make as much of an effort as I could have to make more people aware of the group&#8217;s existence.  I&#8217;ve already begun to remedy that this year by seeking out area software companies and making phone calls, which will hopefully yield some more members.  I need to get on top of speaker scheduling, too, both within the group and without.  There are several group members that I think would make great presenters, I just need to convince them that it&#8217;s a good idea!</p>
<p>I want to start blogging more, as well.  One post a month just isn&#8217;t where I want to be.  I think having a regular schedule will help with that, so I&#8217;m pledging right now in public to post something on my blog at least once a week.  That plan may take a hit when my daughter is born in February, but I&#8217;m going to give it my best effort.</p>
<p>I think something else that may help with blogging is having an area of focus.  I&#8217;ve really been interested in application lifecycle management lately, especially after all the stuff I saw at PDC, so at least for now, I think I&#8217;ll focus on Team System and TFS for a little while.  I&#8217;ve been listening to the back catalog of <a href="www.radiotfs.com">Radio TFS</a>, which has been great, and I plan to seek out other additional resources for ideas. I&#8217;ve recently installed TFS on a virtual machine to play around with, so hopefully that will lead to some ideas, as well.</p>
<p>I hope you had a great 2009; here&#8217;s to 2010!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sullivansoftdev.com/blog/2010/01/07/a-plan-for-2010/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
