<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>A Technical Debtor</title>
        <link>http://blog.dotnetspeech.net/Default.aspx</link>
        <description>Toward continuous improvment</description>
        <language>en-US</language>
        <copyright>Jeff Certain</copyright>
        <managingEditor>jeff@dotnetspeech.net</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <image>
            <title>A Technical Debtor</title>
            <url>http://blog.dotnetspeech.net/images/RSS2Image.gif</url>
            <link>http://blog.dotnetspeech.net/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>Architectural Renovation &amp;ndash; 2 of N</title>
            <link>http://blog.dotnetspeech.net/archive/2010/07/13/architectural-renovation-ndash-2-of-n.aspx</link>
            <description>&lt;p&gt;One of the things that I failed to mention in yesterday’s post is that this series is going to be descriptive, not prescriptive. The biggest reason for that is that my experience is rather narrow in some regards, and I have some advantages that other developers and architects don’t enjoy. For example, the VP of Software at CCI (who I don’t report to, but who makes the calls about letting me borrow the developers!) was one of the earliest developers on our product… in the days when it was migrated to Access 2.0.&lt;/p&gt;  &lt;p&gt;I mentioned briefly an example of what I refer to as “guerilla” architecture – that is, something that can be accomplished by a single person without a great deal of impact on, or effort required by, the rest of the team. (This was the modification of the code generation templates to use inheritance to reduce the amount of duplicated code.)&lt;/p&gt;  &lt;p&gt;However, not all problems are this small, or can be accomplished without some sort of tacit approval. So, I’m going to touch briefly on some of the things I did to build consensus for putting such a massive effort into improving the architecture. &lt;/p&gt;  &lt;p&gt;One of the things that became apparent very early was that there was an architectural pattern around the data that was causing developers at least twice as much work as was needed. I knew this, the developers knew this, the team leads knew this… but management wasn’t aware of the details. The first thing I did was bring the team leads on board, talking to them about the issue and explaining a proposed solution. This was a long-term effort, with a few words about it here and there. Part of the issue was that it was such a daunting change, and with such wide-reaching tendrils, that it honestly took me about 10 months to have the a-ha moment on how to attack the problem. (I mentioned in another post that I was on salary… it’s a good thing, too… I don’t think many consultants get the opportunity to take 10 months to propose a solution.)&lt;/p&gt;  &lt;p&gt;Even before I had the solution in mind, however, I had sent a survey to all our developers. Among other things, it asked what the number one thing was that made their jobs more difficult. It really wasn’t any surprise when the unanimously indicated the very architectural pattern I wanted to change – as I said, pretty much everyone knew it was a problem. However, this gave me a concrete result that I could point to when discussing with management. I also have the benefit of having a leadership team above me that understands, not only software, but what happens when you keep a code base alive for a decade or more. By explaining that the architecture we had made development difficult, and would make maintenance even harder, I was able (along with the survey results) to present a compelling argument for change.&lt;/p&gt;  &lt;p&gt;Next post, I’ll talk about what decisions ought to be considered once you’ve got approval to make massive changes.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=140917"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=140917" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://blog.dotnetspeech.net/aggbug/140917.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Certain</dc:creator>
            <guid>http://blog.dotnetspeech.net/archive/2010/07/13/architectural-renovation-ndash-2-of-n.aspx</guid>
            <pubDate>Wed, 14 Jul 2010 02:10:26 GMT</pubDate>
            <wfw:comment>http://blog.dotnetspeech.net/comments/140917.aspx</wfw:comment>
            <comments>http://blog.dotnetspeech.net/archive/2010/07/13/architectural-renovation-ndash-2-of-n.aspx#feedback</comments>
            <wfw:commentRss>http://blog.dotnetspeech.net/comments/commentRss/140917.aspx</wfw:commentRss>
            <trackback:ping>http://blog.dotnetspeech.net/services/trackbacks/140917.aspx</trackback:ping>
        </item>
        <item>
            <title>Architectural Renovation?</title>
            <category>ALTDOTNET</category>
            <category>Software Development</category>
            <link>http://blog.dotnetspeech.net/archive/2010/07/12/architectural-renovation.aspx</link>
            <description>&lt;p&gt;Mere minutes after I &lt;a target="_blank" href="http://geekswithblogs.net/TechnicalDebtor/archive/2010/07/12/architectural-refactoringhellip.-why-now.aspx#527909"&gt;posted on “architectural refactoring&lt;/a&gt;,” &lt;a target="_blank" href="http://geekswithblogs.net/Designingcode"&gt;Keith Nicholas&lt;/a&gt; has commented about the unsuitability of the term. He said:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;you'd be better off calling it "evolutionary design" &lt;br /&gt;
The dilution of the word refactoring is disturbing, there's a certain rigor to "factorization" which shouldn't destroy the product. &lt;br /&gt;
refactoring != a cool way to say "I'm gonna change stuff"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There’s a fair bit to be said on this, so I thought I’d add another post rather than try to reply in an undersized comment box.&lt;/p&gt;
&lt;p&gt;I agree that the use of "refactoring" in this context makes me a little squeamish. Keith is absolutely right that there's a lack of rigor here -- partly because the scope of the changes ensures that enough changes that this isn't really a refactoring in the Fowleresque sense.&lt;/p&gt;
&lt;p&gt;However, as Fowler defines it, "&lt;a target="_blank" href="http://martinfowler.com/articles/designDead.html#id21462"&gt;evolutionary design means that the design of the system grows as the system is implemented&lt;/a&gt;". In the case I'm describing, the design isn't growing. Rather, suboptimal design decisions are being rethought, reworked, rebuilt. In an evolutionary sense, I suppose you could argue this is "growth," since the new architecture is "fitter" than the old.&lt;/p&gt;
&lt;p&gt;However, to my mind, the word "evolutionary" brings with it a connotation that the improvement is a small forward step, building on what is already there -- not a massive reworking of the underpinnings of the architecture.&lt;/p&gt;
&lt;p&gt;The scope of this effort is what's a little unusual. Kyle Baley, for example, talks &lt;a target="_blank" href="http://kyle.baley.org/ArchitecturalChangesOrLdquoHowToDecideIfAndWhenToStartOverrdquo.aspx"&gt;here&lt;/a&gt; about architectural changes and how you know when it’s time to start over. Now, Kyle is a fellow Canuck and an all-around decent fellow. I even agree that, from what he describes, they made the right choice. However, he describes an effort that was scoped at &lt;em&gt;a maximum of 2 developer-weeks&lt;/em&gt;. I had on the order of twice as much time personally into proof-of-concept for the changes that were made; all told, we invested something like 120 developer-weeks into the changes.&lt;/p&gt;
&lt;p&gt;I have trouble calling a step of this magnitude “evolutionary.” Perhaps architectural renovation would be a more apt term.&lt;/p&gt;
&lt;p&gt;(And, as a minor aside, when I said earlier that “I’m not even leaving the functionality intact,” I should have been clearer. The original architecture made heavy, brilliant and infuriating use of refactoring. That trait, among others, were ripped out. After the renovation, the code base had been reduced by close to 40%, and virtually every line of code had been touched, or at least inspected. However, the &lt;em&gt;business functionality&lt;/em&gt; remained essentially unchanged – essentially, since we were able to identify and remove a fair number of bugs during the process.)&lt;/p&gt;
&lt;p&gt;Thanks for keeping me honest, Keith – and for the great point you made.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=140903"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=140903" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://blog.dotnetspeech.net/aggbug/140903.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Certain</dc:creator>
            <guid>http://blog.dotnetspeech.net/archive/2010/07/12/architectural-renovation.aspx</guid>
            <pubDate>Tue, 13 Jul 2010 03:29:40 GMT</pubDate>
            <wfw:comment>http://blog.dotnetspeech.net/comments/140903.aspx</wfw:comment>
            <comments>http://blog.dotnetspeech.net/archive/2010/07/12/architectural-renovation.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://blog.dotnetspeech.net/comments/commentRss/140903.aspx</wfw:commentRss>
            <trackback:ping>http://blog.dotnetspeech.net/services/trackbacks/140903.aspx</trackback:ping>
        </item>
        <item>
            <title>New York City, Here I Come!!</title>
            <category>Software Architects Group</category>
            <category>Software Development</category>
            <category>User Group Talks</category>
            <link>http://blog.dotnetspeech.net/archive/2010/07/12/new-york-city-here-i-come.aspx</link>
            <description>&lt;p&gt;I’m delighted to reveal that I’ve been accepted to speak at the International Association of Software Architects (IASA) &lt;a target="_blank" href="http://www.iasahome.org/web/itarc/nyc2010"&gt;IT Architecture Conference (ITARC) in New York City&lt;/a&gt;, September 22-24th. I’ll be speaking on effective architecture refactoring… or, in other words, telling people about the mistakes I made, in the hopes that they won’t have to repeat them.&lt;/p&gt;
&lt;p&gt;For those in NYC, this is well worth attending. The keynotes will be delivered by some people you may have heard of: John Zachman, Scott Ambler, George Paras, Len Bass and Angela Yochem. Eric Evans has been relegated to only giving a talk this year, as is Paul Rayner. The inimitable Doc List will be moderating an Open Spaces session. All in all, the sort of conference that takes about a month to fully sink in. Hope to see you there!&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=140900"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=140900" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://blog.dotnetspeech.net/aggbug/140900.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Certain</dc:creator>
            <guid>http://blog.dotnetspeech.net/archive/2010/07/12/new-york-city-here-i-come.aspx</guid>
            <pubDate>Tue, 13 Jul 2010 02:45:45 GMT</pubDate>
            <wfw:comment>http://blog.dotnetspeech.net/comments/140900.aspx</wfw:comment>
            <comments>http://blog.dotnetspeech.net/archive/2010/07/12/new-york-city-here-i-come.aspx#feedback</comments>
            <wfw:commentRss>http://blog.dotnetspeech.net/comments/commentRss/140900.aspx</wfw:commentRss>
            <trackback:ping>http://blog.dotnetspeech.net/services/trackbacks/140900.aspx</trackback:ping>
        </item>
        <item>
            <title>Speaking at Heartland Developer Conference</title>
            <link>http://blog.dotnetspeech.net/archive/2010/07/12/speaking-at-heartland-developer-conference.aspx</link>
            <description>&lt;p&gt;Yet another in my frenzy of posts for tonight!&lt;/p&gt;  &lt;p&gt;I’ve been accepted to speak at the &lt;a href="http://www.heartlanddc.com/" target="_blank"&gt;Heartland Developer’s Conference&lt;/a&gt; in Omaha, NE (Sept 8-10). This is an amazing conference, put on by Joe Olsen. An absolutely star-studded cast of speakers – some of the names you might recognize include (in no particular order) Chris Williams, Amanda Laucher, Don Demsak, Jason Bock, and Jason Beres. (Yes, I’m still surprised Joe is going to let me speak.)&lt;/p&gt;  &lt;p&gt;The price is very reasonable for a two-day conference. If you’re anywhere in the midwest, this is a great conference to attend. I went last year, and it was absolutely spectacular. Knowing Joe, he’s only going to outdo himself this year.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=140897"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=140897" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://blog.dotnetspeech.net/aggbug/140897.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Certain</dc:creator>
            <guid>http://blog.dotnetspeech.net/archive/2010/07/12/speaking-at-heartland-developer-conference.aspx</guid>
            <pubDate>Tue, 13 Jul 2010 02:32:53 GMT</pubDate>
            <wfw:comment>http://blog.dotnetspeech.net/comments/140897.aspx</wfw:comment>
            <comments>http://blog.dotnetspeech.net/archive/2010/07/12/speaking-at-heartland-developer-conference.aspx#feedback</comments>
            <wfw:commentRss>http://blog.dotnetspeech.net/comments/commentRss/140897.aspx</wfw:commentRss>
            <trackback:ping>http://blog.dotnetspeech.net/services/trackbacks/140897.aspx</trackback:ping>
        </item>
        <item>
            <title>Architectural Refactoring&amp;hellip; Why Now?</title>
            <category>Software Architects Group</category>
            <category>Software Development</category>
            <link>http://blog.dotnetspeech.net/archive/2010/07/12/architectural-refactoringhellip.-why-now.aspx</link>
            <description>&lt;p&gt;You’ll notice for the next little while, I’m going to be talking about architectural refactoring. These posts will be a reflection on the past couple years as a software architect, specifically centered around what some people call “brownfield” development. That is, taking something that is in a less than ideal state, and improving it… not starting from scratch as in new (or “greenfield”) development.&lt;/p&gt;
&lt;p&gt;Leaving aside philosophical discussions about whether all software development is “brownfield” or not (no plan survives contact with the enemy; no architecture survives contact with the writing of code), what I’m really interested in sharing is the experiences I’ve had with architectural refactoring. If Martin Fowler stumbles across this blog, I’m sure he’ll take exception to my use of the term “refactoring.” After all, I’m not making a series of small changes, validated through unit testing. I’m not even leaving the functionality intact. In at least one of the cases that I’ll describe, what I did was more akin to lifting the house off the foundation, blowing the old foundation into rubble, pouring a new basement, and then setting the house back down.&lt;/p&gt;
&lt;p&gt;(I say “I” in this case… but really, I was the one that pushed the button that blew the foundation apart, then handed a new set of blueprints to the development team – they did the work rebuilding the business logic to deal with the changes I made.)&lt;/p&gt;
&lt;p&gt;I had the privilege to give a talk about this, at &lt;a target="_blank" href="http://virtual-genius.com/"&gt;Paul Rayner’s&lt;/a&gt; encouraging, for the IASA ITARC (I don’t know what it stands for either – it’s a regional conference) in Denver in May. The talk was incredibly well received, and &lt;a target="_blank" href="http://georgefairbanks.com/"&gt;George Fairbanks&lt;/a&gt; was gracious enough to encourage me to write about what I presented in that talk. So, here I am… writing about it, and also doing a fair bit more talking about it.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=140896"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=140896" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://blog.dotnetspeech.net/aggbug/140896.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Certain</dc:creator>
            <guid>http://blog.dotnetspeech.net/archive/2010/07/12/architectural-refactoringhellip.-why-now.aspx</guid>
            <pubDate>Tue, 13 Jul 2010 02:23:50 GMT</pubDate>
            <wfw:comment>http://blog.dotnetspeech.net/comments/140896.aspx</wfw:comment>
            <comments>http://blog.dotnetspeech.net/archive/2010/07/12/architectural-refactoringhellip.-why-now.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.dotnetspeech.net/comments/commentRss/140896.aspx</wfw:commentRss>
            <trackback:ping>http://blog.dotnetspeech.net/services/trackbacks/140896.aspx</trackback:ping>
        </item>
        <item>
            <title>Architectural &amp;ldquo;Refactoring&amp;rdquo; &amp;ndash; Part 1 of N</title>
            <category>Software Development</category>
            <category>Software Architects Group</category>
            <link>http://blog.dotnetspeech.net/archive/2010/07/12/architectural-ldquorefactoringrdquo-ndash-part-1-of-n.aspx</link>
            <description>&lt;p&gt;I’m in a bit of an odd position, in some ways. CCI brought me on as a “software architect” a little over two years ago. That role wasn’t really defined – in fact, I got to spend several months doing what I felt would be a good use of my time, and then I wrote my own job description. (Perhaps that’s not exactly what other people remember, but it’s sure how things felt to me.)&lt;/p&gt;
&lt;p&gt;Like anything, this approach has benefits and drawbacks. On the plus side, I was empowered to go where the smoke was – to find the areas where I could have a great deal of impact, quickly. (One of my favorite comments of this time comes from &lt;a target="_blank" href="http://msmvps.com/blogs/kathleen/"&gt;Kathleen Dollard&lt;/a&gt;, who recommended I apply at CCI. She told me once that “you’ve had more impact at CCI in the last three months than I thought anyone could in three years – and they haven’t fired you yet!”)&lt;/p&gt;
&lt;p&gt;This was the time-frame in which I was modifying XSLT code generation templates to put repetitious code into a base class, rather than repeating it over and over and over and over and… well, you get the point. They were the days where “minor” changes like this resulted in dropping nearly a &lt;em&gt;million&lt;/em&gt; lines of compiled code through the use of inheritance rather than code generation. (I tease one of our team leads that my job is to remove code faster than his team can write it… and I’m winning.) While this seems like a cool number to quote, the real business value actually didn’t have all that much to do with our code. True, there was a lot less code generated on a nearly-daily frequency. However, what was really valuable to CCI was the fact that &lt;em&gt;the background compiler stopped crashing!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;It turned out that our application was big enough that it taxed the background compiler in the VB IDE just a little bit. Just enough to find a pesky memory fragmentation issue in the background compiler. Just enough to ensure that Visual Studio would die around once per hour for every developer in the company. (For those of you that noticed this problem went away in VS2008 SP1…. you’re welcome! The leadership team at CCI was kind enough to let me ship our code base to Microsoft, where they easily reproduced the problem, and fixed it.)&lt;/p&gt;
&lt;p&gt;These were the good parts of the early days. There were also some pretty rough parts. I mentioned earlier that I’m in an odd position. There are several different roles a software architect can play. One of them is the “gunslinger” or “hit man.” This is the outside consultant who comes in, declares that the architecture is a massive failure, and that everything has to be started anew. Often, this means firing the person that created the old architecture, having the consultant lay out a new one, and then walking away. A bad day for everyone. Lots of resentment, and lots of work scrapped.&lt;/p&gt;
&lt;p&gt;So, what does CCI do? I mean, this is a company that has a 95%+ retention rate, and whose more senior developers have been there a decade or more.&lt;/p&gt;
&lt;p&gt;They hired me. Not as a consultant, but on salary. They kept their corporate knowledge intact, added an opinionated young upstart to the mix, and put me at the desk beside the most senior developer in the company. Then, to heap craziness upon craziness, they invested heavily in “refactoring” the architecture. By heavily, I mean dedicating the development teams to making deep architectural changes for a few &lt;em&gt;weeks&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;And, you know, what? It’s been a great learning experience for everyone… and it’s working. More about that later.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=140895"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=140895" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://blog.dotnetspeech.net/aggbug/140895.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Certain</dc:creator>
            <guid>http://blog.dotnetspeech.net/archive/2010/07/12/architectural-ldquorefactoringrdquo-ndash-part-1-of-n.aspx</guid>
            <pubDate>Tue, 13 Jul 2010 02:13:06 GMT</pubDate>
            <wfw:comment>http://blog.dotnetspeech.net/comments/140895.aspx</wfw:comment>
            <comments>http://blog.dotnetspeech.net/archive/2010/07/12/architectural-ldquorefactoringrdquo-ndash-part-1-of-n.aspx#feedback</comments>
            <wfw:commentRss>http://blog.dotnetspeech.net/comments/commentRss/140895.aspx</wfw:commentRss>
            <trackback:ping>http://blog.dotnetspeech.net/services/trackbacks/140895.aspx</trackback:ping>
        </item>
        <item>
            <title>Agile Like Jazz</title>
            <category>Jazz</category>
            <category>Software Development</category>
            <link>http://blog.dotnetspeech.net/archive/2010/05/26/agile-like-jazz.aspx</link>
            <description>&lt;p&gt;(I’ve been sitting on this for a week or so now, thinking that it needed to be tightened up a bit to make it less rambling. Since that’s clearly not going to happen, reader beware!)&lt;/p&gt;  &lt;p&gt;I had the privilege of spending around 90 minutes last night sitting and listening to Sonny Rollins play a concert at the Disney Center in LA. If you don’t know who Sonny Rollins is, I don’t know how to explain the experience; if you know who he is, I don’t need to.&lt;/p&gt;  &lt;p&gt;Suffice it to say that he has been recording professionally for over 50 years, and helped create an entire genre of music. A true master by any definition. One of the most intriguing aspects of a concert like this, however, is watching the master step aside and let the rest of the musicians play. Not just play their parts, but &lt;em&gt;really&lt;/em&gt; play… letting them take over the spotlight, to strut their stuff, to soak up enthusiastic applause from the crowd.&lt;/p&gt;  &lt;p&gt;Maybe a lot of it has to do with the fact that Sonny Rollins has been doing this for more than a half-century. Maybe it has something to do with a kind of patience you learn when you’re on the far side of 80 – and the man can still blow a mean sax for 90 minutes without stopping! Maybe it has to do with the fact that he was out there for the love of the music and the love of the show, not because he had anything to prove to anyone and, I like to think, not for the money. Perhaps it had more to do with the fact that, when you’re at that level of mastery, the other musicians are going to be &lt;em&gt;good&lt;/em&gt;. Really good.&lt;/p&gt;  &lt;p&gt;Whatever the reasons, there was a incredible freedom on that stage – the ability to improvise, for each musician to showcase their own specialization and skills, and them come back to the common theme, back to being on the same page, as it were. &lt;/p&gt;  &lt;p&gt;All this took place in the same venue that is home to the L.A. Phil. Somehow, I can’t ever see the same kind of free-wheeling improvisation happening in that context.&lt;/p&gt;  &lt;p&gt;And, since I’m a geek, I started thinking about agility. Rollins has put together a quintet that reflects his own particular style and past. No upright bass or piano for Rollins – drums, bongos, electric guitar and bass guitar along with his sax. It’s not about the mix of instruments. Other trios, quartets, and sextets use different mixes of instruments. New Orleans jazz tends towards trombones instead of sax; some prefer cornet or trumpet. But no matter what the choice of instruments, size matters.&lt;/p&gt;  &lt;p&gt;Team sizes are something I’ve been thinking about for a while. We’re on a quest to rethink how our teams are organized. They just feel too big, too unwieldy. In fact, they really don’t feel like teams at all. Most of the time, they feel more like collections or people who happen to report to the same manager. I attribute this to a couple factors. One is over-specialization; we have a tendency to have people work in silos. Although the teams are product-focused, within them our developers are both generalists and specialists. On the one hand, we expect them to be able to build an entire vertical slice of the application; on the other hand, each developer tends to be responsible for the vertical slice. As a result, developers often work on their own piece of the puzzle, in isolation.&lt;/p&gt;  &lt;p&gt;This sort of feels like working on a jigsaw in a group – each person taking a set of colors and piecing them together to reveal a portion of the overall picture. But what inevitably happens when you go to meld all those pieces together? Inevitably, you have some sections that are too big to move easily. These sections end up falling apart under their own weight as you try to move them. Not only that, but there are other challenges – figuring out where that section fits, and how to tie it into the rest of the puzzle. Often, this is when you find a few pieces need to be added – these pieces are “glue,” if you will.&lt;/p&gt;  &lt;p&gt;The other issue that arises is due to the overhead of maintaining communications in a team. My mother, who worked in IT for around 30 years, once told me that 20% per team member is a good rule of thumb for maintaining communication. While this is a rule of thumb, it seems to imply that any team over about 6 people is going to become less agile simple because of the communications burden. Teams of ten or twelve seem like they fall into the philharmonic organizational model. Complicated pieces of music requiring dozens of players to all be on the same page requires a much different model than the jazz quintet. There’s much less room for improvisation, originality or freedom. (There are probably orchestral musicians who will take exception to this characterization; I’m calling it like I see it from the cheap seats.) And, there’s one guy up front who is running the show, whose job is to keep all of those dozens of players on the same page, to facilitate communications.&lt;/p&gt;  &lt;p&gt;Somehow, the orchestral model doesn’t feel much like a self-organizing team, either. The first violin may be the best violinist in the orchestra, but they don’t get to perform free-wheeling solos. I’ve never heard of an orchestra getting together for a jam session. &lt;/p&gt;  &lt;p&gt;But I have heard of teams that organize their work based on the developers available, rather than organizing the developers based on the work required. I have heard of teams where desired functionality is deferred – or worse yet, schedules are missed – because one critical person doesn’t have any bandwidth available. I’ve heard of teams where people simply don’t have the big picture, because there is too much communication overhead for everyone to be aware of everything that is happening on a project.&lt;/p&gt;  &lt;p&gt;I once heard Paul Rayner say something to the effect of “you have a process that is perfectly designed to give you exactly the results you have.” Given a choice, I want a process that’s much more like jazz than orchestral music. I want a process that doesn’t burden me with lots of forms and checkboxes and &lt;em&gt;stuff&lt;/em&gt;. Give me the simplest, most lightweight process that will work – and a smaller team of the best developers I can find. This seems like the kind of process that will get the kind of result I want to be part of.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=140076"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=140076" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://blog.dotnetspeech.net/aggbug/140076.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Certain</dc:creator>
            <guid>http://blog.dotnetspeech.net/archive/2010/05/26/agile-like-jazz.aspx</guid>
            <pubDate>Wed, 26 May 2010 15:03:01 GMT</pubDate>
            <wfw:comment>http://blog.dotnetspeech.net/comments/140076.aspx</wfw:comment>
            <comments>http://blog.dotnetspeech.net/archive/2010/05/26/agile-like-jazz.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.dotnetspeech.net/comments/commentRss/140076.aspx</wfw:commentRss>
            <trackback:ping>http://blog.dotnetspeech.net/services/trackbacks/140076.aspx</trackback:ping>
        </item>
        <item>
            <title>RemoveHandler Issues with Custom Events</title>
            <category>Software Development</category>
            <category>DevCenter</category>
            <category>Tips and Tricks</category>
            <category>VB</category>
            <link>http://blog.dotnetspeech.net/archive/2010/05/04/removehandler-issues-with-custom-events.aspx</link>
            <description>&lt;p&gt;This is a case of things being more complicated that I thought they should be. Since it took a while to figure this one out, I thought it was worth explaining and putting all of the pieces to the answer in one spot.&lt;/p&gt;  &lt;p&gt;Let me set the stage. Architecturally, I have the notion of generic producers and consumers. These put items onto, and remove items from, a queue. This provides a generic, thread-safe mechanism to load balance the creation and processing of work items in our application.&lt;/p&gt;  &lt;p&gt;Part of the IProducer(Of T) interface is:&lt;/p&gt;  &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Interface&lt;/span&gt; IProducer(Of T)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Event&lt;/span&gt; ItemProduced(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; IProducer(Of T), &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; item &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; T)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Event&lt;/span&gt; ProductionComplete(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; IProducer(Of T))&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Interface&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Nothing sinister there, is there? &lt;/p&gt;

&lt;p&gt;In order to simplify our developers’ lives, I wrapped the queue with some functionality to manage the produces and consumers. Since the developer can specify the number of producers and consumers that are spun up, the queue code manages adding event handlers as the producers and consumers are instantiated.&lt;/p&gt;

&lt;p&gt;Now, we’ve been having some memory leaks and, in order to eliminate the possibility that this was caused by weak references to event handles, I wanted to remove them. This is where it got dicey. My first attempt looked like this:&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Each&lt;/span&gt; producer &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; P &lt;span style="color: #0000ff"&gt;In&lt;/span&gt; Producers&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;RemoveHandler&lt;/span&gt; producer.ItemProduced, &lt;span style="color: #0000ff"&gt;AddressOf&lt;/span&gt; ItemProducedHandler&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;RemoveHandler&lt;/span&gt; producer.ProductionComplete, &lt;span style="color: #0000ff"&gt;AddressOf&lt;/span&gt; ProductionCompleteHandler&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;     producer.Dispose()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt; Next&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;What you can’t see in my posted code are the warnings this caused. &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The 'AddressOf' expression has no effect in this context because the method argument to 'AddressOf' requires a relaxed conversion to the delegate type of the event. Assign the 'AddressOf' expression to a variable, and use the variable to add or remove the method as the handler.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, what on earth does that mean? Well, a quick Bing search uncovered a whole bunch of talk about delegates. The first solution I found just changed all parameters in the event handler to Object. Sorry, but no. I used generics precisely because I wanted type safety, not because I wanted to use Object. &lt;/p&gt;

&lt;p&gt;More searching. Eventually, I found &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/2de0bb38-0803-4cbf-b4cc-fe0eaf745587" target="_blank"&gt;this forum post&lt;/a&gt;, where Jeff Shan revealed a missing piece of the puzzle. The other revelation came from Lian_ZA in &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/3c3c2058-3303-4129-ae95-cebb9b639547/" target="_blank"&gt;this post&lt;/a&gt;. However, these two only hinted at the solution. Trying some of what they suggested led to finally getting an invalid cast exception that revealed the existence of ItemProducedEventHandler. &lt;/p&gt;

&lt;p&gt;Hold on a minute! I didn’t create that delegate. There’s nothing even close to that name in my code… except the ItemProduced event in the interface. Could it be? Naaaaah. Hmmm….&lt;/p&gt;

&lt;p&gt;Well, as it turns out, there is a delegate created by the compiler for each event. By explicitly creating a delegate that refers to the method in question, implicitly cast to the generated delegate type, I was able to remove the handlers:&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Each&lt;/span&gt; producer &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; P &lt;span style="color: #0000ff"&gt;In&lt;/span&gt; Producers&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; _itemProducedHandler &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; IProducer(Of T).ItemProducedEventHandler = &lt;span style="color: #0000ff"&gt;AddressOf&lt;/span&gt; ItemProducedHandler&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;RemoveHandler&lt;/span&gt; producer.ItemProduced, _itemProducedHandler&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;  &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; _productionCompleteHandler &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; IProducer(Of T).ProductionCompleteEventHandler = &lt;span style="color: #0000ff"&gt;AddressOf&lt;/span&gt; ProductionCompleteHandler&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;RemoveHandler&lt;/span&gt; producer.ProductionComplete, _productionCompleteHandler&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;     producer.Dispose()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt; Next&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;That’s “all” it took to finally be able to remove the event handlers and maintain type-safe code. Hopefully, this will save you the same challenges I had in trying to figure out how to fix this issue!&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=139667"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=139667" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://blog.dotnetspeech.net/aggbug/139667.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Certain</dc:creator>
            <guid>http://blog.dotnetspeech.net/archive/2010/05/04/removehandler-issues-with-custom-events.aspx</guid>
            <pubDate>Tue, 04 May 2010 17:37:03 GMT</pubDate>
            <wfw:comment>http://blog.dotnetspeech.net/comments/139667.aspx</wfw:comment>
            <comments>http://blog.dotnetspeech.net/archive/2010/05/04/removehandler-issues-with-custom-events.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.dotnetspeech.net/comments/commentRss/139667.aspx</wfw:commentRss>
            <trackback:ping>http://blog.dotnetspeech.net/services/trackbacks/139667.aspx</trackback:ping>
        </item>
        <item>
            <title>IASA ITARC &amp;ndash; Denver May 6th</title>
            <category>Software Development</category>
            <category>User Group Talks</category>
            <link>http://blog.dotnetspeech.net/archive/2010/04/06/iasa-itarc-ndash-denver-may-6th.aspx</link>
            <description>&lt;p&gt;The Denver chapter of the International Association of Software Architects (IASA) is holding an IT Architect Regional Conference (ITARC) in Denver on May 6th.&lt;/p&gt;  &lt;p&gt;The &lt;a href="http://www.iasahome.org/web/itarc/2010/denver" target="_blank"&gt;speaker list&lt;/a&gt; for this conference is amazing. Paul Rayner, Dave McComb, Randy Kahle, Peter Provost, Randy Stafford, George Fairbanks – all great speakers, and from Colorado. Brandon Satrom (who also happens to be the president of the IASA Austin chapter) will also be speaking, as will some other heavy hitters (for example, Ted Farrell, Chief Architect and Senior VP of Oracle). This is an amazing line-up, and the conference is quite reasonably priced ($150 for IASA members until April 10th, including a catered lunch).&lt;/p&gt;  &lt;p&gt;I also have the privilege of being a presenter at this conference. If you’ve ever heard any of the previously named speakers, you know that they set the bar quite high. Sounds like I’m going to have to step up my game.&lt;/p&gt;  &lt;p&gt;What I get to talk about is really cool stuff. The company I work for – Colorado CustomWare – brought me on board nearly two years ago. To say there was some technical debt is somewhat… understated. Equally understated would be that management is committed to doing the right thing. Over the past two years, we’ve done significant architectural refactoring – including an effort that took the entire team offline for most of a month. We’ve reduced the application size by 50% without losing functionality. As you can imagine, this has reduced the complexity of the application, making development faster and less prone to bugs. We’ve made many other changes – moving to an agile process, training developers, moving towards a more OO architecture. The changes we’ve made reveal, in some ways, just how far afield we were.. and there are still more changes to be made.&lt;/p&gt;  &lt;p&gt;Amazingly enough, our leadership team is eager for me to share these experiences with other architects. I’m really looking forward to being able to do so.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=139116"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=139116" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://blog.dotnetspeech.net/aggbug/139116.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Certain</dc:creator>
            <guid>http://blog.dotnetspeech.net/archive/2010/04/06/iasa-itarc-ndash-denver-may-6th.aspx</guid>
            <pubDate>Tue, 06 Apr 2010 18:40:19 GMT</pubDate>
            <wfw:comment>http://blog.dotnetspeech.net/comments/139116.aspx</wfw:comment>
            <comments>http://blog.dotnetspeech.net/archive/2010/04/06/iasa-itarc-ndash-denver-may-6th.aspx#feedback</comments>
            <wfw:commentRss>http://blog.dotnetspeech.net/comments/commentRss/139116.aspx</wfw:commentRss>
            <trackback:ping>http://blog.dotnetspeech.net/services/trackbacks/139116.aspx</trackback:ping>
        </item>
        <item>
            <title>Renewed</title>
            <category>MVP</category>
            <link>http://blog.dotnetspeech.net/archive/2010/04/01/renewed.aspx</link>
            <description>&lt;p&gt;I just got a nice little e-mail from Microsoft. Despite the timing, it’s not an April Fools joke… I’ve been renewed as an MVP for another year.&lt;/p&gt;  &lt;p&gt;Congrats to all the other MVPs being renewed today.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=139035"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=139035" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://blog.dotnetspeech.net/aggbug/139035.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Certain</dc:creator>
            <guid>http://blog.dotnetspeech.net/archive/2010/04/01/renewed.aspx</guid>
            <pubDate>Thu, 01 Apr 2010 18:03:12 GMT</pubDate>
            <wfw:comment>http://blog.dotnetspeech.net/comments/139035.aspx</wfw:comment>
            <comments>http://blog.dotnetspeech.net/archive/2010/04/01/renewed.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blog.dotnetspeech.net/comments/commentRss/139035.aspx</wfw:commentRss>
            <trackback:ping>http://blog.dotnetspeech.net/services/trackbacks/139035.aspx</trackback:ping>
        </item>
    </channel>
</rss>