<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Jimmy Bogard's Blog</title><link>http://lostechies.com/jimmybogard</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/GrabBagOfT" /><description>Strong opinions, weakly held</description><language>en</language><lastBuildDate>Tue, 24 Jan 2012 09:01:48 PST</lastBuildDate><generator>http://wordpress.org/?v=3.1.1</generator><sy:updatePeriod xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">hourly</sy:updatePeriod><sy:updateFrequency xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">1</sy:updateFrequency><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/GrabBagOfT" /><feedburner:info uri="grabbagoft" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><item><title>Speaking at San Diego DNUG tonight</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/iQWRqZ1vNuk/</link><category>Community</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jimmy Bogard</dc:creator><pubDate>Tue, 24 Jan 2012 09:01:48 PST</pubDate><guid isPermaLink="false">http://lostechies.com/jimmybogard/2012/01/24/speaking-at-san-diego-dnug-tonight/</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>If you’re in the San Diego area tonight, I’ll be giving my talk on domain modeling. Details below:</p>
<p><a href="http://www.sandiegodotnet.com/">http://www.sandiegodotnet.com/</a></p>
<p>I’ve been told that there is free pizza. If not, I might be able score some stale bagels from my hotel’s lobby, but no promises there.</p>
<p>Hope to see you there!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=iQWRqZ1vNuk:evRFrsBsAgw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=iQWRqZ1vNuk:evRFrsBsAgw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=iQWRqZ1vNuk:evRFrsBsAgw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=iQWRqZ1vNuk:evRFrsBsAgw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=iQWRqZ1vNuk:evRFrsBsAgw:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/iQWRqZ1vNuk" height="1" width="1"/>]]></content:encoded><description>If you’re in the San Diego area tonight, I’ll be giving my talk on domain modeling. Details below: http://www.sandiegodotnet.com/ I’ve been told that there is free pizza. If not, I might be able score some stale bagels from my hotel’s&amp;#160;&amp;#8230; &lt;a href="http://lostechies.com/jimmybogard/2012/01/24/speaking-at-san-diego-dnug-tonight/"&gt;Continue&amp;#160;reading&amp;#160;&lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://lostechies.com/jimmybogard/2012/01/24/speaking-at-san-diego-dnug-tonight/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://lostechies.com/jimmybogard/2012/01/24/speaking-at-san-diego-dnug-tonight/</feedburner:origLink></item><item><title>CodeMash 2012 wrap up</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/BPMqe4LEiLo/</link><category>Community</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jimmy Bogard</dc:creator><pubDate>Mon, 23 Jan 2012 21:02:43 PST</pubDate><guid isPermaLink="false">http://lostechies.com/jimmybogard/2012/01/24/codemash-2012-wrap-up/</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>This year was my first to attend the bacon debauchery that is <a href="http://codemash.org/">CodeMash</a>. I had been suggested to go by pretty much everyone that I’ve met that has gone, and this year I was fortunate enough to be selected as a speaker.</p>
<p>My talk was on “Crafting Wicked Domain Models” that while was not recorded, all the slides and code can be found on my GitHub:</p>
<p><a href="https://github.com/jbogard/presentations">https://github.com/jbogard/presentations</a></p>
<p>Although that event wasn’t recorded, check out Claudio Lassala’s blog, where he <a href="http://lassala.net/2011/08/25/videos-from-houston-code-camp-2011/">recorded me doing the talk at the Houston Code Camp</a> a couple months before.</p>
<p>A couple of folks came up to me afterwards telling me that they could never code/refactor in front of a Live Studio Audience. But, since the example was straight out of a real project I had lived through, it made going through the code a lot easier.</p>
<p>The questions afterwards were great, too. I always get some discussion around “it’s great and all, but now I have a bunch more classes to deal with”. It’s a fair criticism, and one to keep an eye out for. The way I see it, if the code is more understandable and more representative of real-world concepts, it’s a win. If, however, I’m having a hard time thinking of the names of classes for which I’m building responsibilities around, it’s a bit of a smell that I’m just inventing abstractions.</p>
<p>CodeMash really was a blast. The people were fantastic, the location was great, the food was fantastic, the beer and bacon were plentiful, and as always, the conversations were unforgettable. Hope to see everyone there next year!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=BPMqe4LEiLo:-uHwBvNH6Ck:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=BPMqe4LEiLo:-uHwBvNH6Ck:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=BPMqe4LEiLo:-uHwBvNH6Ck:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=BPMqe4LEiLo:-uHwBvNH6Ck:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=BPMqe4LEiLo:-uHwBvNH6Ck:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/BPMqe4LEiLo" height="1" width="1"/>]]></content:encoded><description>This year was my first to attend the bacon debauchery that is CodeMash. I had been suggested to go by pretty much everyone that I’ve met that has gone, and this year I was fortunate enough to be selected as&amp;#160;&amp;#8230; &lt;a href="http://lostechies.com/jimmybogard/2012/01/24/codemash-2012-wrap-up/"&gt;Continue&amp;#160;reading&amp;#160;&lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://lostechies.com/jimmybogard/2012/01/24/codemash-2012-wrap-up/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><feedburner:origLink>http://lostechies.com/jimmybogard/2012/01/24/codemash-2012-wrap-up/</feedburner:origLink></item><item><title>The grand No Flash experiment (update)</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/anMBubnehZ4/</link><category>Rant</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jimmy Bogard</dc:creator><pubDate>Wed, 18 Jan 2012 05:56:11 PST</pubDate><guid isPermaLink="false">http://lostechies.com/jimmybogard/2012/01/18/the-grand-no-flash-experiment-update/</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>My dislike of Flash has <a href="http://lostechies.com/jimmybogard/2008/01/10/stop-the-flash-insanity/">been</a> <a href="http://lostechies.com/jimmybogard/2008/11/08/boycotting-flash/">well</a> <a href="http://lostechies.com/jimmybogard/2008/11/08/boycotting-flash/">documented</a>, so last month I thought I would try to see what the internet was like <a href="http://lostechies.com/jimmybogard/2011/12/06/a-grand-experiment/">without Flash installed</a>, whatsoever. I removed Flash completely from my system, including any Chrome plugin (Chrome has Flash built in).</p>
<p>I’ve never tried to simply go without Flash. I’ve used FlashBlock and AdBlock to <em>block</em> bad Flash, but for the most part, I couldn’t really tell what sites used Flash or not. I wanted to see how far I could go without Flash.</p>
<p>The final answer: <strong>not very far at all</strong>.</p>
<p>Three sets of websites were difficult or impossible to use:</p>
<ul>
<li>Restaurant websites (who for some reason are determined to make <a href="http://neversaidaboutrestaurantwebsites.tumblr.com/">horrible, horrible sites</a>)</li>
<li>Video streaming sites (YouTube, Vimeo, and other media outlets)</li>
<li>Some food product-related websites</li>
</ul>
<p>I’d put “musical group website” in the list, but I don’t really visit those much. Sites like Tazo.com, while not a restaurant, rely wholly on Flash for the entire “experience”, offering no options whatsoever for non-Flash browsers (like my iPad and iPhone). The answer of course is not “OMG let’s put Flash on mobile devices!!!1”, but to stop making bad websites.</p>
<p>Other sites surprised me with their use of Flash. For example, GitHub uses Flash to perform its “Copy/Paste” code operations (which I guess is only possible/feasible with Flash). Gmail uses Flash for some more advanced file attachment controls, but at least has a fallback option.</p>
<p>Final verdict? <strong>It is not possible (yet) to use the internet without Flash.</strong> Which is unfortunate, because the bulk of my “browsing” these days is on the iPad. It’s so, so annoying to have to switch to a desktop to look up a restaurant’s hours. Unfortunate, and totally unnecessary.</p>
<p>Thankfully, Adobe is forcing the hands of web developers somewhat by discontinuing development of their mobile Flash platform. But we can all do our parts to help rid the world of Flash (for bad uses). If I ever run into a totally Flash-dependent website, I write an email to the webmaster, saying I’m a 56-year-old grandmother who can’t use their website on my iPad and that it’s totally ruined my evening.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=anMBubnehZ4:EFqO7VI6jn8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=anMBubnehZ4:EFqO7VI6jn8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=anMBubnehZ4:EFqO7VI6jn8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=anMBubnehZ4:EFqO7VI6jn8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=anMBubnehZ4:EFqO7VI6jn8:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/anMBubnehZ4" height="1" width="1"/>]]></content:encoded><description>My dislike of Flash has been well documented, so last month I thought I would try to see what the internet was like without Flash installed, whatsoever. I removed Flash completely from my system, including any Chrome plugin (Chrome has&amp;#160;&amp;#8230; &lt;a href="http://lostechies.com/jimmybogard/2012/01/18/the-grand-no-flash-experiment-update/"&gt;Continue&amp;#160;reading&amp;#160;&lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://lostechies.com/jimmybogard/2012/01/18/the-grand-no-flash-experiment-update/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">13</slash:comments><feedburner:origLink>http://lostechies.com/jimmybogard/2012/01/18/the-grand-no-flash-experiment-update/</feedburner:origLink></item><item><title>Formula for project success</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/1SgICUtGDYs/</link><category>Rant</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jimmy Bogard</dc:creator><pubDate>Tue, 03 Jan 2012 05:50:09 PST</pubDate><guid isPermaLink="false">http://lostechies.com/jimmybogard/2012/01/03/formula-for-project-success/</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>In light of <a href="http://lostechies.com/chadmyers/2011/12/30/sweet-sweet-vindication/">recent</a> <a href="http://wekeroad.com/2012/01/03/rails-has-turned-me-into-a-cannibalizing-idiot/">conversations</a> around ActiveRecord and Rails, I thought it might be important to recognize the factors in a project success, in terms of the code produced:</p>
<p><a href="http://lostechies.com/jimmybogard/files/2012/01/image.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lostechies.com/jimmybogard/files/2012/01/image_thumb.png" width="485" height="293"></a></p>
<p>In order for a software project to be successful, two things matter. What you code (the features you choose to develop) and how you code it (what technology you use, how easy it is to change, etc.)</p>
<p>These two constraints balance against each other, and neither is really more important than the other. If you code crap relative to what you need to code, then what you deliver won’t be good. However, it’s also important to recognize what drives what:</p>
<p><a href="http://lostechies.com/jimmybogard/files/2012/01/image1.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lostechies.com/jimmybogard/files/2012/01/image_thumb1.png" width="583" height="135"></a></p>
<p>That is, what ever features/design/scope of what you’re building should drive the architecture/style/technology/patterns of how you code it. Picking the right before the left is putting the cart before the horse. Understand what you’re building, what the vectors of change will be, how large the application will be, how complex in which areas it will be, and let that drive your decisions on what framework/technology/patterns to use.</p>
<p>Once you know HOW to use a technology, the next step is to know WHEN to use that technology, and more importantly, when not to. Clients don’t care about code, but they do care about a bad product. Know what’s important here, and make sure that the code is merely the means (a very important means) to an end.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=1SgICUtGDYs:ArKH3-vd9FE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=1SgICUtGDYs:ArKH3-vd9FE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=1SgICUtGDYs:ArKH3-vd9FE:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=1SgICUtGDYs:ArKH3-vd9FE:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=1SgICUtGDYs:ArKH3-vd9FE:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/1SgICUtGDYs" height="1" width="1"/>]]></content:encoded><description>In light of recent conversations around ActiveRecord and Rails, I thought it might be important to recognize the factors in a project success, in terms of the code produced: In order for a software project to be successful, two things&amp;#160;&amp;#8230; &lt;a href="http://lostechies.com/jimmybogard/2012/01/03/formula-for-project-success/"&gt;Continue&amp;#160;reading&amp;#160;&lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://lostechies.com/jimmybogard/2012/01/03/formula-for-project-success/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">12</slash:comments><feedburner:origLink>http://lostechies.com/jimmybogard/2012/01/03/formula-for-project-success/</feedburner:origLink></item><item><title>Duke Nukem, unhappy marriages, and the Anna Karenina principle</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/KCq0uDDPcbM/</link><category>Uncategorized</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jimmy Bogard</dc:creator><pubDate>Fri, 16 Dec 2011 06:40:14 PST</pubDate><guid isPermaLink="false">http://lostechies.com/jimmybogard/2011/12/16/duke-nukem-unhappy-marriages-and-the-anna-karenina-principle/</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>One of my favorite recent books I’ve read is the tome on human societies, “<a href="http://www.amazon.com/Guns-Germs-Steel-Fates-Societies/dp/0393317552">Guns, Germs, and Steel: The Fates of Human Societies</a>”. In it, there is a section examining domesticable aminals. The author walks through the observation that although there are 148 big wild terrestrial herbivorous mammals, those that could <em>potentially</em> be domesticated, only 14 animals passed the test to actually become domesticated.</p>
<p>The reasons for failure of those other large mammals harks back to the first line of Anna Karenina:</p>
<blockquote><p>Happy families are all alike; every unhappy family is unhappy in its own way.</p>
</blockquote>
<p>While all 14 domesticated animals had common traits on why they were successful, each species that cannot be domesticated fails the test for some unique, specific reason. For example, zebras evidently have a nasty habit of biting people and not letting go.</p>
<p>Looking at software projects and the rates of failure in the industry, I think that there is a very similar phenomena: <strong>Successful projects all have common reasons for success; failed projects each fail in their own unique, spectacular way.</strong></p>
<h3>Duke Nukem and unlimited budgets</h3>
<p>At a No Fluff Just Stuff conference a couple of years back, the keynote speaker shared a story about a failed project. He joined the project a couple of years into the development, and the team had yet to release anything to production. He went on to detail that he was on the project another year and a half, with no production release in sight, and left the project.</p>
<p>This project was one of those legacy re-writes, given pretty much unlimited budget and resources, in hopes that this would produce the best possible replacement for the existing product. The project had budget, resources, executive backing and visibility, technical leadership, support from domain experts etc. etc. <strong>Yet the project was still a colossal failure</strong>. Why? It never released!</p>
<p>Looking at the infamous story of Duke Nukem Forever, I get the same impression. Fresh of the success of Duke Nukem 3D, the software team set out to create the best 3D shooter on the market. This would of course take time and budget. Both of which the team had nearly unlimited resources for. But the technology kept changing and improving underneath their feet, like that line from Alice in Wonderland:</p>
<blockquote><p>It takes all the running you can do, to keep in the same place. If you want to get somewhere else, you must run at least twice as fast as that!</p>
</blockquote>
<p>Clearly something was missing on this project, but it wasn’t anything to do with resources. So what was missing?</p>
<h3>Why projects succeed</h3>
<p>Instead of looking at the myriad of reasons for why a project could fail (I always go back to the <a href="http://www.stevemcconnell.com/rdenum.htm">Classic Mistakes</a> from Steve McConnell), how about we look at successful projects and determine what commonalities these have? If we look at the domesticated animals, they all must possess these six common characteristics:</p>
<ul>
<li>Diet</li>
<li>Growth Rate</li>
<li>Problems of Captive Breeding</li>
<li>Nasty Disposition</li>
<li>Tendency to Panic</li>
<li>Social Structure</li>
</ul>
<p>That is, if any candidate for domestication fails in one of the above categories, it can’t be domesticated.</p>
<p>So how can we distill the common project mistakes into a set of common characteristics? Since they’re grouped in specific categories, we can trace many of these back to specific root causes:</p>
<ul>
<li>Right people for the project needs</li>
<li>Right budget to achieve the project goals</li>
<li>Releasing early and often, or a deadline for delivery</li>
<li>Constant introspection to improve delivery</li>
<li>Alignment between the project sponsor, management, developers and other team members on project’s goals</li>
</ul>
<p>If these look familiar, it’s because they pretty much make up the <a href="http://www.ambysoft.com/essays/brokenTriangle.html">iron triangle of software development</a> from Scott Ambler:</p>
<p><img src="http://www.ambysoft.com/artwork/ironTriangle.jpg"></p>
<p>Going in to a project, the entire team from executives to developers need to agree on the parameters of the Scope, Resources, and Schedule, and constantly introspect to make sure that the team constantly improves its ability to deliver.</p>
<p>I know I’m probably missing something here, but it seems that all the other project mistakes seem to stem out of a deficiency around:</p>
<ul>
<li>Scope</li>
<li>Resources</li>
<li>Schedule</li>
<li>Alignment</li>
<li>Continuous Improvement</li>
</ul>
<p>A project can succeed despite any of the Classic Mistakes, but lack of any of the above characteristics seems to doom a project to failure.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=KCq0uDDPcbM:mtiEWEWdcqk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=KCq0uDDPcbM:mtiEWEWdcqk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=KCq0uDDPcbM:mtiEWEWdcqk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=KCq0uDDPcbM:mtiEWEWdcqk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=KCq0uDDPcbM:mtiEWEWdcqk:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/KCq0uDDPcbM" height="1" width="1"/>]]></content:encoded><description>One of my favorite recent books I’ve read is the tome on human societies, “Guns, Germs, and Steel: The Fates of Human Societies”. In it, there is a section examining domesticable aminals. The author walks through the observation that although&amp;#160;&amp;#8230; &lt;a href="http://lostechies.com/jimmybogard/2011/12/16/duke-nukem-unhappy-marriages-and-the-anna-karenina-principle/"&gt;Continue&amp;#160;reading&amp;#160;&lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://lostechies.com/jimmybogard/2011/12/16/duke-nukem-unhappy-marriages-and-the-anna-karenina-principle/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">6</slash:comments><feedburner:origLink>http://lostechies.com/jimmybogard/2011/12/16/duke-nukem-unhappy-marriages-and-the-anna-karenina-principle/</feedburner:origLink></item><item><title>Is ThreadStatic a leaky abstraction?</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/85wHX-719ls/</link><category>Dependency Injection</category><category>Design</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jimmy Bogard</dc:creator><pubDate>Wed, 07 Dec 2011 06:54:20 PST</pubDate><guid isPermaLink="false">http://lostechies.com/jimmybogard/2011/12/07/is-threadstatic-a-leaky-abstraction/</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Reading Ayende’s post on <a href="http://ayende.com/blog/143361/rhino-service-bus-amp-ravendb-integration">integrating Rhino Service Bus and RavenDB</a>, one thing that caught my eye was the use of the <a href="http://msdn.microsoft.com/en-us/library/system.threadstaticattribute.aspx">ThreadStatic attribute</a> to control the lifecycle of a private field:</p>
<div id="gist-1443003" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">public</span> <span class="k">class</span> <span class="nc">RavenDbMessageModule</span> <span class="p">:</span> <span class="n">IMessageModule</span></div><div class='line' id='LC2'><span class="p">{</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">private</span> <span class="k">readonly</span> <span class="n">IDocumentStore</span> <span class="n">documentStore</span><span class="p">;</span></div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="na">    [ThreadStatic]</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">private</span> <span class="k">static</span> <span class="n">IDocumentSession</span> <span class="n">currentSession</span><span class="p">;</span></div><div class='line' id='LC7'><br/></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">public</span> <span class="k">static</span> <span class="n">IDocumentSession</span> <span class="n">CurrentSession</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">{</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="n">currentSession</span><span class="p">;</span> <span class="p">}</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC12'><br/></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">public</span> <span class="nf">RavenDbMessageModule</span><span class="p">(</span><span class="n">IDocumentStore</span> <span class="n">documentStore</span><span class="p">)</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">{</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="p">.</span><span class="n">documentStore</span> <span class="p">=</span> <span class="n">documentStore</span><span class="p">;</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC17'><br/></div><div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">public</span> <span class="k">void</span> <span class="nf">Init</span><span class="p">(</span><span class="n">ITransport</span> <span class="n">transport</span><span class="p">,</span> <span class="n">IServiceBus</span> <span class="n">serviceBus</span><span class="p">)</span></div><div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">{</span></div><div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">transport</span><span class="p">.</span><span class="n">MessageArrived</span> <span class="p">+=</span> <span class="n">TransportOnMessageArrived</span><span class="p">;</span></div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">transport</span><span class="p">.</span><span class="n">MessageProcessingCompleted</span> <span class="p">+=</span> <span class="n">TransportOnMessageProcessingCompleted</span><span class="p">;</span></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC23'><br/></div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">public</span> <span class="k">void</span> <span class="nf">Stop</span><span class="p">(</span><span class="n">ITransport</span> <span class="n">transport</span><span class="p">,</span> <span class="n">IServiceBus</span> <span class="n">serviceBus</span><span class="p">)</span></div><div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">{</span></div><div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">transport</span><span class="p">.</span><span class="n">MessageArrived</span> <span class="p">-=</span> <span class="n">TransportOnMessageArrived</span><span class="p">;</span></div><div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">transport</span><span class="p">.</span><span class="n">MessageProcessingCompleted</span> <span class="p">-=</span> <span class="n">TransportOnMessageProcessingCompleted</span><span class="p">;</span></div><div class='line' id='LC28'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC29'><br/></div><div class='line' id='LC30'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">private</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">TransportOnMessageProcessingCompleted</span><span class="p">(</span><span class="n">CurrentMessageInformation</span> <span class="n">currentMessageInformation</span><span class="p">,</span> <span class="n">Exception</span> <span class="n">exception</span><span class="p">)</span></div><div class='line' id='LC31'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">{</span></div><div class='line' id='LC32'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="n">currentSession</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span></div><div class='line' id='LC33'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">{</span></div><div class='line' id='LC34'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="n">exception</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span></div><div class='line' id='LC35'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">currentSession</span><span class="p">.</span><span class="n">SaveChanges</span><span class="p">();</span></div><div class='line' id='LC36'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">currentSession</span><span class="p">.</span><span class="n">Dispose</span><span class="p">();</span></div><div class='line' id='LC37'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC38'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">currentSession</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span></div><div class='line' id='LC39'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC40'><br/></div><div class='line' id='LC41'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">private</span> <span class="kt">bool</span> <span class="nf">TransportOnMessageArrived</span><span class="p">(</span><span class="n">CurrentMessageInformation</span> <span class="n">currentMessageInformation</span><span class="p">)</span></div><div class='line' id='LC42'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">{</span></div><div class='line' id='LC43'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="n">currentSession</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span></div><div class='line' id='LC44'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">currentSession</span> <span class="p">=</span> <span class="n">documentStore</span><span class="p">.</span><span class="n">OpenSession</span><span class="p">();</span></div><div class='line' id='LC45'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="k">false</span><span class="p">;</span></div><div class='line' id='LC46'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC47'><span class="p">}</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1443003/37bacb6628d0845c1a5d610a9e2dd0a62284195b/RavenDbMessageModule.cs" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1443003#file_raven_db_message_module.cs" style="float:right;margin-right:10px;color:#666">RavenDbMessageModule.cs</a>
            <a href="https://gist.github.com/1443003">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>One of the things that really bothers me about an implementation like this is that intimate knowledge of the threading model of Rhino Service Bus is required to properly implement an IMessageModule implementation properly. The CurrentSession property is static, yet the IDocumentStore member is an instance field. Why does an implementer of a message module need to be concerned about lifecycle of its dependencies?</p>
<p>I don’t really think it should – lifecycle of a dependency should at most be the responsibility of the dependency itself. Or even better, the responsibility of the container. Dependencies shouldn’t care <em>where</em> they are used, because that knowledge would violate the whole “D” in SOLID.</p>
<p>Instead, I’d much rather see something like <a href="http://mvc.fubu-project.org/">FubuMVC</a> behaviors. Here’s one with NHibernate to have a session always part of a request there:</p>
<p><div id="gist-1443059" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">public</span> <span class="k">class</span> <span class="nc">SimpleUnitOfWorkBehaviour</span> <span class="p">:</span> <span class="n">IActionBehavior</span></div><div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">{</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">readonly</span> <span class="n">IFubuRequest</span> <span class="n">_fubuRequest</span><span class="p">;</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">readonly</span> <span class="n">ISessionFactory</span> <span class="n">_sessionFactory</span><span class="p">;</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">ISession</span> <span class="n">_session</span><span class="p">;</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">public</span> <span class="n">IActionBehavior</span> <span class="n">InnerBehavior</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">public</span> <span class="nf">SimpleUnitOfWorkBehaviour</span><span class="p">(</span><span class="n">ISessionFactory</span> <span class="n">sessionFactory</span><span class="p">,</span> </div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">IFubuRequest</span> <span class="n">fubuRequest</span><span class="p">)</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">{</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">_sessionFactory</span> <span class="p">=</span> <span class="n">sessionFactory</span><span class="p">;</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">_fubuRequest</span> <span class="p">=</span> <span class="n">fubuRequest</span><span class="p">;</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC15'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1443059/b0b00db7fdebecfee38c7145c8cfecfeff12e012/FubuUnitOfWork.cs" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1443059#file_fubu_unit_of_work.cs" style="float:right;margin-right:10px;color:#666">FubuUnitOfWork.cs</a>
            <a href="https://gist.github.com/1443059">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>Note that the behavior doesn’t care about the lifecycle of itself. That’s completely managed by the FubuMVC infrastructure, it’s completely unimportant to the implementor. Then when it comes time to actually <em>create</em> a session, it looks like:</p>
<p><div id="gist-1443065" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">public</span> <span class="k">void</span> <span class="nf">Invoke</span><span class="p">()</span></div><div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">{</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">_fubuRequest</span><span class="p">.</span><span class="n">Set</span><span class="p">(</span><span class="k">new</span> <span class="n">Lazy</span><span class="p">&lt;</span><span class="n">ISession</span><span class="p">&gt;(()</span> <span class="p">=&gt;</span> </div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">_session</span> <span class="p">??</span> <span class="p">(</span><span class="n">_session</span> <span class="p">=</span> <span class="n">CreateTransactionalSession</span><span class="p">())));</span></div><div class='line' id='LC5'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1443065/22fd9e5910e6c794fca0898d7011f50a44421ec2/Invoke.cs" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1443065#file_invoke.cs" style="float:right;margin-right:10px;color:#666">Invoke.cs</a>
            <a href="https://gist.github.com/1443065">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>In the code above, the behavior chain sets a contextual dependency on the IFubuRequest, which, through the magic of child and nested containers, ensures that subsequent behaviors in the execution pipeline have the correct injected ISession from NHibernate. Nowhere in this code do you see any sort of lifecycle management.</p>
<p>The most you see is things like Lazy and in code that uses the dependency, perhaps a lazy Func&lt;T&gt;. But these are only in place because consumers want to direct the scope, not lifecycle.</p>
<p>Lifecycle of dependencies is best served in the framework. Barring that, the container configuration. Consumers and dependencies do not need to change their design to accommodate the lifecycle constraints of the hosted environment. Pushing that into these pieces leaks the abstraction of the hosting environment.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=85wHX-719ls:IjQSQafnwos:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=85wHX-719ls:IjQSQafnwos:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=85wHX-719ls:IjQSQafnwos:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=85wHX-719ls:IjQSQafnwos:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=85wHX-719ls:IjQSQafnwos:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/85wHX-719ls" height="1" width="1"/>]]></content:encoded><description>Reading Ayende’s post on integrating Rhino Service Bus and RavenDB, one thing that caught my eye was the use of the ThreadStatic attribute to control the lifecycle of a private field: One of the things that really bothers me about&amp;#160;&amp;#8230; &lt;a href="http://lostechies.com/jimmybogard/2011/12/07/is-threadstatic-a-leaky-abstraction/"&gt;Continue&amp;#160;reading&amp;#160;&lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://lostechies.com/jimmybogard/2011/12/07/is-threadstatic-a-leaky-abstraction/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">4</slash:comments><feedburner:origLink>http://lostechies.com/jimmybogard/2011/12/07/is-threadstatic-a-leaky-abstraction/</feedburner:origLink></item><item><title>A grand experiment</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/DDsnJN1qq3M/</link><category>Rant</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jimmy Bogard</dc:creator><pubDate>Tue, 06 Dec 2011 06:37:28 PST</pubDate><guid isPermaLink="false">http://lostechies.com/jimmybogard/2011/12/06/a-grand-experiment/</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Flash has crashed for the (hopefully) last time. I’m going to run a little experiment. <strong>I’m uninstalling Flash</strong> and see how much it affects browsing experience for say, one month.</p>
<p>I suspect that most experiences will be fine on Chrome, except for poorly designed websites who force you to browse information through Flash. For legitimate uses of Flash, like video streaming, I don’t really know who does or does not support Flash yet.</p>
<p>I’ll report back in a month with the results. Or less if you really can’t use the web without Flash anymore.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=DDsnJN1qq3M:3lOCRwXpKEs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=DDsnJN1qq3M:3lOCRwXpKEs:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=DDsnJN1qq3M:3lOCRwXpKEs:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=DDsnJN1qq3M:3lOCRwXpKEs:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=DDsnJN1qq3M:3lOCRwXpKEs:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/DDsnJN1qq3M" height="1" width="1"/>]]></content:encoded><description>Flash has crashed for the (hopefully) last time. I’m going to run a little experiment. I’m uninstalling Flash and see how much it affects browsing experience for say, one month. I suspect that most experiences will be fine on Chrome,&amp;#160;&amp;#8230; &lt;a href="http://lostechies.com/jimmybogard/2011/12/06/a-grand-experiment/"&gt;Continue&amp;#160;reading&amp;#160;&lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://lostechies.com/jimmybogard/2011/12/06/a-grand-experiment/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">11</slash:comments><feedburner:origLink>http://lostechies.com/jimmybogard/2011/12/06/a-grand-experiment/</feedburner:origLink></item><item><title>The value of certifications</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/rlycFRjTDZs/</link><category>People</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jimmy Bogard</dc:creator><pubDate>Tue, 29 Nov 2011 14:37:25 PST</pubDate><guid isPermaLink="false">http://lostechies.com/jimmybogard/2011/11/29/the-value-of-certifications/</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>Reading <a href="http://davybrion.com/blog/">Davy Brion’s</a> post on <a href="http://davybrion.com/blog/2011/11/does-certification-have-any-value/">Does Certification Have Any Value?</a>, he provides a common answer:</p>
<blockquote><p>Someone asked which certificate would be the better choice on Twitter today: Microsoft Certified Professional or Certified Scrum Master. My answer was very simple: neither because they&#8217;re both utterly worthless.</p>
</blockquote>
<p>That’s a very common answer to those looking at the point of view from those taking the exams as a means of proving they’ve learned something. In that light, things like Certified Scrum Master and Microsoft Certified Professional are useless. They don’t provide any indication whatsoever that the person holding the certification is able to actually <em>apply</em> those skills in the real world.</p>
<p>In fact, <strong>if someone comes to me using certification as a substitute for examples of experience, it pretty much guarantees that experience will be lacking but bravado will be abundant.</strong></p>
<p>So if you’re wanting to use certifications as a means of learning – don’t, it’s a waste of time. If you’re wanting to use certifications as a means of gaining credibility – you can, but be aware that those that give you credibility because of a certification are likely clueless.</p>
<p>So do certifications hold no value?</p>
<p>No, there is value in some contexts. Clueless or not, sometimes the illusion of credibility from a certification is better than the alternative for some folks. For example, we often meet clients thinking they need Agile advice, but once we start talking to them, it becomes clear that we can help them in other ways.</p>
<p>However, a certification might be a foot-in-the-door to start a conversation that we would otherwise be eliminated. It’s not being disingenuous – it’s recognizing that we have to understand biases and work with them rather than pretend/hope they don’t exist.</p>
<p>Certifications, in some organizations, have currency beyond the illusion of expertise. This could be in the form of currency for promotions, or special deals with vendors (like the Microsoft Partner program was the last time I was involved with it).</p>
<p>Having a certification gets you points that puts you in “Gold” status that gets lower licensing fees. Basically, certification is a coupon for lower prices. It’s a sacrifice employees make for the good of the whole.</p>
<p>Otherwise, yes, don’t waste your time or money. <strong>Don’t worry about the worth of the certification, decide if the process of getting certified holds any value.</strong></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=rlycFRjTDZs:qcRryDT6KUc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=rlycFRjTDZs:qcRryDT6KUc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=rlycFRjTDZs:qcRryDT6KUc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=rlycFRjTDZs:qcRryDT6KUc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=rlycFRjTDZs:qcRryDT6KUc:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/rlycFRjTDZs" height="1" width="1"/>]]></content:encoded><description>Reading Davy Brion’s post on Does Certification Have Any Value?, he provides a common answer: Someone asked which certificate would be the better choice on Twitter today: Microsoft Certified Professional or Certified Scrum Master. My answer was very simple: neither&amp;#160;&amp;#8230; &lt;a href="http://lostechies.com/jimmybogard/2011/11/29/the-value-of-certifications/"&gt;Continue&amp;#160;reading&amp;#160;&lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://lostechies.com/jimmybogard/2011/11/29/the-value-of-certifications/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">15</slash:comments><feedburner:origLink>http://lostechies.com/jimmybogard/2011/11/29/the-value-of-certifications/</feedburner:origLink></item><item><title>Dealing with transactions</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/h9EXhuxdtXc/</link><category>Architecture</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jimmy Bogard</dc:creator><pubDate>Mon, 28 Nov 2011 09:05:42 PST</pubDate><guid isPermaLink="false">http://lostechies.com/jimmybogard/?p=559</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>In the <a href="http://lostechies.com/jimmybogard/2011/11/22/stop-premature-email-sending-with-nservicebus/">last post on NServiceBus</a>, I got quite a few comments that one way to fix the problem of dealing with non-transactional operations that must happen if some transaction succeeds is to simply move the non-transactional operation after the transactional one, so that I know that the transaction succeeds. If we delay the sending of an email until <em>after</em> the transaction succeeds, our picture now looks like this:</p>
<p><a href="http://lostechies.com/jimmybogard/files/2011/11/image3.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lostechies.com/jimmybogard/files/2011/11/image_thumb3.png" width="575" height="321"></a></p>
<p>The steps are slightly altered so that the Commit happens before Send. If step 2 fails, step 3 never happens. I see a couple of problems with this approach, namely in that it assumes:</p>
<ol>
<li>I have explicit control over when transactions happen</li>
<li>I <em>want</em> explicit control over when transactions happen</li>
</ol>
<p>If #1 is true, I have to wonder if #2 is also desirable. In most cases I run into, I don’t want explicit control over transactions. I don’t want to think about them, or mess with them, or deal with them. I want these to just happen without me having to do any work.</p>
<p>I instead like the idea of a unit of work, or at the very least, a concept of <a href="http://ayende.com/blog/136193/the-required-infrastructure-frees-you-from-infrastructure-decisions">required infrastructure</a> for transaction management. Regardless of the host environment I’m working with, WCF, WPF, ASP.NET, NServiceBus etc., my day to day development takes on a picture like this:</p>
<p><a href="http://lostechies.com/jimmybogard/files/2011/11/image4.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lostechies.com/jimmybogard/files/2011/11/image_thumb4.png" width="607" height="400"></a></p>
<p>Day to day, I’m living in the green section. I don’t want to “remember” to create transactions, deal with a pattern of saving, committing, rolling back etc. This should just be taken care of for me, through required infrastructure. One example is in Ayende’s example of the RavenController in MVC:</p>
<div id="gist-1401053" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">using</span> <span class="nn">System</span><span class="p">;</span></div><div class='line' id='LC2'><span class="k">using</span> <span class="nn">System.Web.Mvc</span><span class="p">;</span></div><div class='line' id='LC3'><span class="k">using</span> <span class="nn">Raven.Client</span><span class="p">;</span></div><div class='line' id='LC4'><span class="k">using</span> <span class="nn">TekPub.Profiler.BackOffice.Tasks</span><span class="p">;</span></div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'><span class="k">namespace</span> <span class="nn">TekPub.Profiler.BackOffice.Controllers</span></div><div class='line' id='LC7'><span class="p">{</span></div><div class='line' id='LC8'>	<span class="k">public</span> <span class="k">class</span> <span class="nc">RavenController</span> <span class="p">:</span> <span class="n">Controller</span></div><div class='line' id='LC9'>	<span class="p">{</span></div><div class='line' id='LC10'>		<span class="k">protected</span> <span class="n">IDocumentSession</span> <span class="n">documentSession</span><span class="p">;</span></div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'>		<span class="k">protected</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">OnActionExecuting</span><span class="p">(</span><span class="n">ActionExecutingContext</span> <span class="n">filterContext</span><span class="p">)</span></div><div class='line' id='LC13'>		<span class="p">{</span></div><div class='line' id='LC14'>			<span class="n">documentSession</span> <span class="p">=</span> <span class="n">MvcApplication</span><span class="p">.</span><span class="n">DocumentStore</span><span class="p">.</span><span class="n">OpenSession</span><span class="p">();</span></div><div class='line' id='LC15'>		<span class="p">}</span></div><div class='line' id='LC16'><br/></div><div class='line' id='LC17'>		<span class="k">protected</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">OnActionExecuted</span><span class="p">(</span><span class="n">ActionExecutedContext</span> <span class="n">filterContext</span><span class="p">)</span></div><div class='line' id='LC18'>		<span class="p">{</span></div><div class='line' id='LC19'>			<span class="k">try</span></div><div class='line' id='LC20'>			<span class="p">{</span></div><div class='line' id='LC21'>				<span class="n">using</span><span class="p">(</span><span class="n">documentSession</span><span class="p">)</span></div><div class='line' id='LC22'>				<span class="p">{</span></div><div class='line' id='LC23'>					<span class="k">if</span><span class="p">(</span><span class="n">filterContext</span><span class="p">.</span><span class="n">Exception</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span></div><div class='line' id='LC24'>					<span class="p">{</span></div><div class='line' id='LC25'>						<span class="n">documentSession</span><span class="p">.</span><span class="n">SaveChanges</span><span class="p">();</span></div><div class='line' id='LC26'>						<span class="n">TaskExecuter</span><span class="p">.</span><span class="n">StartExecuting</span><span class="p">();</span></div><div class='line' id='LC27'>					<span class="p">}</span></div><div class='line' id='LC28'>				<span class="p">}</span></div><div class='line' id='LC29'>			<span class="p">}</span></div><div class='line' id='LC30'>			<span class="k">finally</span></div><div class='line' id='LC31'>			<span class="p">{</span></div><div class='line' id='LC32'>				<span class="n">TaskExecuter</span><span class="p">.</span><span class="n">Discard</span><span class="p">();</span></div><div class='line' id='LC33'>			<span class="p">}</span></div><div class='line' id='LC34'>		<span class="p">}</span></div><div class='line' id='LC35'>	<span class="p">}</span></div><div class='line' id='LC36'><span class="p">}</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1401053/67d13377d47a8fe38c15600baa2aa14bbb4325cc/RavenController.cs" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1401053#file_raven_controller.cs" style="float:right;margin-right:10px;color:#666">RavenController.cs</a>
            <a href="https://gist.github.com/1401053">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>On every request, a Raven session is opened, and everything saved at the end of the request. All developers have to do to make sure that transactions are used properly is simply inherit from this controller.</p>
<p>With every application framework I look at, one of the first items I put in is the concept of implicit contextual transactions. The scope of what code I’m working with naturally fits inside a transaction, so it’s not something I want to have to worry about.</p>
<p>If I have to remember to call Commit on a transaction every time I introduce new data manipulation code, that’s just something I’m going to forget to do. Instead, transactions and unit of work management should wrap around my normal application code, without me needing to do anything to manage it.</p>
<p>In the next post, I’ll look at various alternatives to messaging for doing something non-transactional like sending emails (or calling web services), and examine the benefits and drawbacks of each approach.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=h9EXhuxdtXc:-qgxY2i6JSA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=h9EXhuxdtXc:-qgxY2i6JSA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=h9EXhuxdtXc:-qgxY2i6JSA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=h9EXhuxdtXc:-qgxY2i6JSA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=h9EXhuxdtXc:-qgxY2i6JSA:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/h9EXhuxdtXc" height="1" width="1"/>]]></content:encoded><description>In the last post on NServiceBus, I got quite a few comments that one way to fix the problem of dealing with non-transactional operations that must happen if some transaction succeeds is to simply move the non-transactional operation after the&amp;#160;&amp;#8230; &lt;a href="http://lostechies.com/jimmybogard/2011/11/28/dealing-with-transactions/"&gt;Continue&amp;#160;reading&amp;#160;&lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://lostechies.com/jimmybogard/2011/11/28/dealing-with-transactions/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">9</slash:comments><feedburner:origLink>http://lostechies.com/jimmybogard/2011/11/28/dealing-with-transactions/</feedburner:origLink></item><item><title>Stop premature email sending with NServiceBus</title><link>http://feedproxy.google.com/~r/GrabBagOfT/~3/j3LLLGdRzvQ/</link><category>NServiceBus</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jimmy Bogard</dc:creator><pubDate>Tue, 22 Nov 2011 10:53:20 PST</pubDate><guid isPermaLink="false">http://lostechies.com/jimmybogard/2011/11/22/stop-premature-email-sending-with-nservicebus/</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<p>We use NServiceBus quite a lot to manage integration points where the other side isn’t transactional and we need to “shore up the process” of communicating with external services. One integration point we often don’t think about in terms of an integration point is the sending of an email.</p>
<p>Often times, you’ll see some sort of process that needs to notify someone that the job is complete via email. It’ll look something like:
<pre class="code"><span style="color: blue">public void </span>SomeServiceCall()
{
    DoSomeWorkHere();
    CreateSomeObjects();

    SaveToADatabase();

    <span style="color: blue">var </span>message = <span style="color: blue">new </span><span style="color: #2b91af">MailMessage</span>();
    <span style="color: blue">var </span>client = <span style="color: blue">new </span><span style="color: #2b91af">SmtpClient</span>();
    client.Send(message);
}
</pre>
<p>This is all fine and dandy, but the problem comes when something like this is executed inside a transaction. We expect that if the SomeServiceCall method is wrapped in a transaction, that the database save should roll back. But what about that email? It often won’t fail until the transaction commits, which is AFTER the email is sent:</p>
<p><a href="http://lostechies.com/jimmybogard/files/2011/11/image.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lostechies.com/jimmybogard/files/2011/11/image_thumb.png" width="575" height="321"></a></p>
<p>In the picture above, we can see that the transaction only involves the database, but we can’t un-send our email.</p>
<p>What we need to do here is decouple the actual sending of an email with the message to indicate an email needs to be sent. Right now, we’re using a synchronous, non-transactional mechanism of sending an email. Instead, we just need to wrap that interaction point with an NServiceBus message:
<pre class="code"><span style="color: blue">public void </span>SomeServiceCall()
{
    DoSomeWorkHere();
    CreateSomeObjects();

    SaveToADatabase();

    _bus.Send(<span style="color: blue">new </span><span style="color: #2b91af">SendEmailMessage</span>());
}
</pre>
<p>We’re using the NServiceBus bus to send a message that we want to send an email. The nice thing about this picture is that the sending of that NServiceBus message now participates in the transaction:</p>
<p><a href="http://lostechies.com/jimmybogard/files/2011/11/image1.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lostechies.com/jimmybogard/files/2011/11/image_thumb1.png" width="575" height="324"></a></p>
<p>In the case of failure, that message never makes it over to my NServiceBus host. If it does succeed:</p>
<p><a href="http://lostechies.com/jimmybogard/files/2011/11/image2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lostechies.com/jimmybogard/files/2011/11/image_thumb2.png" width="575" height="335"></a></p>
<p>Then my message is delivered to the SMTP NServiceBus host, which will then interact with the SMTP server.</p>
<p>By decoupling the action of sending an email with the intention through an NServiceBus message, I can make sure that the email isn’t sent unless I successfully complete the transaction.</p>
<p>Another nice benefit here is that I was originally synchronously sending an email. With this architecture, if the SMTP server goes down, it doesn’t affect the ability of My Service to stay up. Instead, the durable messaging of MSMQ and NServiceBus reliability mechanisms ensures that I don’t lose the messages of sending those emails.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=j3LLLGdRzvQ:w3eh9N-8t5I:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=j3LLLGdRzvQ:w3eh9N-8t5I:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=j3LLLGdRzvQ:w3eh9N-8t5I:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/GrabBagOfT?a=j3LLLGdRzvQ:w3eh9N-8t5I:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/GrabBagOfT?i=j3LLLGdRzvQ:w3eh9N-8t5I:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/GrabBagOfT/~4/j3LLLGdRzvQ" height="1" width="1"/>]]></content:encoded><description>We use NServiceBus quite a lot to manage integration points where the other side isn’t transactional and we need to “shore up the process” of communicating with external services. One integration point we often don’t think about in terms of&amp;#160;&amp;#8230; &lt;a href="http://lostechies.com/jimmybogard/2011/11/22/stop-premature-email-sending-with-nservicebus/"&gt;Continue&amp;#160;reading&amp;#160;&lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://lostechies.com/jimmybogard/2011/11/22/stop-premature-email-sending-with-nservicebus/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">25</slash:comments><feedburner:origLink>http://lostechies.com/jimmybogard/2011/11/22/stop-premature-email-sending-with-nservicebus/</feedburner:origLink></item></channel></rss>

