<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5808375369110654128</id><updated>2012-01-30T14:57:03.005-08:00</updated><category term='London'/><title type='text'>Dare to dream</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>64</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-9203149791149478662</id><published>2012-01-30T14:32:00.000-08:00</published><updated>2012-01-30T14:32:54.343-08:00</updated><title type='text'>Tough Guy 2012</title><content type='html'>Grueling is perhaps the only term that can be adequately used to define the Tough Guy. &amp;nbsp;In a way, one might liken it to running a half-marathon in that no one thing was hard persai, but taken as a whole, the ToughGuy had a way of draining away at you.&lt;br /&gt;&lt;br /&gt;The whole adventure started late last year. &amp;nbsp;Barry, a colleague of mine, suggested that we consider competing in the ToughGuy race in January. &amp;nbsp;Being somewhat thick headed &amp;amp; without really considering the race itself, I thought it looked cool and signed up. &amp;nbsp;Little did I consider how "cool" it would actually turn out to be. &amp;nbsp;The race itself is a 6 mile cross country run followed by an army assault course. As one competitor said to me, "A walk in the park" to which I replied "A really muddy park."&lt;br /&gt;&lt;br /&gt;My training for the event was half-hearted to say the least, niggling injuries, traveling, work stress and illness all somewhat colluded to give me good excuses for skimping on my running. &amp;nbsp;Fortunately for me, I was never really worried about the running part of the race. &amp;nbsp;I'm certain that my lack of training gave poor Laura a bit of added stress over the whole event, but I was still confident in my ability to succeed. &amp;nbsp;During my preparations I ran 10km on several occasions and even jumped into the local canal to test my clothing choices. &amp;nbsp;I will say right now that the local canal in London was MUCH warmer than the water we ended up running through.&lt;br /&gt;&lt;br /&gt;As the day approached, Laura and my Dad both, bless their hearts, started stressing out about my safety and ensured that I was well&amp;nbsp;acquainted&amp;nbsp;with all the horror stories that other people had filled the internet with. &amp;nbsp;Thanks guys :-) There was nothing stopping me though!&lt;br /&gt;&lt;br /&gt;On the morning of the race I met up with Barry and his friend Peter and we made our way to the start. &amp;nbsp;They had paid some extra money so ended up starting about 5 - 10 minutes ahead of me. &amp;nbsp;The starting area was populated with people of all forms of preparedness, some mostly naked some fully covered in triathlon wetsuits. &amp;nbsp; I swear I even saw Jesus running around. &amp;nbsp;The anticipation for the event was mostly filled with watching a rugby ball getting kicked around the starting area and nervous chatter. &amp;nbsp;A large roar saw the competitors off and a few minutes after the first were off, I started my ToughGuy Challenge.&lt;br /&gt;&lt;br /&gt;It didn't take long for the sadistic nature of the course setters to become known. &amp;nbsp;My original expectation had been for a nice easy run through the country side followed by the assault course... dashed on the first hurdle. &amp;nbsp;Well I will say that it wasn't that hard, but we did have to negotiate several (5?) mud filled ditches and I often pushed competitors up from behind to both assist them and move them faster. &amp;nbsp;I did get a few well meaning boosts myself, everybody was willing to help each other.&lt;br /&gt;&lt;br /&gt;More obstacles and surprises followed but perhaps my least favorite part was running up and down a hill 8 times. &amp;nbsp;Unfortunately I was in a massive crowd of people and ended up walking up most of the hills. &amp;nbsp;I say unfortunately but I was secretly happy... I caught up with Barry &amp;amp; Peter as they were negotiating the forest nets and passed the crowds to them when we started the Jungle Slalom. &amp;nbsp;A series of about 10 zigzags through a muddy river with steep banks, again a good deal ass pushing and arm pulling brought us through these. &amp;nbsp;The best part of the course was coming up!&lt;br /&gt;&lt;br /&gt;The army assault course was quite a beast, a load of climbing, wading through gradually deepening water and some tricky rope work threatened to derail the best prepared ToughGuys, but not me! &amp;nbsp;Laura, Simon &amp;amp; Melanie kept my spirits up as I leapt through fire and slipped and slided my way through the muck. &amp;nbsp;The three toughest parts of the assault would have been 1) The Torture Chambers - a crawl through electric wires dangling from the ceiling with approximately 7000 volts of jolt followed by a narrow pipe crawl. &amp;nbsp;Did I mention it was dark? 2) Being forced to go wade up to my neck, then go underwater to pass some partially submerged logs, and following that with a nice climb up a 40ft structure. &amp;nbsp;I'm fairly certain my smile disappeared briefly after submerging my head. 3) &amp;nbsp;The barbed wire crawl at the end, as sad as it may sound, I didn't want to ruin my shirt and I was dead tired and getting pretty damned cold. &amp;nbsp;The ground was rocky as I slithered and bruised myself. &amp;nbsp;By this point I just wanted to be warm again.&lt;br /&gt;&lt;br /&gt;The finish of the race was a nice cleansing wade followed by a mud climb, followed by sliding back down the same hill (and almost taking a couple people out) following by climbing up the same hill a third time. &amp;nbsp;A nice hot chocolate was waiting for me after my three hour ordeal. &amp;nbsp;In all it was a blast. &amp;nbsp;Again, there was no part of the race that was incredibly difficult and I didn't have to dig really deep to keep on going. &amp;nbsp;It was&amp;nbsp;gruelling&amp;nbsp;and had the weather been colder it would have been more miserable (though I did have extra layers waiting in case) I think I will do it again next year; perhaps prepare a bit better this time.&lt;br /&gt;&lt;br /&gt;Thanks to everybody who volunteered, cheered, photo'd, sponsored, mocked, doubted and raced this crazy thing with me. &amp;nbsp;Hope to see you all again next year!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-JBnytUfuK-M/TycWfE6gg3I/AAAAAAAABwM/y8yV7AM6Av4/s1600/DSC_0005.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="427" src="http://4.bp.blogspot.com/-JBnytUfuK-M/TycWfE6gg3I/AAAAAAAABwM/y8yV7AM6Av4/s640/DSC_0005.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-BvdoqABSsxE/TycWjMMNj0I/AAAAAAAABwc/ikkvA9Sce3E/s1600/DSC_0053.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://4.bp.blogspot.com/-BvdoqABSsxE/TycWjMMNj0I/AAAAAAAABwc/ikkvA9Sce3E/s640/DSC_0053.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-q1Jsot5rZUk/TycWldpS9pI/AAAAAAAABwk/4uMJIqxV-Hc/s1600/DSC_0077.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://1.bp.blogspot.com/-q1Jsot5rZUk/TycWldpS9pI/AAAAAAAABwk/4uMJIqxV-Hc/s640/DSC_0077.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-lIsR2mnNADM/TycWurTPGFI/AAAAAAAABxE/EMtf5iHLF7U/s1600/DSC_0140.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://1.bp.blogspot.com/-lIsR2mnNADM/TycWurTPGFI/AAAAAAAABxE/EMtf5iHLF7U/s640/DSC_0140.jpg" width="428" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-erPQsutacF4/TycWtaj6QcI/AAAAAAAABw8/tM5PFFD4u1g/s1600/DSC_0139.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://2.bp.blogspot.com/-erPQsutacF4/TycWtaj6QcI/AAAAAAAABw8/tM5PFFD4u1g/s640/DSC_0139.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-__1nZDYwcmo/TycWqzMS-qI/AAAAAAAABw0/zS_Jfn2wgT8/s1600/DSC_0128.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://1.bp.blogspot.com/-__1nZDYwcmo/TycWqzMS-qI/AAAAAAAABw0/zS_Jfn2wgT8/s640/DSC_0128.jpg" width="428" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-dex3UItmyYg/TycYV4QUAXI/AAAAAAAABzU/GnYGrP6RuIY/s1600/DSC_0119.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://1.bp.blogspot.com/-dex3UItmyYg/TycYV4QUAXI/AAAAAAAABzU/GnYGrP6RuIY/s640/DSC_0119.jpg" width="428" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-p6f4PTphS-Y/TycXJ4im0YI/AAAAAAAABx8/etdpDcHaBmg/s1600/DSC_0044.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://2.bp.blogspot.com/-p6f4PTphS-Y/TycXJ4im0YI/AAAAAAAABx8/etdpDcHaBmg/s640/DSC_0044.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/--4B0ReRHtrc/TycZgpAp8jI/AAAAAAAAB0E/6_1iJZ6we5s/s1600/DSC_0179.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://3.bp.blogspot.com/--4B0ReRHtrc/TycZgpAp8jI/AAAAAAAAB0E/6_1iJZ6we5s/s640/DSC_0179.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-9203149791149478662?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/9203149791149478662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=9203149791149478662' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/9203149791149478662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/9203149791149478662'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2012/01/tough-guy-2012.html' title='Tough Guy 2012'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-JBnytUfuK-M/TycWfE6gg3I/AAAAAAAABwM/y8yV7AM6Av4/s72-c/DSC_0005.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-7446038213038681661</id><published>2011-12-04T23:47:00.001-08:00</published><updated>2011-12-05T14:22:12.782-08:00</updated><title type='text'>Random Hacks of Kindness - CharityClick</title><content type='html'>As a software developer, it is very easy to forget what it is about software development that we love. &amp;nbsp;The daily grind fails to provide many rewards as when things work it's expected and when things break the business is busy figuring out who they can blame. &amp;nbsp;In general, people expect miracles from developers not really understanding the difficulty that we actually have to deal with to make that widget do that cool thing. &lt;br /&gt;&lt;br /&gt;Occasionally though we have an opportunity to remind ourselves what it is about software development that made our eyes shine when we were younger. &amp;nbsp;We get to see first hand how a good implementation of a cool idea can affect somebodies life and bring real value. &amp;nbsp;That smile that you get when you show a piece of functionality that says "that's fucking cool, thank you" is worth a huge amount.&lt;br /&gt;&lt;br /&gt;I had one of these opportunities fall into my lap this past weekend. &amp;nbsp;A good friend introduced me to the concept of Random Hacks of Kindness, and I figured I'd tag along for fun. &amp;nbsp;&lt;a href="http://www.rhok.org/"&gt;Random Hacks of Kindness&lt;/a&gt;&amp;nbsp;is an annual 48 hour global code jam that focuses on providing technology solutions to "make the world a better place." &amp;nbsp;I believe there were approximately 24 locations through out the world taking part in the event. The focus of RHOK London was financial literacy and financial exclusion. &amp;nbsp;The event was sponsored by &lt;a href="http://www.mybnk.org/home"&gt;MyBnk&lt;/a&gt;&amp;nbsp;a charity organization founded by the talented Lily Lapenna (&lt;a href="https://twitter.com/#!/LilyLapenna" target="_blank"&gt;@lilylapenna&lt;/a&gt;). &amp;nbsp;Its focus is (not surprisingly) on financial literacy for young people aged 11 - 25.&lt;br /&gt;&lt;br /&gt;On Saturday morning, after waking up well before I normally would on a work day, I made the 20 minute walk to the venue. &amp;nbsp;Very nice venue. &amp;nbsp;The majority of the morning was spent on idea generation by subject matter experts. &amp;nbsp;They presented their ideas and the assorted crowd of developers &amp;amp; designers then chose which idea they wanted to help with. &amp;nbsp;My decision wasn't an easy one. &amp;nbsp;I wasn't terribly attached to any one idea that was put forth and certainly a little put off by a couple that were really far fetched from a technical point of view. &amp;nbsp;So at the end it really boiled down to the team that didn't say "I need somebody to build a database."&lt;br /&gt;&lt;br /&gt;It turns out that I made the right choice. &amp;nbsp;The idea was put forward by Andrea James; apparently she had been growing the idea for quite a while. &amp;nbsp;And really it was a great idea, unfortunately didn't really fit in the theme of financial literacy. &amp;nbsp;But no matter, the team of myself, Andrea, Sandy &amp;amp; Alejandro rolled up our collective and (aside from me) somewhat figurative sleeves and started hacking. &amp;nbsp;The effort really focused on working software. &amp;nbsp;Many of the teams that we were competing with did nice powerpoint presentations but failed to demonstrate working software. &amp;nbsp;We had %100 working software with a small bit of smoke and mirrors to tie it together.&lt;br /&gt;&lt;br /&gt;The first step of the project was a mini-inception. &amp;nbsp;We drove out 3 personas, or people who will be using our software. &amp;nbsp;Two were random people who felt the need to donate to charity, they had differing life situations which helped to outline differing usage patterns. &amp;nbsp;The third was a small charity owner with little or no budget for marketing. &amp;nbsp;Once we had these three personas we delved into some user journeys. &amp;nbsp;Out of these journeys came a set of tasks and based on their priorities, working software. &amp;nbsp;You can actually see the fruits of our labour at the following link:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.chromeextensions.org/wp-content/uploads/2011/12/charityclicks3.crx" style="color: #1155cc;" target=""&gt;http://www.chromeextensions.&lt;wbr&gt;&lt;/wbr&gt;org/wp-content/uploads/2011/&lt;wbr&gt;&lt;/wbr&gt;12/charityclicks3.crx&lt;/a&gt;&amp;nbsp; (only works in chrome)&lt;br /&gt;&lt;br /&gt;Once you install the link visit the following two links and look for the little hearts. &amp;nbsp;Hover over the hearts see the magic.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://www.guardian.co.uk/society/2011/dec/04/charities-welcome-cash-for-homes?INTCMP=SRCH" style="color: #1155cc;" target="_blank"&gt;http://www.guardian.co.uk/&lt;wbr&gt;&lt;/wbr&gt;society/2011/dec/04/charities-&lt;wbr&gt;&lt;/wbr&gt;welcome-cash-for-homes?INTCMP=&lt;wbr&gt;&lt;/wbr&gt;SRCH&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.ted.com/speakers/sunitha_krishnan.html" style="background-color: rgba(255, 255, 255, 0.917969); color: #1155cc; font-family: arial, sans-serif; font-size: 13px;" target="_blank"&gt;http://www.ted.com/speakers/&lt;wbr&gt;&lt;/wbr&gt;sunitha_krishnan.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We also have a web page (alas not live right now) that Sandy masterfully built to help drive the solution. &amp;nbsp;The only missing piece is the connection between the add-on and the web page. &amp;nbsp;As I said in the presentation given another 24 hours we would have had it functioning end to end. &amp;nbsp;There is a chance that I will do another blog post on the technical details on creating a chrome extension. &amp;nbsp;It's actually incredibly easy (don't tell anybody that thinks I did magic, I have a reputation to maintain) once you understand the fundamentals.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The judging started at 4:30 on Sunday, about 28 hours after we started coding (and yes I did sleep). &amp;nbsp;The quality of the ideas was generally really high. &amp;nbsp;I was very impressed with some of the ideas, but I feel that many of them could have used some more focused delivery management. &amp;nbsp;The eventual winners (&lt;a href="http://www.rhok.org/solutions/blackball" target="_blank"&gt;BlackBall&lt;/a&gt;) had a brilliant presentation that almost brought a tear to the eye. &amp;nbsp;They definitely deserve the win and I hope that they continue to drive their solution to the problem of keeping touch between financial advisors (debt councillors etc, not the fat cats) and the people that need the help the most.&lt;br /&gt;&lt;br /&gt;Well at this point you know we didn't win... Though I did come in second in the twitterer of the weekend... or is that twit of the weekend? Dunno, got a cool book outta it. &amp;nbsp;So after judging was complete (I'm going to try to upload a video of the presentation asap) the judges came out and delivered the verdict. &amp;nbsp;Watch the judges verdict at 3:00 of the following video (you can also see me graciously accept the twitter award earlier in the video):&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://3.gvt0.com/vi/DpSMNxdHaCM/0.jpg" height="266" width="320"&gt;&lt;param name="movie" value="http://www.youtube.com/v/DpSMNxdHaCM&amp;fs=1&amp;source=uds" /&gt;&lt;param name="bgcolor" value="#FFFFFF" /&gt;&lt;embed width="320" height="266"  src="http://www.youtube.com/v/DpSMNxdHaCM&amp;fs=1&amp;source=uds" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This is a really really really really big deal both for me (though its all pro-bono from my perspective) and for Andrea as it means that her idea might really take off.&lt;br /&gt;&lt;br /&gt;All in all, I have to say it was an amazing weekend. &amp;nbsp;I didn't think it would be much when I started but the payoff has been incredible for me personally. &amp;nbsp;I want to thank the team Andrea, Alejandro and Sandy - it was a pleasure. &amp;nbsp;The organisers from MyBnk and all the participants for a fantastic weekend.&lt;br /&gt;&lt;br /&gt;If you have any interest in contributing to &lt;a href="http://www.rhok.org/solutions/CharityClick" target="_blank"&gt;CharityClick&lt;/a&gt;&amp;nbsp;please get in contact and I'll see how contributions can be managed. &lt;/div&gt;&lt;div&gt;&lt;div class="yj6qo ajU" style="background-color: rgba(255, 255, 255, 0.917969); color: #222222; cursor: pointer; font-family: arial, sans-serif; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 2px; outline-color: initial; outline-style: none; outline-width: initial; padding-bottom: 10px; padding-left: 0px; padding-right: 0px; padding-top: 10px; width: 22px;"&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-7446038213038681661?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/7446038213038681661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=7446038213038681661' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7446038213038681661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7446038213038681661'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/12/random-hacks-of-kindness-charityclick.html' title='Random Hacks of Kindness - CharityClick'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-1929602920235124228</id><published>2011-10-09T14:00:00.000-07:00</published><updated>2011-10-09T14:00:13.665-07:00</updated><title type='text'>Munich - Oktoberfest</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-6bJqr-UnUb0/TpH644aiUWI/AAAAAAAABbs/_wDpvF-ebvk/s1600/DSC_0036.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="427" src="http://2.bp.blogspot.com/-6bJqr-UnUb0/TpH644aiUWI/AAAAAAAABbs/_wDpvF-ebvk/s640/DSC_0036.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;If you're in Europe and it happens to be October, where would you go? The obvious answer, other than to London to visit David, is Munich for the famous, infamous and incredibly (I think?) unique Oktoberfest. &amp;nbsp;A celebration of Bavarian culture and quite frankly the ingestion of copious amounts of Alcohol. &lt;br /&gt;&lt;br /&gt;On September 30, my colleague and friend Jo and I embarked on an EasyJet flight to Munich. &amp;nbsp;It took us a few seconds to ensure that we were heading to the correct location because their were people dressed in pink tutus and kilts on board. &amp;nbsp;However, apparently everybody was waiting till they arrived in Munich to put on their&amp;nbsp;Dirndls &amp;amp;&amp;nbsp;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Times New Roman';"&gt;Lederhosen (Bavarian clothing)&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Times New Roman';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-c2dAeWi4Ot8/TpH8i_M845I/AAAAAAAABeM/zVdNIhKyB2s/s1600/DSC_0198.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://1.bp.blogspot.com/-c2dAeWi4Ot8/TpH8i_M845I/AAAAAAAABeM/zVdNIhKyB2s/s640/DSC_0198.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Times New Roman';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Times New Roman';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Times New Roman';"&gt;Upon arrival in Munich, Jo &amp;amp; I checked in at the campsite, picked up a warmup beer and jumped on a bus to the Oktoberfest grounds. &amp;nbsp;On the way, I dusted off my Italian to help a ground of somewhat lost Italians. &amp;nbsp;Many Italians visit Oktoberfest... must be because of the crappy beer &amp;amp; serious lack of protein in Italy.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Times New Roman';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-PEyjVxV_Oq8/TpH7FaSvE2I/AAAAAAAABcA/GzHXFo5OvNE/s1600/DSC_0058.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://1.bp.blogspot.com/-PEyjVxV_Oq8/TpH7FaSvE2I/AAAAAAAABcA/GzHXFo5OvNE/s640/DSC_0058.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Times New Roman';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Times New Roman';"&gt;We arrived at the Oktoberfest grounds in good time and immediately set about trying to find a seat in the beer gardens. &amp;nbsp;The weather was so nice that it was packed, but before too long Jo &amp;amp; I found some good seats and started in on our first beer...&lt;/span&gt;&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://1.bp.blogspot.com/-FW8B6pXr724/TpH7AotsT7I/AAAAAAAABb4/2hBhLI-GN6s/s1600/DSC_0053.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://1.bp.blogspot.com/-FW8B6pXr724/TpH7AotsT7I/AAAAAAAABb4/2hBhLI-GN6s/s400/DSC_0053.jpg" width="267" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://1.bp.blogspot.com/-Ei-p87i-M5Q/TpH7DIntXpI/AAAAAAAABb8/vaa3oiTQvRM/s1600/DSC_0057.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="213" src="http://1.bp.blogspot.com/-Ei-p87i-M5Q/TpH7DIntXpI/AAAAAAAABb8/vaa3oiTQvRM/s320/DSC_0057.jpg" width="320" /&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;The night progressed quickly, we met some friendly Austrians, and watched a kid vomit into his glass, get kicked out, sneak back in then get kicked out two more times before getting the message.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-3CVxMwUw06E/TpH7Kid1LrI/AAAAAAAABcI/wUxck-GWYTo/s1600/DSC_0062.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="427" src="http://1.bp.blogspot.com/-3CVxMwUw06E/TpH7Kid1LrI/AAAAAAAABcI/wUxck-GWYTo/s640/DSC_0062.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-D5vSRj2dRjo/TpH7Wa4syfI/AAAAAAAABcc/DGVX39g7jM0/s1600/DSC_0076.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://2.bp.blogspot.com/-D5vSRj2dRjo/TpH7Wa4syfI/AAAAAAAABcc/DGVX39g7jM0/s640/DSC_0076.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The rest of the evening was spent wandering to another beer tent (only got into the Garden) and riding three rides in the fair grounds. &amp;nbsp;I was yelling SCHNELL SCHNELL (faster faster) on the roller coaster. &amp;nbsp;Unfortunately, not many photos for the rest of the evening survived as they started to look more and more like the following one.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-n_NNChjyqTg/TpH7TgFk9yI/AAAAAAAABcY/jI7Lbdb9ReQ/s1600/DSC_0074.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://2.bp.blogspot.com/-n_NNChjyqTg/TpH7TgFk9yI/AAAAAAAABcY/jI7Lbdb9ReQ/s640/DSC_0074.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The following morning Jo and I went on a sobering experience as we visited the dachau concentration camp. &amp;nbsp;Visiting a concentration camp is an intense emotional experience and a very vivid reminder of why we can never forget and continue to fight for human rights and equality. &amp;nbsp;Unfortunately, the ride to the concentration camp was filled with stories of how somebody we were riding with managed to vomit all over a child at Oktoberfest.&lt;br /&gt;&lt;br /&gt;The afternoon was spent at a beer Monastery - a much more light hearted affair. &amp;nbsp;Jo &amp;amp; I went up to the monastery, saw a lovely lady getting ready to get married - then promptly went to find lunch.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-ryH8BTtOBrg/TpH7fYWtRaI/AAAAAAAABco/N5n3dEZCJAo/s1600/DSC_0104.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://2.bp.blogspot.com/-ryH8BTtOBrg/TpH7fYWtRaI/AAAAAAAABco/N5n3dEZCJAo/s640/DSC_0104.jpg" width="427" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Oh and what a lunch it was...&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://2.bp.blogspot.com/-RbqAL_2z_cY/TpH7vdlNB9I/AAAAAAAABdA/9Dye12irAys/s1600/DSC_0126.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-RbqAL_2z_cY/TpH7vdlNB9I/AAAAAAAABdA/9Dye12irAys/s320/DSC_0126.jpg" width="214" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://1.bp.blogspot.com/-KpLyS0mzi2E/TpH7k8U_U4I/AAAAAAAABcw/UswD1Cvlyzg/s1600/DSC_0117.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-KpLyS0mzi2E/TpH7k8U_U4I/AAAAAAAABcw/UswD1Cvlyzg/s320/DSC_0117.jpg" width="214" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Nh0HmiAF3sA/TpH7yViDyAI/AAAAAAAABdE/Ot8zs4yVUB4/s1600/DSC_0127.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-Nh0HmiAF3sA/TpH7yViDyAI/AAAAAAAABdE/Ot8zs4yVUB4/s320/DSC_0127.jpg" width="214" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;So of the two beers there, one is stronger than the other (8%) when I offered them both to Jo, a German couple said "That's strong beer, not for wives." &amp;nbsp;Jo, being a friend and not a wife and probably able to drink me under the table, found that funny on multiple levels. &amp;nbsp;Dessert was another level of awesome.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-wdbTEfIHyWc/TpH8G-r59jI/AAAAAAAABdk/LlqBuh-J1HQ/s1600/DSC_0146.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://1.bp.blogspot.com/-wdbTEfIHyWc/TpH8G-r59jI/AAAAAAAABdk/LlqBuh-J1HQ/s640/DSC_0146.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;In the evening we headed back to the Oktoberfest grounds where things had taken a decided turn for the worst...&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://3.bp.blogspot.com/-g5uZqjK-cvw/TpH8J1S1iuI/AAAAAAAABdo/cRRCGoKXtK4/s1600/DSC_0148.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="214" src="http://3.bp.blogspot.com/-g5uZqjK-cvw/TpH8J1S1iuI/AAAAAAAABdo/cRRCGoKXtK4/s320/DSC_0148.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://2.bp.blogspot.com/-mzpADqUosng/TpH8Su_xAMI/AAAAAAAABd0/cOXPmONtfa4/s1600/DSC_0156.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="214" src="http://2.bp.blogspot.com/-mzpADqUosng/TpH8Su_xAMI/AAAAAAAABd0/cOXPmONtfa4/s320/DSC_0156.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Indeed, the night was warm and the drinkers were drunk... alas the beer gardens were also quite full. &amp;nbsp;Despite waiting a long time and a near fight with the security guard, Jo and I ended up leaving the Oktoberfest grounds with no drinks.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-JkHa7i3bnmQ/TpH8t0J8pEI/AAAAAAAABec/0BaAOIqB-CE/s1600/DSC_0215.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://3.bp.blogspot.com/-JkHa7i3bnmQ/TpH8t0J8pEI/AAAAAAAABec/0BaAOIqB-CE/s640/DSC_0215.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Instead, we went back to the campsite, where for significantly cheaper, we bought the exact same beer! A couple of litres, one dude urinating on a tent, one dude just urinating on nothing in particular and lots of laughs later Jo and I went to sleep.&lt;br /&gt;&lt;br /&gt;The following day was much more relaxed. &amp;nbsp;Jo and I grabbed a nice breakfast at the Cafe in town and wandered around Munich. &amp;nbsp;Both of us had been there before so there wasn't alot of tourist type activity for us to do. &amp;nbsp;We ended the trip with a last beer at the camp site (fair grounds PACKED and unable to get a beer) and a mad dash to the airport.&lt;br /&gt;&lt;br /&gt;All in all, the weekend was loads of fun. &amp;nbsp;I won't be going back to Oktoberfest in the near future though. &amp;nbsp;Too many drunk &amp;amp; stupid people but it was well worth the price of admission.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;hl=en_US&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2F105302176970713958800%2Falbumid%2F5661581836317498417%3Falt%3Drss%26kind%3Dphoto%26authkey%3DGv1sRgCPHysciR_fKQkAE%26hl%3Den_US" height="400" pluginspage="http://www.macromedia.com/go/getflashplayer" src="https://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="600"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-1929602920235124228?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/1929602920235124228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=1929602920235124228' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1929602920235124228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1929602920235124228'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/10/munich-oktoberfest.html' title='Munich - Oktoberfest'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-6bJqr-UnUb0/TpH644aiUWI/AAAAAAAABbs/_wDpvF-ebvk/s72-c/DSC_0036.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-5717776077316895095</id><published>2011-09-27T13:55:00.000-07:00</published><updated>2011-09-27T13:55:08.359-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='London'/><title type='text'>London - The Rat Race</title><content type='html'>This past weekend, a colleague and friend of mine, Brett and I competed in the a monster endurance event known as &lt;a href="http://www.ratraceadventure.com/ratracelondon/"&gt;The Rat Race&lt;/a&gt;. &amp;nbsp;We both trained for years to be ready for this race and registered about 10 days in advance for it. &amp;nbsp;Ahem. &amp;nbsp;Amusingly enough, when I travelled in London a year ago, Emilie &amp;amp; I saw a bunch of crazy people scurrying too and fro in London. &amp;nbsp;These people were competing in the very event that Brett and I had signed up to do the race.&lt;br /&gt;&lt;br /&gt;Sign in on the morning of started at 7am. &amp;nbsp;All the intense teams were there bright and early mapping out the routes they would take throughout London. &amp;nbsp;We rocked up at 8am. &amp;nbsp;We were already prepared. &amp;nbsp;Neither of us knowing London at all. &amp;nbsp;The kit included an A-Z map of London and a route booklit detailing where we had to bike/run to and what sort of challenges would await us upon arrival. &amp;nbsp;Not at all desperately, we tried to plot the entire route on the map... I'd say we feel that we plotted quite enough of the route to be ready to go. &amp;nbsp;Perhaps some of the less confident teams may have plotted more, but us, we were ready.&lt;br /&gt;&lt;br /&gt;The first challenge included a nice 5 mile run to get the leg juices flowing. &amp;nbsp;During this run we needed to find 4 churches in London and total up the number of services on a Sunday. &amp;nbsp;A touch ambiguous as one of the churches was somewhat confusing. &amp;nbsp;And two didn't have services on a Sunday. &amp;nbsp;Anyway, after getting the number 2 right on our second guess, we were off on our bikes. &amp;nbsp;We lost alot of time on the run due to me not really being a runner. &amp;nbsp;Ah well, I'm training for next year already.&lt;br /&gt;&lt;br /&gt;Here we learnt the first thing about urban adventure racing that we perhaps should have been prepared for: you need to look at the map whilst on your bike. &amp;nbsp;Many teams had clipboards attached to their handle bars. No matter! &amp;nbsp;On we went! &amp;nbsp;Brett held the map in his hand while cycling and I was the caretaker of the instructions.&lt;br /&gt;&lt;br /&gt;The first challenge required more running. &amp;nbsp;We received a map and had to run to 8 different checkpoints. &amp;nbsp;At one of them, we either needed to run across a boat bridge (I don't think many made it) or start in the water swimming. &amp;nbsp;We both swam as a slow dude was on the boat bridge. &amp;nbsp;Did I mention it was a beautiful sunny day?&lt;br /&gt;&lt;br /&gt;Back onto the bikes and onwards. &amp;nbsp;Next up we needed to showcase our soccer skills, exercise ability and climbing skills at the next challenge. &amp;nbsp;A short dribble followed by 30 seconds on an exercise machine of our choice and a wall traverse completed in short order sent us towards the kayaking portion of the day. &lt;br /&gt;&lt;br /&gt;In the crystal clear waters off the London City Airport we kayaked for a kilometer (dropped a little time on this one... I think Brett had to reach extra far down to reach the water... the boat may have been tilted back a little bit...) Following this there was some "mountain biking" down the steps at the Arsenal Stadium, followed by&amp;nbsp;abseiling (rappelling) off the Lord's Cricket Grounds, climbing onto the Big Guns at the War Museum, playing around on a small jungle gym and finally arriving back at the finish line where we were greeted by a large inflatable obstacle course and 10 foot slanted wall covered in baby oil. &amp;nbsp;I made a heroic leap to catch the lip of the wall and pulled myself up. &amp;nbsp;Turning I assisted Brett to make the leap (almost coming tumbling down on his head) and together we completed the race. &amp;nbsp; Our final position turned out to be 15th... perhaps with better fitness, a touch more planning and better equipment we might have placed better. &lt;br /&gt;&lt;br /&gt;Regardless, the race was a blast. &amp;nbsp;Loads of people were there having a ton of fun, there was no pressure and we travelled through some pretty cool places in London. &amp;nbsp;While perhaps it wasn't very adventurous even as far as adventure races go, it was still something that we will consider doing again next year... and next year we go for the win! :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-5717776077316895095?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/5717776077316895095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=5717776077316895095' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5717776077316895095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5717776077316895095'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/09/london-rat-race.html' title='London - The Rat Race'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-7999624720550000921</id><published>2011-08-19T15:46:00.000-07:00</published><updated>2011-08-19T15:46:21.627-07:00</updated><title type='text'>Edinburgh - The Fringe in Review</title><content type='html'>The Fringe Festival in Edinburgh was an incredible event.  It was the first fringe festival that I have really "done".  The 20 or so Edmonton Fringe Festivals I've been to were generally driven by my parents rather than me.  The general buzz in Edinburgh was pretty electric.  Apparently something like 1.2 million unique visitors come to Edinburgh during the month of August.  It was a pretty special place to be.  As far as shows go I caught about ??? shows.&lt;br /&gt;&lt;br /&gt;1) Lights, Camara, Improvise - A lovely improvised movie with my work colleagues.&lt;br /&gt;2) Take the red pill - Stand up comedy %50 funny, with the funniest bit coming early and fading towards the end&lt;br /&gt;3) Baby wants Candy - A improvise musical, not as nice as Lights, Camara, Improvise but still nice.&lt;br /&gt;4) A Clockwork Orange - Amazing theatrical performance of the classic book.&lt;br /&gt;5) The Two Wrongies - so wrong it was right... can't really describe this one.&lt;br /&gt;6) Absolut Improv - decent improv but lacking in energy&lt;br /&gt;7) 5 Steps To Being German - funny standup all about Germans&lt;br /&gt;8) Camille O'Sullivan - Smooth &amp; sultry cabaret&lt;br /&gt;9) Mr Darwin's Tree - Amazing one man story about Darwin's life&lt;br /&gt;10) Anges and Walter (a little love story) - forgettable dance show&lt;br /&gt;11) Club Noir - Burlesque show, lots of nipple tassles but the company out weighed the show&lt;br /&gt;12) The Ginger, the geordie and the geek - funny sketch comedy&lt;br /&gt;13) David O'Doherity - Funny irishman standup, lots of fun music&lt;br /&gt;14) Jason Byrne - Very funny standup comedian with lots of audience participation.&lt;br /&gt;&lt;br /&gt;It's a bit of a pity that I needed to leave before it was finished, but it was an amazing experience all around :-)&lt;br /&gt;&lt;br /&gt;Here are a few pictures from the Tour de France that I should have posted a while back but didn't quite get around to. Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;embed type="application/x-shockwave-flash" src="https://picasaweb.google.com/s/c/bin/slideshow.swf" width="600" height="400" flashvars="host=picasaweb.google.com&amp;hl=en_US&amp;feat=flashalbum&amp;RGB=0x000000&amp;feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2F105302176970713958800%2Falbumid%2F5634869430303177761%3Falt%3Drss%26kind%3Dphoto%26authkey%3DGv1sRgCMnl_dLOu-3r1AE%26hl%3Den_US" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-7999624720550000921?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/7999624720550000921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=7999624720550000921' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7999624720550000921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7999624720550000921'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/08/edinburgh-fringe-in-review.html' title='Edinburgh - The Fringe in Review'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-1205844043373689322</id><published>2011-07-12T15:57:00.000-07:00</published><updated>2011-07-12T15:57:01.817-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='London'/><title type='text'>London - Bad David No Posts!</title><content type='html'>So, appears that my lofty goal of weekly posts has fallen by the wayside and now I'm at monthly posts!  Well without further ado here is a brief summary of the last month of my life:&lt;br /&gt;&lt;br /&gt;It's funny how quickly your life can get into a rhythm and things become more like real life - even after moving away from home.  I've become much more comfortable with my surroundings, almost like a real Londoner now!  I understand the tube, can generally figure out where I'm going when I want to go there.  Don't get lost very often any more.  It's a pretty cool thing.  However, I have found some of the things that I am missing about Calgary and Canada.  There is no easy way to get out climbing or cycling from London.  To get out of London on a bike takes about 1 - 1.5 hours of traffic and stinky cars.  Not ideal.  But on the other hand, it has forced me to start running more.  Turns out I kinda like running.  Thinking about the 2013 London Marathon.&lt;br /&gt;&lt;br /&gt;The one main exciting thing that has happened (aside from moving to Edinburgh for work - next blog post... don't want to use all my material in one post) is Canada Day in Trafalgar square.  So turns out that Canadians in London like to get down and party on Canada Day (similar to Canadians in Canada, but not in Canada) and have the biggest Canada Day celebration outside of Canada.  I went to Trafalgar Square, and like you would expect for a true Canadian celebration, watched a hockey tournament.  The 6th Annual Trafalgar Cup featured 8 Canadian organizations going toe to toe for the coveted trophy!  Third in prestige only after the Stanley Cup &amp;amp; Olympic Gold Medal!  The teams battled for glory and the Canadian High Commission team ended up as the victors.  A slew of Canadian bands played in the glorious sunlight and I got a nice sunburn.  Enjoy the photos below!&lt;br /&gt;&lt;br /&gt;I don't think I discussed this before so I'm going to make a quick shout out to my goal of visiting all 50 European Sovereign States over the next 2 years.  The list of countries in case you are interested is here:  &lt;a href="http://en.wikipedia.org/wiki/List_of_sovereign_states_and_dependent_territories_in_Europe"&gt;http://en.wikipedia.org/wiki/List_of_sovereign_states_and_dependent_territories_in_Europe&lt;/a&gt; - thus far I have hit 3 (Spain, Ireland and the UK), but I will hit France &amp;amp; Andorra this weekend.&lt;br /&gt;&lt;br /&gt;Next up will be a quick post on living/working in Edinburgh and shortly following that my trip this weekend to see the Tour de France and visit Andorra.&lt;br /&gt;&lt;br /&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;captions=1&amp;amp;hl=en_US&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2F105302176970713958800%2Falbumid%2F5628593197498672177%3Falt%3Drss%26kind%3Dphoto%26authkey%3DGv1sRgCLvwz_aQoICdcQ%26hl%3Den_US" height="400" pluginspage="http://www.macromedia.com/go/getflashplayer" src="https://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="600"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-1205844043373689322?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/1205844043373689322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=1205844043373689322' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1205844043373689322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1205844043373689322'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/07/london-bad-david-no-posts.html' title='London - Bad David No Posts!'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-194425558508949334</id><published>2011-06-12T13:49:00.000-07:00</published><updated>2011-06-12T13:50:29.672-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='London'/><title type='text'>London Month 2 - Ireland</title><content type='html'>Ireland - It started as a tweet; '&lt;span class="Apple-style-span" style="color: #444444; font-family: Arial, 'Helvetica Neue', sans-serif; font-size: 15px; line-height: 19px;"&gt;June 3 - June 5; Should I fly to Dublin &amp;amp; drive to Kilkenny for a comedy festival? Replies required.'&amp;nbsp;&lt;/span&gt;two people responded with yes absolutely. &amp;nbsp;It took me a day to convince myself to convince myself after that and book the tickets.&lt;br /&gt;&lt;br /&gt;June 3rd arrived quickly and I set off for an Irish adventure. &amp;nbsp;I left my house @ 5:20am - about 20 minutes later than I should have (who the hell books at 6:50am flight?!!!) and of course as one can imagine, I didn't arrive at the airport in time for check in. &amp;nbsp;£60 and two hours later I boarded another flight to Dublin. &amp;nbsp;Delayed, exhausted but excited I embarked on the trip.&lt;br /&gt;&lt;br /&gt;Day 1:&lt;br /&gt;&lt;br /&gt;Day one consisted mainly of wandering around Dublin looking around. &amp;nbsp;Dublin is a nice city, somewhat quaint compared to other larger European cities I have travelled but still quite nice. &amp;nbsp;Not as dirty as the cities in Spain so that was nice. &amp;nbsp;Lots of differing architectures throughout the city. &amp;nbsp;The main highlights for me were the Guinness brewery tour - guinness did come as part of the tour... mmmm guinness - It's good for you. The Christ Church, build in the 12th century it was quite a nice tour - less pompous than other European&amp;nbsp;churches. &amp;nbsp;There was a cafe in the crypt where I napped for an hour... And the bevy of live music and street music I found throughout the town. &amp;nbsp;All in all Dublin is a nice city, worth visiting.&lt;br /&gt;&lt;br /&gt;Day 2:&lt;br /&gt;&lt;br /&gt;Day 2 started with a trip the the Ireland National Museum only because I had time before the train to Kilkenny. &amp;nbsp;I like to live dangerously and somehow, with 10 minutes to spare, made it to the train. &amp;nbsp;In this case missing the train wouldn't have cost me anything as I didn't actually book ahead. &amp;nbsp;The train ride to Kilkenny wasn't terribly long, 1.5 hours or so, and I past the time snapping photos out of the window and reading David's Kindle v2.0. &amp;nbsp;Upon arrival in Kilkenny, I was promptly mocked by some visiting Irish ladies about the size of my feet and managed to avoid bringing up the good old "You know what they say about guys with big feet? &amp;nbsp;They wear big shoes" line that has served me so well in the past.&lt;br /&gt;&lt;br /&gt;Kilkenny itself is a nice small town with a river and two streets upon which there is life. &amp;nbsp;Life in this case is defined as street life as opposed to bacterial life. &amp;nbsp;In that way it's&amp;nbsp;similar&amp;nbsp;to Calgary, except&amp;nbsp;immensely&amp;nbsp;smaller and less Canadian. &amp;nbsp;The draw of Kilkenny was the Cat Laughs Comedy Festival and I have to admit I was slightly disappointed by the festival. &amp;nbsp;I can appreciate that my impression of festivals has been forever tainted by the best festival in the world - The Edmonton Fringe Festival - but I was hoping for a few more things going on in the streets. &amp;nbsp;Essentially the festival was focused entirely on the purchase of tickets for standup comedy rather than any sort of street comedy. &amp;nbsp;Regardless, I bought tickets for two shows and spent the rest of the day wandering around the castle and kilkenny in general. &lt;br /&gt;&lt;br /&gt;The shows were "The Horne Section" a lively little musical comedy. &amp;nbsp;The comedian along with other comedians from other shows spent the hour and a half using music to be funny. &amp;nbsp;It was actually rather amusing. &amp;nbsp;The second show was a dedicated standup comedy show with a bunch of comedians of some sort of fame or other. &amp;nbsp;As you may have guessed, I don't really follow stand up and honestly, given that, will likely not attend another standup comedy festival. &amp;nbsp;In general it was amusing but not really my cup of tea. &amp;nbsp;I don't regret going as the city and the experience was in general awesome.&lt;br /&gt;&lt;br /&gt;Day 3:&lt;br /&gt;&lt;br /&gt;A day of travel - didn't see much today but did meet a few loony Irish girls in for the festival. &amp;nbsp;They were in my hostel and I had breakfast with them. &amp;nbsp;Definitely loony. &amp;nbsp;Many Canadian stereotypes are driven by&amp;nbsp;south park&amp;nbsp;apparently and I don't have nearly enough pop culture knowledge to keep up with today's youth. &amp;nbsp;Apparently I also sound like Jon Favreau; I don't buy it but they were convinced.&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;In other news, I have started an improvisation workshop that will run for 8 weeks every tuesday night. &amp;nbsp;That's pretty awesome and alot of fun. &amp;nbsp;It's interesting that the act of making shit up can actually be very difficult and require alot of practice.&lt;br /&gt;&lt;br /&gt;Currently I am in Edinburgh about to help give an Agile development talk to a client here. &amp;nbsp;Still a beautiful city but I did forget my&amp;nbsp;camera... shame on me. &amp;nbsp;Guess I'll just have to come back. &amp;nbsp;I played badminton with a friend for 2ish hours yesterday and am so sore that I'm not walking around the town this evening. &amp;nbsp;Hopefully I'll feel better tomorrow and be able to go for a walk!&lt;br /&gt;&lt;br /&gt;Next up looks like a trip to northern Italy June 24 - 26th. &amp;nbsp;Flying into Verona will be&amp;nbsp;challenging&amp;nbsp;but I'm going to make it work somehow! &amp;nbsp;Till next time!!&lt;br /&gt;&lt;br /&gt;&lt;embed type="application/x-shockwave-flash" src="https://picasaweb.google.com/s/c/bin/slideshow.swf" width="600" height="400" flashvars="host=picasaweb.google.com&amp;captions=1&amp;hl=en_US&amp;feat=flashalbum&amp;RGB=0x000000&amp;feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2F105302176970713958800%2Falbumid%2F5616322908955897953%3Falt%3Drss%26kind%3Dphoto%26authkey%3DGv1sRgCMeT1sLgxJvffg%26hl%3Den_US" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-194425558508949334?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/194425558508949334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=194425558508949334' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/194425558508949334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/194425558508949334'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/06/london-month-2-ireland.html' title='London Month 2 - Ireland'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-6892559858335669919</id><published>2011-06-03T00:39:00.000-07:00</published><updated>2011-06-03T00:39:52.876-07:00</updated><title type='text'>London month 2</title><content type='html'>The last couple of weeks have been pretty tame by my standards so this post isn't going to be a long one.  I spent alot of time hanging out with friends old and new.  I guess one of the things that we learn while traveling is the true value of our good friends back home.  It's very easy for people to take friendships for granted and not really appreciate the people you have.  So rather than a long post I'm just going to tell you to hug a friend today.  And send a hug to all the friends I miss very much.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-6892559858335669919?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/6892559858335669919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=6892559858335669919' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/6892559858335669919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/6892559858335669919'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/06/london-month-2.html' title='London month 2'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-5689709575941718795</id><published>2011-05-27T05:26:00.001-07:00</published><updated>2011-05-27T05:34:13.162-07:00</updated><title type='text'>RSpec–Beautiful BDD, part 1</title><content type='html'>One of my biggest struggles with BDD in a .NET environment is the contraints introduced by the language.&amp;nbsp; I'm currently learning Ruby and have written my first context based specification... I love it.&lt;br /&gt;&lt;pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;1: &lt;span style="color: darkblue;"&gt;require&lt;/span&gt; "&lt;span style="color: darkred;"&gt;rspec&lt;/span&gt;"&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;2: &lt;span style="color: darkblue;"&gt;require&lt;/span&gt; &lt;a href="http://www.ruby-doc.org/docs/rdoc/1.9/classes/File.html" style="color: red;"&gt;File&lt;/a&gt;.expand_path(&lt;a href="http://www.ruby-doc.org/docs/rdoc/1.9/classes/File.html" style="color: red;"&gt;File&lt;/a&gt;.dirname(&lt;span style="color: blue;"&gt;__FILE__&lt;/span&gt;) + '/../order_parser')&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;3: &lt;span style="color: blue;"&gt;def&lt;/span&gt; given_a_single_case&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;4:   $input = %{&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;5: 1&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;6: 4 O 2 B 1 B 2 O 4&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;7: }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;8: &lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;9: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;10: &lt;span style="color: blue;"&gt;def&lt;/span&gt; setup&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;11:   $system_under_test = OrderParser.new&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;12: &lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;13: &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;14: describe OrderParser, "&lt;span style="color: darkred;"&gt;When asked to parse&lt;/span&gt;" =&amp;gt; [setup, given_a_single_case] &lt;span style="color: blue;"&gt;do&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;15:   it "&lt;span style="color: darkred;"&gt;should return a single list of orders&lt;/span&gt;" &lt;span style="color: blue;"&gt;do&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;16:     ... validate ...&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;17:   &lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;18: &lt;span style="color: blue;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Once I’ve gotten a bit more of a handle on the intricacies I’ll be posting a few tutorials.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-5689709575941718795?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/5689709575941718795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=5689709575941718795' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5689709575941718795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5689709575941718795'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/05/rspecbeautiful-bdd-part-1.html' title='RSpec–Beautiful BDD, part 1'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-4259748487277477478</id><published>2011-05-23T09:09:00.000-07:00</published><updated>2011-05-24T03:54:56.852-07:00</updated><title type='text'>London - Madrid Photos</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-RHY03TI3b0A/TdZ6iF_BF3I/AAAAAAAAAs0/aqQXqxZBZGA/s1600/Madrid-4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://1.bp.blogspot.com/-RHY03TI3b0A/TdZ6iF_BF3I/AAAAAAAAAs0/aqQXqxZBZGA/s640/Madrid-4.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;SOL is the heart of Madrid. &amp;nbsp;I kinda like this photo with the reflection, almost a reflection on the soul of Madrid. &amp;nbsp;Sol is where, as I'll show later, all the celebrations &amp;amp; protests happen in Madrid.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-pCxUBpP-42Q/TdZ6iWF14fI/AAAAAAAAAs4/6pFJgLMEFvw/s1600/Madrid-5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://2.bp.blogspot.com/-pCxUBpP-42Q/TdZ6iWF14fI/AAAAAAAAAs4/6pFJgLMEFvw/s640/Madrid-5.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;As with most of my trips, the focus is generally on food. &amp;nbsp;This was a fantastic steak I shared with my&amp;nbsp;colleagues&amp;nbsp;during the conference.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-fvLKouM7t68/TdZ6kXtol7I/AAAAAAAAAtg/wk_r1bPh57c/s1600/Madrid-12.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-fvLKouM7t68/TdZ6kXtol7I/AAAAAAAAAtg/wk_r1bPh57c/s320/Madrid-12.jpg" width="320" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/-NgqUDEV41kY/TdZ6itfLs6I/AAAAAAAAAs8/vpNUXThriws/s1600/Madrid-6.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;/a&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/-NgqUDEV41kY/TdZ6itfLs6I/AAAAAAAAAs8/vpNUXThriws/s320/Madrid-6.jpg" width="320" /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;These lovely chaps, and chappetes are my work&amp;nbsp;colleagues. &amp;nbsp;Except for the guy on the far left of the second photo. &amp;nbsp;He's just a cool guy I met at the conference.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-JkHpBniFfBg/TdZ6k3TOalI/AAAAAAAAAto/X881ifQMrAM/s1600/Madrid-14.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="538" src="http://3.bp.blogspot.com/-JkHpBniFfBg/TdZ6k3TOalI/AAAAAAAAAto/X881ifQMrAM/s640/Madrid-14.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Live music, again, was prevalent in Madrid. &amp;nbsp;Here though, the people got into it and danced in the streets.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-uwAOBRgFHl8/TdZ6oj7eq5I/AAAAAAAAAuM/2ov-72lTMpc/s1600/Madrid-23.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://1.bp.blogspot.com/-uwAOBRgFHl8/TdZ6oj7eq5I/AAAAAAAAAuM/2ov-72lTMpc/s640/Madrid-23.jpg" width="614" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;This dude was hanging out in SOL doing his fancy bike tricks. &amp;nbsp;I feel lucky to have gotten one nice shot of him. &amp;nbsp;With the lighting and the movement I tossed a bunch of them.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-KP6jBpR9UCE/TdZ6ohpTzzI/AAAAAAAAAuQ/UrdjfsGTvD4/s1600/Madrid-24.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="378" src="http://1.bp.blogspot.com/-KP6jBpR9UCE/TdZ6ohpTzzI/AAAAAAAAAuQ/UrdjfsGTvD4/s640/Madrid-24.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Unfortunately, this was not an uncommon sight. &amp;nbsp;The unemployment in Spain is extremely high as they try to weather the recession.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-qBJhaOkxRww/TdZ6qej54UI/AAAAAAAAAug/mtrzD5j4SzE/s1600/Madrid-27.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://4.bp.blogspot.com/-qBJhaOkxRww/TdZ6qej54UI/AAAAAAAAAug/mtrzD5j4SzE/s640/Madrid-27.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;One of the protests in SOL. &amp;nbsp;Not entirely certain what they were protesting in this case, but it was loud. &amp;nbsp;I seriously considered grabbing a flag and joining in, but then I decided to just take photos.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-j0nlJ8wwkSg/TdZ6se82pqI/AAAAAAAAAu4/77HwwElP1KU/s1600/Madrid-33.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="534" src="http://1.bp.blogspot.com/-j0nlJ8wwkSg/TdZ6se82pqI/AAAAAAAAAu4/77HwwElP1KU/s640/Madrid-33.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Even in the midst of the protest, the tourists still wanted to get photos of themselves wearing spanish clothing.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-tgo_tN-W3Mk/TdZ6tw7zZMI/AAAAAAAAAvM/B2xcwq3w_qE/s1600/Madrid-38.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://4.bp.blogspot.com/-tgo_tN-W3Mk/TdZ6tw7zZMI/AAAAAAAAAvM/B2xcwq3w_qE/s640/Madrid-38.jpg" width="428" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;The Royal Palace in Spain was quite nice. However, apparently there are several other buildings (the cathedral &amp;amp; the Opera house) that were made to look less impressive because a building could not look more impressive than the royal palace.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-D41MQwvwyZU/TdZ6uYwMSyI/AAAAAAAAAvU/NynG4_zrF9U/s1600/Madrid-40.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="492" src="http://1.bp.blogspot.com/-D41MQwvwyZU/TdZ6uYwMSyI/AAAAAAAAAvU/NynG4_zrF9U/s640/Madrid-40.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;The back of the cathedral looked much better than the front.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/--87gDSYDoj8/TdZ6vk4C47I/AAAAAAAAAvk/LNO0GOf6lhM/s1600/Madrid-44.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://3.bp.blogspot.com/--87gDSYDoj8/TdZ6vk4C47I/AAAAAAAAAvk/LNO0GOf6lhM/s640/Madrid-44.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;In Plaza Mayor there were many street performers, none more famous than the fat spiderman. &amp;nbsp;I'm not sure how he makes money but apparently has been there for years.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-W_eNO1XKBDw/TdZ604ZAAHI/AAAAAAAAAwU/qVejgmfWGg0/s1600/Madrid-54.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="508" src="http://1.bp.blogspot.com/-W_eNO1XKBDw/TdZ604ZAAHI/AAAAAAAAAwU/qVejgmfWGg0/s640/Madrid-54.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;This fellow taught me a lesson in big city living. &amp;nbsp;He caught a&amp;nbsp;pidgin with his hands. &amp;nbsp;He then proceeded to kiss it on the head and release it. &amp;nbsp;It was perhaps the oddest thing I have ever seen.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-c4SoG3Kk_kg/TdZ67Ln6eOI/AAAAAAAAAxQ/lR_CkJ8jGOY/s1600/Madrid-68.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="580" src="http://1.bp.blogspot.com/-c4SoG3Kk_kg/TdZ67Ln6eOI/AAAAAAAAAxQ/lR_CkJ8jGOY/s640/Madrid-68.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;There was a festival for the patron saint of Madrid, lots of people were dressed in traditional outfits. &amp;nbsp;It was quite lovely.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-9YlJofzTaEQ/TdZ680rgJbI/AAAAAAAAAxw/brS_2LEo13M/s1600/Madrid-76.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://2.bp.blogspot.com/-9YlJofzTaEQ/TdZ680rgJbI/AAAAAAAAAxw/brS_2LEo13M/s640/Madrid-76.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;I took several shots of this little girl. &amp;nbsp;I think she was on to me :-)&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-tfvGqE-V4GY/TdZ69u1hfVI/AAAAAAAAAx8/VckQUO-qM54/s1600/Madrid-79.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://4.bp.blogspot.com/-tfvGqE-V4GY/TdZ69u1hfVI/AAAAAAAAAx8/VckQUO-qM54/s640/Madrid-79.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;A military band was playing in front of the Royal Palace, they were very&amp;nbsp;talented&amp;nbsp;if somewhat grim looking.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-f2NhCJrZn40/TdZ6-Ulqd_I/AAAAAAAAAyI/hHqF38ELbf0/s1600/Madrid-81.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://1.bp.blogspot.com/-f2NhCJrZn40/TdZ6-Ulqd_I/AAAAAAAAAyI/hHqF38ELbf0/s640/Madrid-81.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;This is the not terribly inspiring looking Opera house. &amp;nbsp;Remember you can't build something more&amp;nbsp;opulent&amp;nbsp;than the Royal Palace.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-V13GqWqm69c/TdZ6_rZxBEI/AAAAAAAAAyc/SrlDh7Iim5U/s1600/Madrid-86.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://2.bp.blogspot.com/-V13GqWqm69c/TdZ6_rZxBEI/AAAAAAAAAyc/SrlDh7Iim5U/s640/Madrid-86.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;Another street performer. &amp;nbsp;This dude was pretty odd, but somehow he managed to sit around without a head.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-7aM-XvAT0mI/TdZ7AqK9TQI/AAAAAAAAAys/sYYsGayyE8k/s1600/Madrid-90.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://4.bp.blogspot.com/-7aM-XvAT0mI/TdZ7AqK9TQI/AAAAAAAAAys/sYYsGayyE8k/s640/Madrid-90.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;Everybody was dressed up and having an awesome time.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-4jWROtot9Jc/TdZ7BC_ULKI/AAAAAAAAAy0/h2CRxzm8qBw/s1600/Madrid-92.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://3.bp.blogspot.com/-4jWROtot9Jc/TdZ7BC_ULKI/AAAAAAAAAy0/h2CRxzm8qBw/s640/Madrid-92.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;More kids dressed up with awesome colours.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;All in all Madrid was an awesome time. &amp;nbsp;Met some really cool people, both industry colleagues and researchers. &amp;nbsp;I actually learned that I can not fill my memory card (16GB) with photos before I run out of batteries (1600 photos). &amp;nbsp;Not sure what's next up for me, but right now I'm looking at a weekend in Ireland for a comedy festival in Kilkenny. &amp;nbsp;Till next time!&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-4259748487277477478?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/4259748487277477478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=4259748487277477478' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/4259748487277477478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/4259748487277477478'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/05/london-madrid-photos.html' title='London - Madrid Photos'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-RHY03TI3b0A/TdZ6iF_BF3I/AAAAAAAAAs0/aqQXqxZBZGA/s72-c/Madrid-4.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-1182710964744638682</id><published>2011-05-18T15:16:00.001-07:00</published><updated>2011-05-19T04:35:18.957-07:00</updated><title type='text'>London–Week after the last time I posted</title><content type='html'>Apparently my counting skills are being incredibly taxed by this blog thingy.&amp;nbsp; So this post is going to attempt to get you all up to date with the current happenings.&amp;nbsp; I am a bit behind so bare with me a bit while I briefly jump back in time…&lt;br /&gt;Wooo Wooo Wooo --- It is now the weekend after Malaga, I meet for the first time my two lovely flatmates (see I said flat… tee hee… as an aside, I got rained on today, told my climbing partner that I had a dry shirt and that my pants should dry quickly… oups, pants mean underwear to the English) So my flatmares are Claudia, an Italian lady from Rome.&amp;nbsp; She moved to London to be closer to her boyfriend.&amp;nbsp; He is studying in Portsmouth and traveling a lot.&amp;nbsp; She offered to cook me Italian food… mmmmmmmm. She also decided I pronounce my last name incorrectly and that I am not Canadian, I am Italian. She’s a touch odd, but she’s super cool. My other flatmate is Caroline (pronounced with a French accent) she is from Paris (pronounced in a French accent) and has moved into London to learn English.&amp;nbsp; We’ve had a few awkward moments as I’ve attempted to have her understand my English.&amp;nbsp; She does speak English very well, but explaining her the intricacies of pants vs trousers was challenging.&amp;nbsp; She works as a designer but has been shoehorned into doing some web development.&amp;nbsp; She doesn’t really like to do development because she is not a “supergeek.”&amp;nbsp; Fortunately for me, she says I am not like most geeks who don’t like to talk to people.&amp;nbsp; There’s another funny story about talking (not related to Caroline) but you’ll have to poke me directly to get that story.&lt;br /&gt;Claudia is on the right, Caroline is on the left.&lt;br /&gt;&lt;img src="http://desmond.yfrog.com/Himg614/scaled.php?tn=0&amp;amp;server=614&amp;amp;filename=ddptxf.jpg&amp;amp;xsize=640&amp;amp;ysize=640" /&gt;&lt;br /&gt;This weekend as also after we had finished up working in Peterborough.&amp;nbsp; Our final presentation wasn’t until Monday and we are still working on the final report.&amp;nbsp; I have become completely post technical and haven’t written a line of code in anger since I got to London.&amp;nbsp; I have however, given several presentations, talked a lot and drawn a bunch of pretty pictures.&lt;br /&gt;On the weekend I settled into the flat, not all the furniture was, or has been delivered, so still a bit of a mess right now.&amp;nbsp; A co-worker Christian invited me to the brick lane curry festival.&amp;nbsp; Caroline &amp;amp; I went to the festival together and met up with Christian, his lovely wife, and some other co-workers.&amp;nbsp; It was a lovely day and I have some photos (of course, however, they will have to wait till tomorrow before being uploaded).&amp;nbsp; The brick lane portion of the festival was relatively standard street festival stuff.&amp;nbsp; Not terribly interesting or exciting but there were many people trying to sell me curry.&amp;nbsp; Traveling a little further afield we ran into a stampedesc carnival where we honestly felt that we had teleported from London to India.&amp;nbsp; It was a pretty neat experience. Kath chickened out on eating a dessert – not sure what it was called – but the slogan was eye it, try it, fantasize it.&amp;nbsp; To show the true Canadian fortitude, I got the desert.&amp;nbsp; It was some sort of mixture of noodles, condensed milk, something pink, something crunchy and ice cream.&amp;nbsp; A few hours later I was fantasizing not having eaten it… gurgle gurgle.&lt;br /&gt;On Wednesday, I departed for Madrid, Spain.&amp;nbsp; The excuse was of course XP2011, a technical conference that I will not bore you with the details about.&amp;nbsp; Perhaps there will be another blog post focusing on what I learnt - just for the techies who read my blog (assuming there are any).&amp;nbsp; The truth though was because I wanted to go to Madrid.&amp;nbsp; Beautiful city is all I can say.&amp;nbsp; Wednesday – Friday was spent at the conference.&amp;nbsp; Dinner on Wednesday was lovely – a large high class dinner hall.&amp;nbsp; I felt out of place.&amp;nbsp; I was slightly confused about which toilet was for gentlemen and which for ladies.&amp;nbsp; My confusion was furthered when a cleaning lady entered the bathroom while I was doing my business.&amp;nbsp; Awkward anyone?&amp;nbsp; I met a ton of colleagues there and some other very interesting people in the industry.&amp;nbsp; An interesting conference all around.&lt;br /&gt;I think I will save my Madrid experiences for the next blog post when I can narrate with photos.&amp;nbsp; I’ll leave you now with the photos from the royal wedding.&amp;nbsp; Oh, you can now travel back to the present --- Wooo Wooo Wooo --- (I’m trying to prove that I am a super geek)&lt;br /&gt;&lt;embed flashvars="host=picasaweb.google.com&amp;amp;captions=1&amp;amp;hl=en_US&amp;amp;feat=flashalbum&amp;amp;RGB=0x000000&amp;amp;feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2F105302176970713958800%2Falbumid%2F5604999687539255889%3Falt%3Drss%26kind%3Dphoto%26authkey%3DGv1sRgCOjblsf9rp26eQ%26hl%3Den_US" height="400" pluginspage="http://www.macromedia.com/go/getflashplayer" src="https://picasaweb.google.com/s/c/bin/slideshow.swf" type="application/x-shockwave-flash" width="600"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-1182710964744638682?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/1182710964744638682/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=1182710964744638682' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1182710964744638682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1182710964744638682'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/05/londonweek-after-last-time-i-posted.html' title='London–Week after the last time I posted'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-8152403913067961240</id><published>2011-05-07T05:52:00.001-07:00</published><updated>2011-05-07T05:52:06.892-07:00</updated><title type='text'>London Month 1–The good, the bad &amp; the ugly</title><content type='html'>&lt;p&gt;&lt;br&gt;Well, we have arrived at the end of my first month in London.&amp;nbsp; As the title to this blog post suggests, there have been three faces to my time here.&amp;nbsp; The good is pretty self explanatory.&amp;nbsp; London is simply a gorgeous city.&amp;nbsp; There is stuff going on everywhere.&amp;nbsp; You can’t walk 10 minutes without passing some sort of architectural beauty and there is a vibe in London that is unparalleled in any of the places that I have visited.&amp;nbsp; In one week, I spent 4 days in Spain, watched a royal wedding with half a million Londoners in Hyde Park and experienced a large Indie music festival, including some artists from Canada.&amp;nbsp; The Camden Markets are a treat with food from all corners of the world.&amp;nbsp; One particular booth was selling Crocodile, Kangaroo &amp;amp; Ostrich burgers.&amp;nbsp; Basically London is a city for living and doing.&lt;/p&gt; &lt;p&gt;The bad was my introduction to my new neighbourhood.&amp;nbsp; Camden is known to have one of the highest crime rates in London and I experienced this first hand.&amp;nbsp; Imagine if you will, a nice quiet London street.&amp;nbsp; You’re waiting with your stuff on the street, for your landlord to give you the keys.&amp;nbsp; To pass the time you decide to sit in the sunlight on a nice picnic bench and read your kindle.&amp;nbsp; It’s one pm.&amp;nbsp; Just as you are reaching a climatic fight scene in the novel, somebody on a bike rides by and plucks the kindle directly off your lap.&amp;nbsp; Not much you can do but curse London, think about moving home to crime free Canada and remove your credit card from the kindle so that he doesn’t buy any books.&amp;nbsp; Welcome to Camden David.&amp;nbsp; In reality, there are many things more painful that I could have had stolen and it was a good learning experience.&amp;nbsp; But seriously.&amp;nbsp; Sigh.&lt;/p&gt; &lt;p&gt;The ugly, well – anything that has beautiful has ugly to offset it.&amp;nbsp; Paying 867pounds a month (~$1300) for a room, sharing a house with 5 people.&amp;nbsp; That’s kinda ugly.&amp;nbsp; It’s a nice room and honestly, I’m 15 minutes walk from basically everything in central London.&amp;nbsp; Alright fine, I’m stretching for this one.&amp;nbsp; There’s not much that’s ugly persai.&lt;/p&gt; &lt;p&gt;And some more photos for ya! These photos are from Camden Crawl.&amp;nbsp; I do actually have photos of the Royal Wedding – those will get uploaded soon.&amp;nbsp; I’m having some internet issues right now so these will have to do.&lt;/p&gt; &lt;embed type="application/x-shockwave-flash" src="https://picasaweb.google.com/s/c/bin/slideshow.swf" width="600" height="400" flashvars="host=picasaweb.google.com&amp;hl=en_US&amp;feat=flashalbum&amp;RGB=0x000000&amp;feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2F105302176970713958800%2Falbumid%2F5602611733222644321%3Falt%3Drss%26kind%3Dphoto%26authkey%3DGv1sRgCKfTwoL36YOTVA%26hl%3Den_US" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-8152403913067961240?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/8152403913067961240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=8152403913067961240' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8152403913067961240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8152403913067961240'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/05/london-month-1the-good-bad-ugly.html' title='London Month 1–The good, the bad &amp;amp; the ugly'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-2038810626982719057</id><published>2011-04-27T14:27:00.000-07:00</published><updated>2011-04-27T14:27:53.251-07:00</updated><title type='text'>London Week 3/4ish - Photography</title><content type='html'>So I spent the weekend in Malaga.  Lovely little town.  There is an interesting dichotomy between the people that have, and the people that don't.  It's pretty similar to many towns I suppose that have nice weather.  Lots of people on the streets.  I was unlucky in that I didn't see any of the easter parades... the weather wasn't awesome.  Anyway it was a pretty cool trip.  However, the best part of it was taking photos.  I have a few that I'm going to highlight cause I think they are pretty neat :-)&lt;br /&gt;&lt;br /&gt;Otherwise, work is good - very challenging.  Oh and to those who sent me addresses, I have the post cards ready to go, but they haven't been mailed yet.  I haven't discovered how to find a post office here in London yet ;-) and everything was closed in spain.  Maybe I'll bring them to Madrid in May and send them then!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-8bFZoSIx6gk/TbdUKdAtaZI/AAAAAAAAALA/EO3mPf9SguQ/s1600/Malaga-6.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="427" src="http://3.bp.blogspot.com/-8bFZoSIx6gk/TbdUKdAtaZI/AAAAAAAAALA/EO3mPf9SguQ/s640/Malaga-6.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I like this photo, not because it's actually very good (stupid tree getting in the way) but because it highlights the plight of the poor. &amp;nbsp;There are three homeless people living in that photo.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-V8IuYaZxesk/TbdUMp-EDvI/AAAAAAAAALk/N9mn1mZqd9I/s1600/Malaga-14.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://2.bp.blogspot.com/-V8IuYaZxesk/TbdUMp-EDvI/AAAAAAAAALk/N9mn1mZqd9I/s640/Malaga-14.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;The weather wasn't awesome :-)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-yTavd7VcI4M/TbdUPHTXajI/AAAAAAAAAMI/6jVNgcyySdM/s1600/Malaga-24.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://1.bp.blogspot.com/-yTavd7VcI4M/TbdUPHTXajI/AAAAAAAAAMI/6jVNgcyySdM/s640/Malaga-24.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;I didn't go to the bull fight, but the arena is pretty cool looking.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-vJYmh7FISRY/TbdURYm5rDI/AAAAAAAAAM0/IAYZPK7Ebfw/s1600/Malaga-34.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="464" src="http://3.bp.blogspot.com/-vJYmh7FISRY/TbdURYm5rDI/AAAAAAAAAM0/IAYZPK7Ebfw/s640/Malaga-34.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;I just really like this photo. &amp;nbsp;Don't know what it is, but I like the kids &amp;amp; the statue.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-KB7t2m3p_r4/TbdURwKrmkI/AAAAAAAAAM8/R7o8FRoHtCw/s1600/Malaga-36.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://1.bp.blogspot.com/-KB7t2m3p_r4/TbdURwKrmkI/AAAAAAAAAM8/R7o8FRoHtCw/s640/Malaga-36.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;I'm pretty sure this is what I look like all the time. &amp;nbsp;Minus the girl and add an iphone.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-j_C3En7zeQE/TbdUVMjzWTI/AAAAAAAAAN4/qv172Ik1-B4/s1600/Malaga-50.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="565" src="http://2.bp.blogspot.com/-j_C3En7zeQE/TbdUVMjzWTI/AAAAAAAAAN4/qv172Ik1-B4/s640/Malaga-50.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;There were many street musicians playing in Malaga. &amp;nbsp;This particular fellow played with a passion.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-qEORlhGJq0I/TbdUWzHkulI/AAAAAAAAAOY/PNHSZVDtwZs/s1600/Malaga-57.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://4.bp.blogspot.com/-qEORlhGJq0I/TbdUWzHkulI/AAAAAAAAAOY/PNHSZVDtwZs/s640/Malaga-57.jpg" width="537" /&gt;&lt;/a&gt;&lt;/div&gt;Watching the flamenco dancer was alot of fun. &amp;nbsp;They did go on a couple "5 minute" breaks that turned into 15 minutes, but given that it was free and the tapas were pretty reasonable, I thought it was pretty cool. &amp;nbsp;I must have been pretty obvious taking photos (I took about 150 of her) as she asked me to send her the photos.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-dwDJu5sDgzA/TbdUYQQ2TLI/AAAAAAAAAO0/c0IFaPEFnuQ/s1600/Malaga-64.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="428" src="http://4.bp.blogspot.com/-dwDJu5sDgzA/TbdUYQQ2TLI/AAAAAAAAAO0/c0IFaPEFnuQ/s640/Malaga-64.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;She called a few people up on to stage with her. &amp;nbsp;For some reason she chose not to call me up. &amp;nbsp;I feel insulted ;-)&lt;br /&gt;&lt;br /&gt;Malaga was a blast. &amp;nbsp;This weekend I'll be at the Camden Crawl - an Indie music festival. &amp;nbsp;Two weeks following that I'll be back in Spain. &amp;nbsp;Madrid this time. &amp;nbsp;There is a technical conference that I'm going to - but I get the weekend to myself. &amp;nbsp;Should be a blast. &amp;nbsp;I'll be hanging out with some young friends I met in Malaga.&lt;br /&gt;&lt;br /&gt;Till next week (or 2).&lt;br /&gt;&lt;br /&gt;David&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-2038810626982719057?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/2038810626982719057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=2038810626982719057' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/2038810626982719057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/2038810626982719057'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/04/london-week-34ish-photography.html' title='London Week 3/4ish - Photography'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-8bFZoSIx6gk/TbdUKdAtaZI/AAAAAAAAALA/EO3mPf9SguQ/s72-c/Malaga-6.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-8267544446930112365</id><published>2011-04-16T10:55:00.000-07:00</published><updated>2011-04-16T11:18:36.955-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='London'/><title type='text'>London Week 2 - The glamorous life of an IT consultant</title><content type='html'>Well I've now been in London for 2.5 weeks.  The most exciting thing that I feel has happened is that I have welcomed a new bike into my family.  It's a Genesis Day-One single speed cross bike meant for pedalling around London.  It's a pretty hot bike!  I spent a bunch of time today getting myself truly and completely lost.  The roads in London are basically a great big maze of one way streets and T intersections.  I can't believe how many people ride around without helmets!!!  I'd say that less than %50 of the cyclists I've seen are wearing helmets.  It's mental.&lt;br /&gt;&lt;br /&gt;In other news I have been put on a consulting gig in Peterborough.  Peterborough is a small town about 60 miles north of London.  There isn't much going on in Peterborough at any given time.  There do seem to be a fair amount of business there though.  I'm working with a pretty well known insurance comparison website.  They need some serious help.  I actually feel really bad for some of there developers.  The development process is completely messed up.  I guess the interesting thing about being in an IT consultancy is that when people feel desperate enough to call us in, things are already pretty bad.  Anyway, I guess it's my job to help fix things.  If we can come up with a good plan then Peterborough will become my home away from home for the next 6 months or so.  Not really ideal, however it's a fantastic learning experience.  It is close enough to go home, but the commute would be 1.5 - 2 hours minimum.  Not really something I want to do everyday - though the alternative is either cycling (yay) or drinking (boo).&lt;br /&gt;&lt;br /&gt;I have been hanging out with some pretty cool people.  Was randomly accosted by a couple of drunk london girls last night.  That was pretty interesting; they were pretty cool so we may hang out again in the future.  I have found it a little challenging to meet new people as the fabled English reserve does actually exist.  That said, I'm definitely trying to step out of my comfort zone (not that I had alot of choice - I can't hang out with Alyse &amp;/or Megan all the time; especially not in Peterborough) and meet new people.  I met a really cool group of people from Croydan (townish thing south of London... not sure if it's in greater London or not?) last weekend.  They were super cool.&lt;br /&gt;&lt;br /&gt;The other pretty cool thing is that I have been playing around with my new D80 camera.  Trying to remember/figure out how to take photos manually.  Some of my work down in Peterborough is evidenced in the attached photo gallery.&lt;br /&gt;&lt;br /&gt;Hope everyone back home is surviving the snow - I miss you all.&lt;br /&gt;&lt;br /&gt;PS: I am going to be going to Spain next weekend.  Please send me your address if you want a postcard!  david@morgantini.ca&lt;br /&gt;&lt;br /&gt;&lt;embed type="application/x-shockwave-flash" src="https://picasaweb.google.com/s/c/bin/slideshow.swf" width="600" height="400" flashvars="host=picasaweb.google.com&amp;hl=en_US&amp;feat=flashalbum&amp;RGB=0x000000&amp;feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2F105302176970713958800%2Falbumid%2F5596247274334558913%3Falt%3Drss%26kind%3Dphoto%26authkey%3DGv1sRgCJS-89HipMqBzgE%26hl%3Den_US" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-8267544446930112365?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/8267544446930112365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=8267544446930112365' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8267544446930112365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8267544446930112365'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/04/london-week-2-glamorous-life-of-it.html' title='London Week 2 - The glamorous life of an IT consultant'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-6192062935822522521</id><published>2011-04-06T15:52:00.000-07:00</published><updated>2011-04-06T22:14:57.418-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='London'/><title type='text'>London Week 1</title><content type='html'>So I've officially been in London for a week and in a word - I love it. &amp;nbsp;I know it's early, but there is something about the vibe of a living city that you don't really get in Calgary. &amp;nbsp;Perhaps in 6 months I'll find that the vibe is driving me nuts (arrrrh) but for now I'm loving it. &amp;nbsp;The weeks highlights were:&lt;br /&gt;&lt;br /&gt;1) Arriving in London (a very important part of being in london).&lt;br /&gt;2) Hanging with Meghan &amp;amp; Alyse, two Australians whom I had met last time I visited London.&lt;br /&gt;3) Getting to my tiny "one" bedroom&amp;nbsp;apartment. &amp;nbsp;I generally think that if you can take you shoes off sitting on your bed, it's not considered a bedroom...&lt;br /&gt;4) Finding the local coffee shop (on my way to work) and it has fantastic coffee.&lt;br /&gt;5) Fooling all my friends with a cruel April fools prank. &amp;nbsp;I'm sorry everybody whose heart rate I made sky rocket - It was kinda fun though... &amp;nbsp;And to be honest the outpouring of support was very touching. &amp;nbsp;I love you all.&lt;br /&gt;6) Wandering around downtown London for 7 hours on Saturday and managing to buy an undershirt and a cycling book.&lt;br /&gt;7) Being told to show up at work on Friday because I might be at the client on Monday only to find that the project was indefinitely delayed. &amp;nbsp;Consulting is fun :-)&lt;br /&gt;8) Finding out that my office is just off Drury Lane... I haven't yet looked for the muffin man.&lt;br /&gt;9) Playing board games in a pub with the local board game meetup group.&lt;br /&gt;10) Getting some slightly more "cosmopolitan" clothing for rather reasonable prices.&lt;br /&gt;11) Randomly running into the Real Food Festival - fantastic food... mmmmm.&lt;br /&gt;12) Beer.&lt;br /&gt;&lt;br /&gt;One of the&amp;nbsp;benefits&amp;nbsp;of travelling without any expectations of where you are going is that you can't be disappointed. &amp;nbsp;This whole trip is about new experiences and allowing whatever comes to be the experience, no prejudice, no expectations. &amp;nbsp;As far as the&amp;nbsp;neigh sayers&amp;nbsp;go, it actually doesn't take an hour to get any where in London. ;-) &amp;nbsp;In fact, from my place to work is a 45 minute walk. &amp;nbsp; Now, if there is a person on the tracks, then apparently things slow down a bit. &amp;nbsp;This is a common thing, a couple of co-workers took 3 extra hours to get to work today because of that issue. &amp;nbsp;Give me another few months and in the&amp;nbsp;sweltering&amp;nbsp;summer heat I might just change my tune about the tube. &amp;nbsp;The food in London is really good thus far. &amp;nbsp;Yes, English&amp;nbsp;cuisine is not&amp;nbsp;necessarily incredibly inspiring but London is a multi-cultural city with many different types of food. &amp;nbsp;The fish pie I had today was extremely nice. &amp;nbsp;The wine is expensive though. &amp;nbsp;The biggest thing that I have noticed is how easy it is to get good quality sandwiches pretty much everywhere. &amp;nbsp;In Calgary, finding good food quickly is impossible with the barest exception being Subway. &amp;nbsp;In London there is a cafe on every street corner selling fresh sandwiches.&lt;br /&gt;&lt;br /&gt;Overall, my experiences in London have been lovely. &amp;nbsp;I'm really enjoying it here.&lt;br /&gt;&lt;br /&gt;Oh and it was sunny &amp;amp; 22 degrees today... not that I'm gloating. ;-)&lt;br /&gt;&lt;br /&gt;My morning commute images:&lt;br /&gt;&lt;br /&gt;&lt;embed type="application/x-shockwave-flash" src="https://picasaweb.google.com/s/c/bin/slideshow.swf" width="600" height="400" flashvars="host=picasaweb.google.com&amp;noautoplay=1&amp;hl=en_US&amp;feat=flashalbum&amp;RGB=0x000000&amp;feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2F105302176970713958800%2Falbumid%2F5592606333103786033%3Falt%3Drss%26kind%3Dphoto%26authkey%3DGv1sRgCMzMq87PmMDMIA%26hl%3Den_US" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-6192062935822522521?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/6192062935822522521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=6192062935822522521' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/6192062935822522521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/6192062935822522521'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/04/london-week-1.html' title='London Week 1'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-3110655879452669751</id><published>2011-04-05T03:42:00.000-07:00</published><updated>2011-04-05T03:42:59.972-07:00</updated><title type='text'>Software Craftsmanship and the pursuit of excellence</title><content type='html'>** Note: I'm intending on doing a weekly blog post about my London experiences, work and otherwise, every Wednesday **&lt;br /&gt;&lt;br /&gt;I went to an interesting panel discussion yesterday titled "How can craftsmanship move the industry forward?" &amp;nbsp;You can watch the podcast &lt;a href="http://skillsmatter.com/podcast/agile-testing/how-can-craftsmanship-move-the-industry-forwards/js-1477"&gt;here&lt;/a&gt;. &amp;nbsp;It was interesting because this is actually a topic that has been weighing heavily on my mind recently. &amp;nbsp;For a bit of background the software craftsmanship manifesto is found &lt;a href="http://manifesto.softwarecraftsmanship.org/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The panel consisted of the following people:&amp;nbsp;&lt;a href="http://redsquirrel.com/dave"&gt;Dave Hoover&lt;/a&gt;, &lt;a href="http://dannorth.net/"&gt;Dan North&lt;/a&gt;,&amp;nbsp;&lt;a href="http://chrismdp.github.com/"&gt;Chris Parsons&lt;/a&gt;, and&amp;nbsp;&lt;a href="http://blog.oshineye.com/"&gt;Ade Oshineye&lt;/a&gt;. It was extremely interesting and in my opinion boiled down to two fundamental questions: How do we, as software developers, most effectively build good code? &amp;nbsp;How do we, as software developers, most effectively build good software developers? &amp;nbsp;Those questions aside though, (I will address my opinions on those in another blog post) in a way the debate came down to the suitability of the Craftsmanship metaphor to software development. &amp;nbsp;I agree with Dan North's &lt;a href="http://dannorth.net/2011/01/11/programming-is-not-a-craft/"&gt;opinion&lt;/a&gt;&amp;nbsp;that programming is not in fact a craft as our clients do not pay us for beautiful code, they pay us for working code that will be able to grow as the business grows. &amp;nbsp;They pay us to meet deadlines and to be pragmatic enough to understand that there are corners that can and should be cut in order to get working software. &amp;nbsp;The bottom line is working, production software is infinitely more valuable than "beautiful" not working or non-deployed software. &lt;br /&gt;&lt;br /&gt;This treads quite closely to the tempest in a teapot last year about the &lt;a href="http://www.joelonsoftware.com/items/2009/09/23.html"&gt;Duct Tape Programmer&lt;/a&gt;. &amp;nbsp;Indeed it was quite interesting to listen to Dan North (Inventor of BDD, so we can safely assume that he knows TDD) state that over the past year only %30 of the code he wrote was TDD. &amp;nbsp;I tweeted a few nights back the following statement: "The two fundamental evils in software development: overly complex code and overly simple code. Finding the balance is the hard part." &amp;nbsp;Do we look at a craftsman in the traditional sense as somebody who find the correct balance between simplicity and complexity? &amp;nbsp;Does a craftsman cut corners to deliver? &amp;nbsp;Does a craftsman know what corners to cut?&lt;br /&gt;&lt;br /&gt;Software development, as far as professions go, is incredibly young. &amp;nbsp;The tools, best practices, languages, etc are changing at a stunning rate. &amp;nbsp;The metaphors we apply to attempt to bring sanity to this rapidly changing environment can be helpful, but at the same time we need to define software development as an&amp;nbsp;independent&amp;nbsp;entity. &amp;nbsp;We only need to look at the metaphor of engineering and big up front design to see how much pain a flawed metaphor can bring.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-3110655879452669751?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/3110655879452669751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=3110655879452669751' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/3110655879452669751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/3110655879452669751'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/04/software-craftsmanship-and-pursuit-of.html' title='Software Craftsmanship and the pursuit of excellence'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-5524852107079752059</id><published>2011-04-02T23:06:00.000-07:00</published><updated>2011-04-02T23:06:16.395-07:00</updated><title type='text'>London and the pursuit of Dreams</title><content type='html'>This blog was created initially in order for me to blog about technical things.  I've had a few people read the blog over the past 2 years or so I've been infrequently posting and am generally happy with it.&lt;br /&gt;&lt;br /&gt;Recently, I moved to London England so I will be changing the focus of my blogging if not the location as well.  A few personal blogs are going to start popping up at least until I have a better blog setup with both a personal and technical section.  Just as to not bore either of my groups of loyal followers.&lt;br /&gt;&lt;br /&gt;So with no further ado, let's talk briefly about London and why I'm here.  There is something interesting about how people grow and come to perceive the place they grow up. I talked to a few people from the UK about my plans, by and large the response was "why would you want to go there?"  Well, aside from the easy answer, "cause" I believe the answer lies in stretching of comfort zones and doing something that, hopefully, will work out really nicely for me.  Too often we find ourselves with regrets, missed opportunities that 5 or 10 years down the road gnaw away at us.  There were more than a few people who told me that they wished that they had done something like what I'm doing when they didn't have pets, kids, a mortgage, etc.&lt;br /&gt;&lt;br /&gt;I operate on the philosophy that you will never regret chasing a dream.  You will only regret not chasing it.  You will never regret the uncertainty that comes with stepping out of your comfort zone and going somewhere different.  Everybody dreams differently, so it's not about packing up your stuff and moving to another continent, but it's about accepting and owning your dreams and making them happen.&lt;br /&gt;&lt;br /&gt;So here I am in London, been here for three days.  This is actually the culmination of a dream that has been bubbling within in me for 10+ years.  To live and work in Europe for a year was the original dream.  So why London?  Generally, people in London speak some form of English, allowing me to get a job!  Additionally, there is an &lt;a href="http://www.workgateways.com/working-visa-tier-5.html"&gt;easy way&lt;/a&gt; for young people like me to get a work visa in England. &amp;nbsp;In the end, there wasn't going to be anything that would have stopped me from making this trip. &amp;nbsp;Had London not been possible, than it would have been Rome or Paris, or Madrid or somewhere else. &amp;nbsp;It's nice though to start somewhere easier. &amp;nbsp;The next two years are likely going to be very interesting and I expect to meet many cool people and have an awesome time.&lt;br /&gt;&lt;br /&gt;Next Post: Either a technical post about Craftsmanship vs Gardening or a personal post on leaving a life behind.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-5524852107079752059?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/5524852107079752059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=5524852107079752059' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5524852107079752059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5524852107079752059'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/04/london-and-pursuit-of-dreams.html' title='London and the pursuit of Dreams'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-8399587828300839337</id><published>2011-03-21T14:25:00.001-07:00</published><updated>2011-03-21T14:25:52.250-07:00</updated><title type='text'>Administer Everything Panel on Windows 7</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;1. Create a folder somewhere&lt;br&gt;2. Rename the folder to “Computer Admin.{ED7BA470-8E54-465E-825C-99712043E01C}”&lt;br&gt;3. ????&lt;br&gt;4. Profit &lt;p&gt;Thanks Keith!!!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-8399587828300839337?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/8399587828300839337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=8399587828300839337' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8399587828300839337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8399587828300839337'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/03/administer-everything-panel-on-windows.html' title='Administer Everything Panel on Windows 7'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-8953744324245951229</id><published>2011-03-10T13:54:00.001-08:00</published><updated>2011-03-10T13:54:14.275-08:00</updated><title type='text'>HttpContextBase–Decoupling your unit tests with IOC</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Using ASP.NET MVC generally leads you to use the HttpContext throughout your code base.&amp;nbsp; General usage is for cookies, query strings, and other general request or response data.&amp;nbsp; The question is, how to you go about testing it?&amp;nbsp; The easiest way to access the HttpContext is from HttpContext.Current.&amp;nbsp; If you use that and then run a unit test, on the code it will fail because HttpContext.Current is null.&amp;nbsp; So ASP MVC provided a handy abstraction called HttpContextBase.&lt;br&gt;The simplest way I found to use the HttpContextBase is as follows:&lt;br&gt; &lt;div 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;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; HttpContextBase httpContext;&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;&amp;nbsp; &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;public&lt;/span&gt; CookieJar(HttpContextBase httpContext)&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;this&lt;/span&gt;.httpContext = httpContext;&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;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The secret in the sauce though is in how we inject that.&amp;nbsp; Using StructureMap we can use this handy mapping:&lt;br&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&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; For&amp;lt;HttpContextBase&amp;gt;().Use(() =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; HttpContextWrapper(HttpContext.Current));&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This means that every time StructureMap runs into HttpContextBase it creates a new HttpContextWrapper around HttpContext.Current.&amp;nbsp; And now, all your service classes are completely unit testable.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-8953744324245951229?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/8953744324245951229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=8953744324245951229' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8953744324245951229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8953744324245951229'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/03/httpcontextbasedecoupling-your-unit.html' title='HttpContextBase–Decoupling your unit tests with IOC'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-2305486239728698593</id><published>2011-02-08T11:28:00.001-08:00</published><updated>2011-02-08T11:41:02.079-08:00</updated><title type='text'>Criminal Code – NORM Mongo Driver – Part 2</title><content type='html'>&lt;div&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;There were a few comments on my last NORM Mongo Driver post and I thought I should clear the air. First off the only purpose of the post was as a learning experience for others, and a warning for anybody hoping to use NORM rather than the 10gen driver.&amp;nbsp; I deeply respect the work the author of the NORM driver did and really was surprised myself on how poorly the published code performed.&amp;nbsp; We have recently completed the migration to the 10gen driver (it supports replica sets, which is very very important to us) but our current production version is running with the NORM driver (+ my fix). For the inquisitive minds, the code fixes are as follows:&lt;/div&gt; &lt;div&gt;Original:&lt;br&gt; &lt;div 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; var stream = _connection.GetStream();&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;while&lt;/span&gt; (!stream.DataAvailable)&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;/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;     Thread.Sleep(1);&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;/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;&amp;nbsp; &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; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!stream.DataAvailable)&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; {&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="lnum9"&gt;   9:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TimeoutException(&lt;span style="color: #006080"&gt;"MongoDB did not return a reply in the specified time for this context: "&lt;/span&gt; + _connection.QueryTimeout.ToString());&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="lnum10"&gt;  10:&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="lnum11"&gt;  11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ReplyMessage&amp;lt;T&amp;gt;(_connection, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._collection, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BinaryReader(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BufferedStream(stream)), MongoOp.Query, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.NumberToTake);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;Fixed (No connection timeout implementation):&lt;br&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&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; var stream = _connection.GetStream();&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;&amp;nbsp; &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;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ReplyMessage&amp;lt;T&amp;gt;(_connection, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._collection, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BinaryReader(stream), MongoOp.Query, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.NumberToTake);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;Fixed (Dynamic sleep time):&lt;br&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&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; var stream = _connection.GetStream();&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;&amp;nbsp; &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; Thread.Sleep(avgWait);&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; var totalSleep = avgWait;&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; var intervalSleep = 2;&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; var neededAdditionalSleep = &lt;span style="color: #0000ff"&gt;false&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="lnum7"&gt;   7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (!stream.DataAvailable || totalSleep &amp;gt; _connection.QueryTimeout)&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; {&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="lnum9"&gt;   9:&lt;/span&gt;     Thread.Sleep(intervalSleep);&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="lnum10"&gt;  10:&lt;/span&gt;     totalSleep += intervalSleep;&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="lnum11"&gt;  11:&lt;/span&gt;     intervalSleep += intervalSleep;&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="lnum12"&gt;  12:&lt;/span&gt;     neededAdditionalSleep = &lt;span style="color: #0000ff"&gt;true&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="lnum13"&gt;  13:&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: #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="lnum14"&gt;  14:&lt;/span&gt;&amp;nbsp; &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="lnum15"&gt;  15:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (neededAdditionalSleep)&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="lnum16"&gt;  16:&lt;/span&gt;     avgWait = (totalSleep + avgWait) / 2; &lt;span style="color: #008000"&gt;// poor mans average wait time&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="lnum17"&gt;  17:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;else&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: #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="lnum18"&gt;  18:&lt;/span&gt;     avgWait /= 2; &lt;span style="color: #008000"&gt;// if we slept too long we have to autocorrect so we aren't always sleeping too long.&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="lnum19"&gt;  19:&lt;/span&gt;&amp;nbsp; &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="lnum20"&gt;  20:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!stream.DataAvailable)&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="lnum21"&gt;  21:&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: #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="lnum22"&gt;  22:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TimeoutException(&lt;span style="color: #006080"&gt;"MongoDB did not return a reply in the specified time for this context: "&lt;/span&gt; + _connection.QueryTimeout.ToString());&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="lnum23"&gt;  23:&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: #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="lnum24"&gt;  24:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ReplyMessage&amp;lt;T&amp;gt;(_connection, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._collection, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BinaryReader(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BufferedStream(stream)), MongoOp.Query, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.NumberToTake);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;div&gt;The code above isn’t exactly the code I profiled while attempting to fix the issue, but it’s roughly the same idea.&amp;nbsp; It looks like the QueryTimeout defaults to 30?, not sure if that’s milliseconds or seconds, so the implementation would have to change slightly.&amp;nbsp; Essentially, we will assume some network latency and sleep for avgWait (static instance variable, initially 1ms) then we will keep track of the total sleep time for averaging.&amp;nbsp; An interval sleep starts a 2ms and will work up exponentially ie 2, 4, 8, 16 etc so that we aren’t thrashing the cpu for downloads that are slow for whatever reason. Afterwards we get a new avgWait, ensure that we haven’t gotten too high because of some really long latency.&amp;nbsp; This code is not tested so it may not work, but it should.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;The code that needs to be fixed is also found in GetMoreMessage.cs Execute(), we don’t appear to be using that so it’s not an issue for us.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Keep in mind that the above solutions are not necessarily the optimal solution to the issue.&amp;nbsp; I don’t know a better solution, and would love to have somebody give one.&amp;nbsp; I spent a pretty long while coming up with the second solution before realizing that the first solution was the best solution for our needs.&lt;/div&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-2305486239728698593?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/2305486239728698593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=2305486239728698593' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/2305486239728698593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/2305486239728698593'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/02/criminal-code-norm-mongo-driver-part-2.html' title='Criminal Code – NORM Mongo Driver – Part 2'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-7441242020218013189</id><published>2011-01-31T04:00:00.001-08:00</published><updated>2011-01-31T04:02:03.449-08:00</updated><title type='text'>ASP MVC–Proxy an Image</title><content type='html'>&lt;p&gt;The app I’ve been working on for the last little while is finally going live. (Thus why I am writing a blog post @ 4:45am)&amp;nbsp; We ran into an issue where some images we were loading up were not accessible to the client.&amp;nbsp; The only quick solution to the problem was to create a proxy using ASP MVC (our technology of choice).&amp;nbsp; This actually turned out to be a rather simple task.&lt;/p&gt; &lt;p&gt;1) Replace the src of the image tags with our own servers&lt;/p&gt; &lt;p&gt;ie: http://&amp;lt;new.url&amp;gt;/entertai//LON101-212_2005_002029_low.jpg&amp;nbsp; converted to http://&amp;lt;our.url&amp;gt;/NewsImage//entertai//LON101-212_2005_002029_low.jpg&lt;/p&gt; &lt;p&gt;2) Wire up a new route in global.asax.cs:&lt;/p&gt; &lt;div 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;routes.MapRoute(&lt;span style="color: #006080"&gt;"NewsImage"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"NewsImage/{Category}/{ImageName}"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; {controller = &lt;span style="color: #006080"&gt;"News"&lt;/span&gt;, action=&lt;span style="color: #006080"&gt;"Image"&lt;/span&gt; });&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;3) Create a new action handler in the controller of choice:&lt;/div&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&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; ActionResult Image(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Category, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ImageName)&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;/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;&amp;nbsp; &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;     var cacheKey = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CompositeCacheKey(Category, ImageName);&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;     var imageResult = (ImageResult)applicationCache.Get(cacheKey);&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;if&lt;/span&gt; (imageResult == &lt;span style="color: #0000ff"&gt;null&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="lnum7"&gt;   7:&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: #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;         ImageFormat format;&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="lnum9"&gt;   9:&lt;/span&gt;&amp;nbsp; &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="lnum10"&gt;  10:&lt;/span&gt;         var path = ConfigurationManager.AppSettings[&lt;span style="color: #006080"&gt;"NewsEndpoint"&lt;/span&gt;] + &lt;span style="color: #006080"&gt;"/"&lt;/span&gt; + Category + &lt;span style="color: #006080"&gt;"/"&lt;/span&gt; + ImageName;&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="lnum11"&gt;  11:&lt;/span&gt;         Image image;&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="lnum12"&gt;  12:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (var client = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WebClient())&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="lnum13"&gt;  13:&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: #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="lnum14"&gt;  14:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;try&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="lnum15"&gt;  15:&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: #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="lnum16"&gt;  16:&lt;/span&gt;                 var data = client.DownloadData(path);&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="lnum17"&gt;  17:&lt;/span&gt;                 var contentType = client.ResponseHeaders[&lt;span style="color: #006080"&gt;"Content-Type"&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: #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="lnum18"&gt;  18:&lt;/span&gt;                 format = mimeTypes[contentType];&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="lnum19"&gt;  19:&lt;/span&gt;                 var ms = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MemoryStream();&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="lnum20"&gt;  20:&lt;/span&gt;                 ms.Write(data, 0, data.Length);&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="lnum21"&gt;  21:&lt;/span&gt;                 image = System.Drawing.Image.FromStream(ms);&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="lnum22"&gt;  22:&lt;/span&gt;&amp;nbsp; &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="lnum23"&gt;  23:&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: #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="lnum24"&gt;  24:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (WebException exception)&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="lnum25"&gt;  25:&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: #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="lnum26"&gt;  26:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; HttpResult(&lt;span style="color: #006080"&gt;"Image error"&lt;/span&gt;, HttpStatusCode.NotFound);&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="lnum27"&gt;  27:&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: #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="lnum28"&gt;  28:&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="lnum29"&gt;  29:&lt;/span&gt;         imageResult = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ImageResult {Image = image, ImageFormat = format};&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="lnum30"&gt;  30:&lt;/span&gt;&amp;nbsp; &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="lnum31"&gt;  31:&lt;/span&gt;         applicationCache.Add(cacheKey, imageResult, DateTime.Now.AddHours(1));&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="lnum32"&gt;  32:&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="lnum33"&gt;  33:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; imageResult;&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="lnum34"&gt;  34:&lt;/span&gt;&amp;nbsp; &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="lnum35"&gt;  35:&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: #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="lnum36"&gt;  36:&lt;/span&gt;&amp;nbsp; &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="lnum37"&gt;  37:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;, ImageFormat&amp;gt; mimeTypes = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;, ImageFormat&amp;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: #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="lnum38"&gt;  38:&lt;/span&gt;                                                         {&lt;span style="color: #006080"&gt;"image/gif"&lt;/span&gt;, ImageFormat.Gif},&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="lnum39"&gt;  39:&lt;/span&gt;                                                         {&lt;span style="color: #006080"&gt;"image/jpeg"&lt;/span&gt;, ImageFormat.Jpeg},&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="lnum40"&gt;  40:&lt;/span&gt;                                                         {&lt;span style="color: #006080"&gt;"image/png"&lt;/span&gt;, ImageFormat.Png},&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="lnum41"&gt;  41:&lt;/span&gt;                                                     };&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Keeping in mind that the code was written @ 2am with a looming go/no go and will be refactored within the next week, the general idea is to use a cached &lt;a href="http://blog.maartenballiauw.be/post/2008/05/13/ASPNET-MVC-custom-ActionResult.aspx" target="_blank"&gt;ImageResult&lt;/a&gt;.&amp;nbsp; This provides us (and our clients) with a significant performance boost.&amp;nbsp; If the ImageResult is not cached, we fetch the image from the original server, use a memory stream to create an Image and then create and store an ImageResult in the cache.&amp;nbsp; Simple, effective and solved a serious problem in a very short amount of time.  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-7441242020218013189?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/7441242020218013189/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=7441242020218013189' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7441242020218013189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7441242020218013189'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/01/asp-mvcproxy-image.html' title='ASP MVC–Proxy an Image'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-5260403586175752422</id><published>2011-01-25T06:27:00.001-08:00</published><updated>2011-01-25T06:27:50.187-08:00</updated><title type='text'>Criminal Code – NORM Mongo Driver</title><content type='html'>&lt;p&gt;&lt;br&gt;I recently spent some time performance tuning the website I am working on.&amp;nbsp; The site was not managing to maintain our peak TPS (transactions per second) and the performance team had concerns with the CPU utilization.&amp;nbsp; So I fired up dot Trace and ran into an interesting little phenomenon - &lt;/p&gt; &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_-DGD9abNBI0/TT7dxQ8Xc6I/AAAAAAAAABk/Dvr3xn0jD_c/s1600-h/2011-01-25_0706%5B5%5D.png"&gt;&lt;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="2011-01-25_0706" border="0" alt="2011-01-25_0706" src="http://lh5.ggpht.com/_-DGD9abNBI0/TT7dxlrw24I/AAAAAAAAABo/3xwhDJMaMc8/2011-01-25_0706_thumb%5B3%5D.png?imgmax=800" width="875" height="122"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It was immediately obvious to me that there was something going on in the Execute method of the Norm driver we are using to communicate with MongoDB.&amp;nbsp; So being that the code is open source, I opened it up and took a look at &lt;a href="https://github.com/atheken/NoRM/blob/master/NoRM/Protocol/Messages/QueryMessageGeneric.cs" target="_blank"&gt;the code&lt;/a&gt;.&lt;/p&gt; &lt;div 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; var stream = _connection.GetStream();&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;while&lt;/span&gt; (!stream.DataAvailable)&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;/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;     Thread.Sleep(1);&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;/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;&amp;nbsp; &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; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!stream.DataAvailable)&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; {&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="lnum9"&gt;   9:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TimeoutException(&lt;span style="color: #006080"&gt;"MongoDB did not return a reply in the specified time for this context: "&lt;/span&gt; + _connection.QueryTimeout.ToString());&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="lnum10"&gt;  10:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;br&gt;To me, this appears to be an attempt to handle connection timeouts – an entirely noble goal.&amp;nbsp; However, it is done in perhaps the worst possible method.&amp;nbsp; Ignoring that the if statement will never execute because the while loop break condition is the same as the if condition.&amp;nbsp; We did some performance testing, running the code above we were able to get 1000 transactions through in 10 minutes (profiled on a dev machine so prod is much faster).&amp;nbsp; With a Thread.Sleep(10) we hit 1300 transactions through in 10 minutes.&amp;nbsp; Removing line 4 and leaving a hot spin, we managed to get 1800 transactions through in 10 minutes. This is not necessarily the expected response to removing a thread sleep, which in theory, allows the cpu to prioritize other threads.&amp;nbsp; Unfortunately, because we have 15 – 30 IIS threads all running at the same time, each of which is constantly requesting then releasing the CPU in the above manner, it turns out that the above code is the least performant option of all.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I spent some time tweaking the above code, using a dynamic sleep time (averaging out the sleep time based on the total sleep time of the previous call) we hit 2500 transactions in 10 minutes.&amp;nbsp; Then, I realized, as I should have earlier, that because the code above does not actually achieve its intended goal of network timeout, I should simply allow the .NET/windows infrastructure handle the issue.&amp;nbsp; Network Stream (I believe all Network.IO.Stream implementations) has a blocking read.&amp;nbsp; A small tweak to the rest of the code in the execute method and I removed the Thread.Sleep all together.&amp;nbsp; We hit 2650 transactions in 10 minutes.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;The lessons from this are 1) Open Source Software is good because if it’s broken, you can take a look under the hood and fix it. 2) Doing a loop over Thread.Sleep(*) is a terrible idea. 3) Dot Trace is an awesome tool for locating and fixing CPU bound performance problems.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;As a note, NORM is no longer supported, we are migrating to the 10gen driver. I have not submitted a patch to this code.&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-5260403586175752422?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/5260403586175752422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=5260403586175752422' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5260403586175752422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5260403586175752422'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/01/criminal-code-norm-mongo-driver.html' title='Criminal Code – NORM Mongo Driver'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_-DGD9abNBI0/TT7dxlrw24I/AAAAAAAAABo/3xwhDJMaMc8/s72-c/2011-01-25_0706_thumb%5B3%5D.png?imgmax=800' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-8457936843799112837</id><published>2011-01-17T14:40:00.001-08:00</published><updated>2011-01-17T14:40:28.081-08:00</updated><title type='text'>Google Chrome Frame – Detecting that Chrome Frame is running</title><content type='html'>&lt;p&gt;&lt;br&gt;My current website was initially designed only to support the most recent version of each browser; Firefox 3.6, IE 8, Chrome and Safari.&amp;nbsp; It turns out that there is a significant part of our user base that can not upgrade from IE 7.&amp;nbsp; We found this out with 3 weeks to go before our prod release – not nearly enough time to rebuild large portions of our site to support IE 7.&amp;nbsp; So the decision was to support &lt;a href="http://code.google.com/chrome/chromeframe/" target="_blank"&gt;Chrome Frame&lt;/a&gt; – an IE plugin that renders webpages using Chrome’s rendering engine rather than IE’s.&lt;br&gt;&lt;br&gt;Problem Solved… right?&amp;nbsp; Wrong.&lt;br&gt;&lt;br&gt;Unfortunately, Chrome Frame fails when you fire up a popup window that redirects to an external site.&amp;nbsp; This is because Chrome Frame activates depending meta data in the http response headers; Unless the web site you are browsing explicitly states that it uses chrome frame, you will not see the site in Chrome Frame.&amp;nbsp; The unfortunate consequence of this is that when a popup is created, even if you are pointing at a local site, which should open in chrome frame, if the popup does a redirect, Chrome Frame is closed.&amp;nbsp; This means that you lose all scriptability between your popup and your original page. window.opener will return null.&amp;nbsp; Before anybody states that you shouldn’t use popups, the reasoning is for twitter or facebook logins.&amp;nbsp; IFrames would have the same issue.&lt;br&gt;&lt;br&gt;This unfortunate issue means that users can not properly use some of our functionality as they rely heavily on scripting between the popup and window.opener.&amp;nbsp; The underlying functionality still works, but requires the user to manually refresh the initial page.&amp;nbsp; The only solution that we could easily implement was to message the users that are using Chrome Frame and let them know that they would need to kill the popup and refresh the page (usability nightmare, but necessary for now).&amp;nbsp; An alternative option would be a reverse proxy for our external calls and force them to render in Chrome Frame.&amp;nbsp; Not enough time for that.&lt;br&gt;&lt;br&gt;So I set out to figure out how to determine if you are using Chrome Frame.&amp;nbsp; The first stop was Chrome Frame’s own javascript.&amp;nbsp; Unfortunately, it only checked if you ARE NOT using Chrome Frame and recommends that you install it.&amp;nbsp; Next stop was checking the userAgent using javascript: navigator.userAgent; this returned the Chrome user agent rather than the Chrome Frame user agent and was not terribly helpful as we couldn’t differentiate between Chrome and Chrome Frame.&lt;br&gt;&lt;br&gt;Following this, we realized that a http request originating in Chrome Frame would send a chromeframe user agent to the server and we could determine if you were using Chrome Frame – except for the first call, which would be IE or whatever other browser you were using.&amp;nbsp; This is because there is no way for the browser to know it’s going to need to use Chrome Frame until after the first response.&lt;br&gt;&lt;br&gt;The solution therefore, was for us to use a ActionFilter (asp.net mvc) to add the header to any response for a request coming from IE 6 or 7 or Chrome Frame.&amp;nbsp; Additionally, since it’s not possible to access http headers from Javascript, we had to set a cookie called isChromeFrame.&amp;nbsp; Then, within our javascript we check for the cookie and, if it exists, show the message explaining what the user should do.&lt;br&gt;&lt;br&gt;Clear as mud?&amp;nbsp; Good, I thought so too.&amp;nbsp; Sigh…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-8457936843799112837?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/8457936843799112837/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=8457936843799112837' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8457936843799112837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8457936843799112837'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/01/google-chrome-frame-detecting-that.html' title='Google Chrome Frame – Detecting that Chrome Frame is running'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-5446840489213525672</id><published>2011-01-11T09:19:00.001-08:00</published><updated>2011-01-11T09:22:18.714-08:00</updated><title type='text'>Epic WTF</title><content type='html'>&lt;p&gt;I don’t usually like to pick on other people’s code; Everybody has written code they are not proud of.&amp;nbsp; In this particular case, I had to shake my head at this implementation.&amp;nbsp; I will use this opportunity though, to show some jquery that could be used to greatly simplify this code.&lt;/p&gt; &lt;div 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: #0000ff"&gt;var&lt;/span&gt; MastheadScript = {};&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;MastheadScript.scripts = document.getElementsByTagName(&lt;span style="color: #006080"&gt;'script'&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;MastheadScript.scriptId = (MastheadScript.scripts.length - 1);&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: #0000ff"&gt;var&lt;/span&gt; i;&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: #0000ff"&gt;for&lt;/span&gt; (i=0;i&amp;lt;=( MastheadScript.scripts.length - 1);i++) {&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: #0000ff"&gt;if&lt;/span&gt; ( MastheadScript.scripts[i].src != &lt;span style="color: #006080"&gt;''&lt;/span&gt; &amp;amp;&amp;amp; MastheadScript.scripts[i].src.match(&lt;span style="color: #006080"&gt;'&amp;lt;snip&amp;gt;some regex&amp;lt;/snip&amp;gt;'&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: #0000ff"&gt;var&lt;/span&gt; defaultMastheadOptions = {&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: #008000"&gt;// &amp;lt;snip&amp;gt;&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: #008000"&gt;// some options &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: #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: #008000"&gt;// &amp;lt;/snip&amp;gt;&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;/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;    i = MastheadScript.scripts.length + 1;&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;/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: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ( MastheadScript.scripts[i].src != &lt;span style="color: #006080"&gt;''&lt;/span&gt; &amp;amp;&amp;amp; MastheadScript.scripts[i].src.match(&lt;span style="color: #006080"&gt;'&amp;lt;snip&amp;gt;some regex other regex&amp;lt;/snip&amp;gt;'&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: #0000ff"&gt;var&lt;/span&gt; defaultMastheadOptions = {&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: #008000"&gt;// &amp;lt;snip&amp;gt;&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: #008000"&gt;// some options (actually are the same as the previous options)&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: #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: #008000"&gt;// &amp;lt;/snip&amp;gt;&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;/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;    i = MastheadScript.scripts.length + 1;&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;/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;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;The issue with this code is not the probable performance issue in iterating through all of the scripts on a page (shouldn’t be many, but could be) but rather the readability issue.&amp;nbsp; It took me a while to understand the code and what it was attempting to accomplish.&amp;nbsp; So the main issue is the maintainability.&amp;nbsp; I mean seriously, why would you ever use i = MastheadScript.scripts.length + 1 instead of just break?&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br&gt;Regardless, here is the better solution using jQuery:&lt;br&gt;&lt;br&gt;&lt;br /&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: #0000ff"&gt;var&lt;/span&gt; labsScript = $(&lt;span style="color: #006080"&gt;'script'&lt;/span&gt;).filter(&lt;span style="color: #0000ff"&gt;function&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: #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: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.attr(&lt;span style="color: #006080"&gt;'src'&lt;/span&gt;).match(/&amp;lt;snip&amp;gt;some regex&amp;lt;/snip&amp;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;/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;&amp;nbsp;&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: #0000ff"&gt;if&lt;/span&gt; (labsScript)&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: #0000ff"&gt;var&lt;/span&gt; defaultMastheadOptions = {&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: #008000"&gt;// &amp;lt;snip&amp;gt;&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: #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: #008000"&gt;// some options&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: #008000"&gt;// &amp;lt;/snip&amp;gt;&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: #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;/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: #0000ff"&gt;else&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: #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: #0000ff"&gt;var&lt;/span&gt; defaultMastheadOptions = {&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: #008000"&gt;// &amp;lt;snip&amp;gt;&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: #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: #008000"&gt;// some options (actually are the same as the previous options) :-/&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: #008000"&gt;// &amp;lt;/snip&amp;gt;&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: #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;/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;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Identical functionality – readability/maintainability %100 improved.&amp;nbsp; Software development isn’t just about making things work, it’s also about making it maintainable.&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-5446840489213525672?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/5446840489213525672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=5446840489213525672' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5446840489213525672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5446840489213525672'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2011/01/epic-wtf.html' title='Epic WTF'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-6650851678248483402</id><published>2010-12-30T17:23:00.001-08:00</published><updated>2010-12-30T17:35:45.799-08:00</updated><title type='text'>A Cookie Temp Data Provider</title><content type='html'>&lt;p&gt;&lt;br&gt;At my current work place we are using ASP.MVC to build a webpage.&amp;nbsp; We used the TempData collection in order to provide error/success messages for redirect calls such as RedirectToAction.&amp;nbsp; To step back quickly, TempData is used when you want to store an object for a successive server request.&amp;nbsp; It’s pretty nifty especially for error/success messages.&amp;nbsp; By default, ASP.MVC stores your TempData collection in the ASP Session which is fine, unless you have multiple sessions; Sticky sessions could solve the problem, but they have their own set of issues from an infrastructure point of view.&lt;/p&gt; &lt;p&gt;In order to solve this, the team decided to use cookies to store TempData.&amp;nbsp; Fortunately, the ASP.MVC framework gives you a simple way to do this requiring one simple class implementation.&lt;/p&gt; &lt;div 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: #008000"&gt;/// &amp;lt;summary&amp;gt;&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: #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: #008000"&gt;/// This class is used to override the default temp data provider which uses session to store the temp data&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: #008000"&gt;/// It utilizes the request and response cookies to read and store the temp data collection.&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: #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: #008000"&gt;/// You do not have to worry about clearing the data when you load the temp data as the ASP.MVC infrastructure&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: #008000"&gt;/// deals with this.&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: #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: #008000"&gt;/// &amp;lt;/summary&amp;gt;&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: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; CookieTempDataProvider : ITempDataProvider&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;/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: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; TempDataCookieKey = &lt;span style="color: #006080"&gt;"__ControllerTempData"&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: #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;    IDictionary&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;gt; ITempDataProvider.LoadTempData(ControllerContext controllerContext)&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;/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;        var cookie = controllerContext.HttpContext.Request.Cookies[TempDataCookieKey];&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: #0000ff"&gt;if&lt;/span&gt; (cookie != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; !&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(cookie.Value))&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: #0000ff"&gt;return&lt;/span&gt; cookie.Value.DeserializeBase64EncodedString();&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: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;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: #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;/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;&amp;nbsp;&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: #0000ff"&gt;void&lt;/span&gt; ITempDataProvider.SaveTempData(ControllerContext controllerContext, IDictionary&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;gt; values)&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;/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;        var isEmpty = values.Count == 0;&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;        var cookieValue = isEmpty ? &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty : values.SerializeToBase64EncodedString();&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;        var cookie = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; HttpCookie(TempDataCookieKey) { HttpOnly = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, Value = cookieValue };&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: #0000ff"&gt;if&lt;/span&gt; (isEmpty)&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;            cookie.Expires = SystemTime.Now().AddDays(-1);&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;        controllerContext.HttpContext.Response.Cookies.Add(cookie);&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;/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;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;and the extension methods used:&lt;/p&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&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: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; IDictionaryExtensions&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;/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: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; IDictionary&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;gt; DeserializeBase64EncodedString(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; base64EncodedSerializedTempData)&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;/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;        var bytes = Convert.FromBase64String(base64EncodedSerializedTempData);&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;        var memStream = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MemoryStream(bytes);&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;        var binFormatter = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BinaryFormatter();&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: #0000ff"&gt;return&lt;/span&gt; binFormatter.Deserialize(memStream, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;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;/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;&amp;nbsp;&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: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; SerializeToBase64EncodedString(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; IDictionary&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;gt; values)&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;/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;        var memStream = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MemoryStream();&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;        memStream.Seek(0, SeekOrigin.Begin);&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;        var binFormatter = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BinaryFormatter();&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;        binFormatter.Serialize(memStream, values);&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;        memStream.Seek(0, SeekOrigin.Begin);&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: #0000ff"&gt;byte&lt;/span&gt;[] bytes = memStream.ToArray();&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: #0000ff"&gt;return&lt;/span&gt; Convert.ToBase64String(bytes);&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;/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;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;And finally, adding it to your controllers is as easy as (within your IocControllerFactory):&lt;/p&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;br /&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: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; IController GetControllerInstance(RequestContext requestContext, Type controllerType)&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;/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: #0000ff"&gt;lock&lt;/span&gt; (Padlock)&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;/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: #0000ff"&gt;if&lt;/span&gt; (controllerType == &lt;span style="color: #0000ff"&gt;null&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: #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: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.GetControllerInstance(requestContext, controllerType);&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;&amp;nbsp;&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;        var parameter = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Parameter(&lt;span style="color: #006080"&gt;"requestContext"&lt;/span&gt;, requestContext, &lt;span style="color: #0000ff"&gt;false&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;        var controller = kernel.TryGet(controllerType, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt;[] { parameter }) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; IController ??&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: #0000ff"&gt;base&lt;/span&gt;.GetControllerInstance(requestContext, controllerType);&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;/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;        (controller &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Controller).TempDataProvider = kernel.Get&amp;lt;ITempDataProvider&amp;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;&amp;nbsp;&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: #0000ff"&gt;return&lt;/span&gt; controller;&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;/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;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;And there you have it.&amp;nbsp; You could easily extend this to also hit any database you like, flat files and random markup languages.&amp;nbsp; Enjoy!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-6650851678248483402?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/6650851678248483402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=6650851678248483402' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/6650851678248483402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/6650851678248483402'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2010/12/cookie-temp-data-provider.html' title='A Cookie Temp Data Provider'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-1800601465213432451</id><published>2010-12-30T13:06:00.001-08:00</published><updated>2010-12-30T13:06:47.632-08:00</updated><title type='text'>My Developer Resolutions for 2011</title><content type='html'>&lt;p&gt;&lt;a href="http://scottmuc.com/"&gt;Scott Muc&lt;/a&gt; posted his &lt;a href="http://scottmuc.com/blog/development/my-developer-resolutions-for-2011/" target="_blank"&gt;developer resolutions&lt;/a&gt; for 2011 and that got me thinking; I should figure out what my developer resolutions are!&lt;/p&gt; &lt;p&gt;I didn’t make any resolutions last year (at least not from a development perspective) so I can’t really go over any from last year.&amp;nbsp; However, this next year is a year full of possibilities.&lt;/p&gt; &lt;h1&gt;&lt;strong&gt;Development Goals for 2011:&lt;/strong&gt;&lt;/h1&gt; &lt;h4&gt;&lt;/h4&gt; &lt;h3&gt;Learn Objective-C&lt;/h3&gt; &lt;p&gt;Hate to say it, but the work I’ve done so far with Objective-C has been pretty hacky.&amp;nbsp; Lots of code &amp;amp; pray and coding by coincidence.&amp;nbsp; Need to bring my TDD skills to bear on this Objective-C thing and actually write some decent code.&amp;nbsp; Time to actually read and understand some of the plethora of books on the topic.&amp;nbsp; Granted, this goal can not and should not trump my next goal.&lt;/p&gt; &lt;h3&gt;Complete (to the iPhone app store) the Gazillion Dollar Idea™ I am working on&lt;/h3&gt; &lt;p&gt;I’ve found that iPhone development can be quite painful, (see goal above) and I often go three steps forward than spend 4 hours trying to figure out which step I did wrong.&amp;nbsp; It’s been a learning process and often times, learning processes end as just learning processes.&amp;nbsp; My resolution is to continue to soldier on until I can put something on the app store.&lt;/p&gt; &lt;h3&gt;Write more to this blog&lt;/h3&gt; &lt;p&gt;As part of the above Gazillion Dollar Idea™, I have learnt a lot of cool, rather poorly documented things about iPhone development.&amp;nbsp; I need to blog more about that stuff.&amp;nbsp; I’ve also learned about jQuery, Powershell, CSS, etc.&amp;nbsp; This things should be shared at least a little bit.&amp;nbsp; So I’m going to try to blog more.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-1800601465213432451?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/1800601465213432451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=1800601465213432451' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1800601465213432451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1800601465213432451'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2010/12/my-developer-resolutions-for-2011.html' title='My Developer Resolutions for 2011'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-2415644636993466623</id><published>2009-07-21T08:59:00.000-07:00</published><updated>2009-07-21T09:33:16.854-07:00</updated><title type='text'>Nhibernate Disjunction</title><content type='html'>As I use NHibernate more, I have been learning a bit about the criteria (very slick) and today I learned a really nice piece of functionality in NHibernate 2.0:&lt;br /&gt;&lt;br /&gt;Original Code:&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;criteria.CreateCriteria(GetFieldName(x =&amp;gt; x.MessageStatus))&lt;br /&gt;  .Add(Restrictions.Or(&lt;br /&gt;       Restrictions.Eq(GetFieldName&amp;lt;MessageStatus&amp;gt;(x =&amp;gt; x.Status), FailedDeliveringStatus.State),&lt;br /&gt;       Restrictions.Or(&lt;br /&gt;       Restrictions.Eq(GetFieldName&amp;lt;MessageStatus&amp;gt;(x =&amp;gt; x.Status), FailedEntryToAwaitingProcessingStatus.State),&lt;br /&gt;       Restrictions.Or(&lt;br /&gt;       Restrictions.Eq(GetFieldName&amp;lt;MessageStatus&amp;gt;(x =&amp;gt; x.Status), FailedProcessingStatus.State),&lt;br /&gt;       Restrictions.Eq(GetFieldName&amp;lt;MessageStatus&amp;gt;(x =&amp;gt; x.Status), FailedLegacyWriteStatus.State)))));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;New Code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;criteria.CreateCriteria(GetFieldName(x =&amp;gt; x.MessageStatus))&lt;br /&gt;  .Add(Restrictions.Disjunction()&lt;br /&gt;  .Add(Restrictions.Eq(GetFieldName&amp;lt;MessageStatus&amp;gt;(x =&amp;gt; x.Status), FailedDeliveringStatus.State))&lt;br /&gt;  .Add(Restrictions.Eq(GetFieldName&amp;lt;MessageStatus&amp;gt;(x =&amp;gt; x.Status), FailedEntryToAwaitingProcessingStatus.State))&lt;br /&gt;  .Add(Restrictions.Eq(GetFieldName&amp;lt;MessageStatus&amp;gt;(x =&amp;gt; x.Status), FailedProcessingStatus.State))&lt;br /&gt;  .Add(Restrictions.Eq(GetFieldName&amp;lt;MessageStatus&amp;gt;(x =&amp;gt; x.Status), FailedLegacyWriteStatus.State))&lt;br /&gt;  .Add(Restrictions.Eq(GetFieldName&amp;lt;MessageStatus&amp;gt;(x =&amp;gt; x.Status), FailedNotificationStatus.State)));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As you can see, much nicer.  The Disjunction makes the code much easier to read and modify.&lt;br /&gt;&lt;br /&gt;In case you are wondering this is the code for GetFieldName:&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GetFieldName(Expression&amp;lt;Func&amp;lt;DomainType, &lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt;&amp;gt; expression)&lt;br /&gt;    {&lt;br /&gt;      var name = expression.ToString();&lt;br /&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; Regex.Match(name, &lt;span class="str"&gt;@"\.(.*)"&lt;/span&gt;)&lt;br /&gt;        .Groups[1].Value;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GetFieldName&amp;lt;TObjectType&amp;gt;(Expression&amp;lt;Func&amp;lt;TObjectType, &lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt;&amp;gt; expression)&lt;br /&gt;    {&lt;br /&gt;      var name = expression.ToString();&lt;br /&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; Regex.Match(name, &lt;span class="str"&gt;@"\.(.*)"&lt;/span&gt;)&lt;br /&gt;        .Groups[1].Value;&lt;br /&gt;    }&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-2415644636993466623?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/2415644636993466623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=2415644636993466623' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/2415644636993466623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/2415644636993466623'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/07/nhibernate-disjunction.html' title='Nhibernate Disjunction'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-1300131309338492138</id><published>2009-06-11T16:28:00.000-07:00</published><updated>2009-06-11T17:04:03.448-07:00</updated><title type='text'>Dev Teach 2009 - Day 3 Session Six</title><content type='html'>Oren Eini - Advanced Usages of IoC&lt;br /&gt;&lt;br /&gt;So looks like this might be more of a questions &amp; answer session.  So we are asking the questions right now.&lt;br /&gt;&lt;br /&gt;- IOC exists to help manage complexity.&lt;br /&gt;&lt;br /&gt;- Many people go to IoC for testing &amp; Mocking.  This is incorrect.  IoC is actually about managing complexity.  The testing/mocking are just side benefits.&lt;br /&gt;&lt;br /&gt;5:46 - XML configuration is the root of all evil when it comes to IoC. (Oren says that Women are the root of all evil... his humour is so similiar to Sean's) XML violates the DRY principles.  Why are we repeating the name of the class within the XML?&lt;br /&gt;&lt;br /&gt;5:50 - I like IoC conventions! So pretty in windsor... mmmm.  Using conventions means that every piece of your application behaves in the same manner.  This is really cool and allows your developers to "Fall into the pit of success"&lt;br /&gt;&lt;br /&gt;5:55 - Depth dive into windsor use.&lt;br /&gt;&lt;br /&gt;I'm tired, no more notes!&lt;br /&gt;&lt;br /&gt;Cheerio!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-1300131309338492138?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/1300131309338492138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=1300131309338492138' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1300131309338492138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1300131309338492138'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-day-3-session-six.html' title='Dev Teach 2009 - Day 3 Session Six'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-8370572346738120000</id><published>2009-06-11T14:27:00.000-07:00</published><updated>2009-06-11T15:08:02.518-07:00</updated><title type='text'>Dev Teach 2009 - Day 3 Session Five</title><content type='html'>Michael Stiefel - Are Agile and Domain Modeling Frenemies?&lt;br /&gt;&lt;br /&gt;This guy destroyed my mind last time he spoke.  Let's see what comes about this time.  (Considering that my minds was destroyed by the last talk)&lt;br /&gt;&lt;br /&gt;4:00 - I guess this talk will be more of a discussion rather than a talk.  Should still gain something but I imagine that the notes might be difficult&lt;br /&gt;&lt;br /&gt;Domain Modeling implies creating most of the domain in advance, this flies in the face of the YAGNI concept.  So the question is how can they interact happily.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-8370572346738120000?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/8370572346738120000/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=8370572346738120000' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8370572346738120000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8370572346738120000'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-day-3-session-five.html' title='Dev Teach 2009 - Day 3 Session Five'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-6137324063369024090</id><published>2009-06-11T13:27:00.000-07:00</published><updated>2009-06-11T14:21:19.878-07:00</updated><title type='text'>Dev Teach 2009 - Day 3 Session Four</title><content type='html'>Mmmm lunch.  Not a phenomenal lunch, but not bad.&lt;br /&gt;&lt;br /&gt;Greg Young - Unleash Your Domain&lt;br /&gt;&lt;br /&gt;The talk is about architecture with a domain driven design applications.  Mixing a ddd with service based application.&lt;br /&gt;&lt;br /&gt;2:30 - Generally people say that ddd is useful for business applications, since it doesn't matter what the performance is.&lt;br /&gt;&lt;br /&gt;Greg says that you can get high performance and use domain models.  20000 calls per second in the application that he was working on.&lt;br /&gt;&lt;br /&gt;2:32 - Talking about Audit logs.  What happens if you can't prove that your audit is correct?  What's the point of the audit?  Hansel and Gretal had an audit trail, but the animals eat their audit log, so they were completely lost.&lt;br /&gt;&lt;br /&gt;2:34 - State transitions are an important part of our problem space and should be modeled within our domain.  There was a specific reason that the state changed.&lt;br /&gt;&lt;br /&gt;2:35 - How do explicit state transitions help with auditing?  If redo behaviors on an object then you should be able to get back to the state that you had before.  Since you have explicit state transitions, you know that your audit log is correct because you are able to recreate the object from your audit log. (I don't know if I am really understanding this myself so forgive me if it makes no sense)&lt;br /&gt;&lt;br /&gt;2:41 - So every behaviour on an object is a "command".  The model is additive only, you never remove something from the objects, you send a behavior called "Remove 1". If you have many, many commands that need to be put in the audit log, you can use "rolling snapshots", so you mark spots along the chain of behaviors.  That way you have specific knowledge of the state throughout it's history.&lt;br /&gt;&lt;br /&gt;2:44 - My head hurts.&lt;br /&gt;&lt;br /&gt;2:45 - So essentially, if I understand correctly, your database basically only has one table, which is just a list of commands that build objects.  Then when we want to partition across multiple machines it's really easy.&lt;br /&gt;&lt;br /&gt;2:50 - Since we don't have any state normalized in a database we need to provide this.&lt;br /&gt;&lt;br /&gt;A single model cannot be appropriate for reporting, searching and transactional behaviors.  Reporting is anything from the database that doesn't mean get the object by id so I can update it.&lt;br /&gt;&lt;br /&gt;This is a circular picture.&lt;br /&gt;&lt;br /&gt;Map DTO from Domain -&gt; &lt;br /&gt;Edit DTO in UI -&gt; We don't really edit data, we do behaviors on the object.  We don't edit a persons address, we move them to a new location.&lt;br /&gt;Send DTO to Server -&gt; &lt;br /&gt;Map Data from DTO to Domain -&gt; &lt;br /&gt;Save Domain Object(s) -&gt; &lt;br /&gt;Repeat&lt;br /&gt;&lt;br /&gt;The model that a client needs the data in a distributed system is screen based and different than the domain model.&lt;br /&gt;&lt;br /&gt;There is now a picture from the bottom of a golf cup.  We are supposed to use a different perspective.&lt;br /&gt;&lt;br /&gt;2:55 - Our read data is already stale as soon as we show the data to the user.  We don't need consistency on read data because as soon as you show the data then the data has changed.  Therefore we can split the queries away from the write and the data.  Writes on the other hand require absolute consistency.&lt;br /&gt;&lt;br /&gt;2:57 - Getters and Setters are a domain anti-pattern.  They are actually the smell of procedural code.  Basically I think that we don't have to have getters or setters when we focus on behaviors rather than state.  Since we are using the command query separation, we are side stepping the issue of setters.  The domain objects themselves should be maintaining their inner state.&lt;br /&gt;&lt;br /&gt;3:05 - I am so confused.&lt;br /&gt;&lt;br /&gt;3:05 - When the data from your domain context changes, your reporting context should be listening to events thrown by the domain context.  Event streaming provides a way for other systems to integrate with us as it allows them to handle information as it comes.  Increases system up town.&lt;br /&gt;&lt;br /&gt;3:07 - Most Bounded Contexts can interact with relaxed consistency.&lt;br /&gt;&lt;br /&gt;"Man acts as though he were the shaper and master of language, while in fact it is language that is the master of man"&lt;br /&gt;&lt;br /&gt;Events are past tense, Behaviors are imperative.  These events are not to be confused with events from the dot net framework.&lt;br /&gt;&lt;br /&gt;Coming into your domain, you have have events and commands, commands you can reject.  If you have a problem with the events the problem is with your system.&lt;br /&gt;&lt;br /&gt;3:15 - Getters and Setters are an anti-pattern.  Avoid them&lt;br /&gt;Relax consistency between systems or you constrain your availability.  Your system is only as strong as the weakest link.&lt;br /&gt;&lt;br /&gt;A single model is never appropriate for all behaviors within your system.  Reporting, searching, and transactional behaviors.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I think I understand... my head kinda hurts but I think I understand.  This is a really different way to think about architecture but I think it makes alot of sense.&lt;br /&gt;&lt;br /&gt;I want to revisit this post as I need to spend some time to understand it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-6137324063369024090?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/6137324063369024090/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=6137324063369024090' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/6137324063369024090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/6137324063369024090'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-day-3-session-four.html' title='Dev Teach 2009 - Day 3 Session Four'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-5402297613437310799</id><published>2009-06-11T10:59:00.000-07:00</published><updated>2009-06-11T11:56:42.526-07:00</updated><title type='text'>Dev Teach 2009 - Day 3 Session Three</title><content type='html'>D'Arcy Lussier - Architecting Software in Silverlight&lt;br /&gt;&lt;br /&gt;Well after the last barn burner, let's see what D'Arcy has to teach!&lt;br /&gt;&lt;br /&gt;12:04 - We are going over the fact that Silverlight is different than ASP.NET or WinForms, so you have to ensure that you are not bringing notions from those technologies.&lt;br /&gt;&lt;br /&gt;12:06 - What is Silverlight?&lt;br /&gt;- Rich client-side technology&lt;br /&gt;- New platform for creating browser-based applications (3.0 will (maybe) allow for offline support)&lt;br /&gt;- Not a replacement for ASP.NET (or ASP.NET MVC).  Silverlight should not be considered an alternative, but rather should be considered complimentary.&lt;br /&gt;- Microsoft is highly invested in this technology.&lt;br /&gt;&lt;br /&gt;12:08 - When you are considering Silverlight, you need to think about it first.  It is not the hammer that can hammer anything.&lt;br /&gt;&lt;br /&gt;#1- Identify the scenario(s) - keep in mind if Silverlight is the right fit.&lt;br /&gt;#2- Understand the tradeoffs.&lt;br /&gt;#3- Be prepared to relearn as Silverlight is a new technology and how you used to do it won't necessarily be the right way.&lt;br /&gt;&lt;br /&gt;12:10 - Differences:&lt;br /&gt;&lt;br /&gt;ASP.NET - Server Side Technology&lt;br /&gt;WinForms - Client Side Technology with deployment&lt;br /&gt;Silverlight - Client Side Technology with no deployment.  While you are not deploying it, there is still a download required, so make sure to think about it.&lt;br /&gt;&lt;br /&gt;12:11 - Some guy just razzed on my for typing too loudly.  I almost swore at him, but thought that would be unprofessional.&lt;br /&gt;&lt;br /&gt;Persistence&lt;br /&gt;ASP.NET - Cookies, Session, QueryString, Database&lt;br /&gt;Winforms - Local file system, Database&lt;br /&gt;Silverlight - Isolated storage &lt;br /&gt;-&gt; You don't get any direct connections to databases.  You need to WCF to get your domain stuff.  You also don't have the ability to access the filesystem.  Silverlight applications get 1mg of storage space, if you need more, then you will need to prompt the user.  What happens if they don't let you?  They could also disable the isolated storage all together.  There is db4o which can run within the isolated storage to give you a DB if you want to.&lt;br /&gt;&lt;br /&gt;12:19 - Communication&lt;br /&gt;You have to use WCF to communicate outside of a Silverlight Application&lt;br /&gt;&lt;br /&gt;Security&lt;br /&gt;ASP.NET &amp; WinForms are rich and mature.&lt;br /&gt;&lt;br /&gt;Silverlight&lt;br /&gt;- Client Side - Sandboxed&lt;br /&gt;- Client Side - Restricted Resource Access&lt;br /&gt;- Client Side - Open User Access (if anybody can browse to the .xap file, they can access the application, if you are using ASP.NET you might want to use the ASP.NET security to provide access security)&lt;br /&gt;- Communications - Cross Domain Complexity (if you want to access anything outside of the domain (devteach.com -&gt; amazon.com) sounds complex, there is a cross domain file.&lt;br /&gt;&lt;br /&gt;12:26&lt;br /&gt;Support&lt;br /&gt;ASP.NET - Well supported.&lt;br /&gt;WinForms - RIP... have you met my friend WPF?&lt;br /&gt;Silverlight - Moving Fast, Relies on Community.  Therefore, there isn't quite as much support available for it.  The silverlight team is committed to doing quick turnaround on features.  It should move fast!  Silverlight 3 is looking like it will be release in July.  There isn't the established base that you would find in the other two technologies, so it will take longer to build the software.&lt;br /&gt;&lt;br /&gt;12:30&lt;br /&gt;Tooling&lt;br /&gt;Blend is a must for 2.0 but will still be important for 3.0&lt;br /&gt;Don't underestimate learning curve for XAML of how properties, binding, etc, work within Silverlight.&lt;br /&gt;Blend is the microsoft tool to create XAML and is supposed to work really well.&lt;br /&gt;2010 will be better than 2008 as far as XAML support.&lt;br /&gt;&lt;br /&gt;12:33&lt;br /&gt;Architecture&lt;br /&gt;Silverlight&lt;br /&gt;Architecture patterns like MVVM which focus on utilizing databinding features of Silverlight.  MVVM is worth learning about because it allows better databinding.  In Silverlight (and WPF) you don't have the choice but to use databinding.  So MVVM was created to deal with the issues that we used to have in winforms with databinding.&lt;br /&gt;&lt;br /&gt;Guidance like Prism (Composite Application Block) from Microsoft on how to separate concerns in an application.&lt;br /&gt;&lt;br /&gt;12:48 &lt;br /&gt;Question time!&lt;br /&gt;&lt;br /&gt;If your code isn't obfuscated in Silverlight, then the users can see all your Intellectual Property.  WCF would solve most of this problem.&lt;br /&gt;&lt;br /&gt;LUNCH TIME!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-5402297613437310799?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/5402297613437310799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=5402297613437310799' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5402297613437310799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5402297613437310799'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-day-3-session-three.html' title='Dev Teach 2009 - Day 3 Session Three'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-7076137892566973203</id><published>2009-06-11T09:27:00.000-07:00</published><updated>2009-06-11T10:56:25.375-07:00</updated><title type='text'>Dev Teach 2009 - Day 3 Session Two</title><content type='html'>James Kovacs - Convention-over-Configuration in a .NET World&lt;br /&gt;&lt;br /&gt;Here we are again with James Kovacs.  Should be another pretty interesting talk.&lt;br /&gt;&lt;br /&gt;10:34 - &lt;br /&gt;.NET is historically configuration based&lt;br /&gt;- App/web.config&lt;br /&gt;- IoC config&lt;br /&gt;- ORM config&lt;br /&gt;- Mappers&lt;br /&gt;- Event Handlers&lt;br /&gt;&lt;br /&gt;10:35 - &lt;br /&gt;Ruby (Ruby on Rails) was a game changer, as it is mostly convention based. Very convention based, as long as you do the right thing, then it will just work.  It appears that there are many things that allow for pure convention, if you want to add a field to your class, you just need to add the column to the database.&lt;br /&gt;&lt;br /&gt;10:42&lt;br /&gt;Supporting Conventions&lt;br /&gt;- NHibernate/Fluent NHibernate&lt;br /&gt;- AutoMapper (Very recent)&lt;br /&gt;- Castle Windsor&lt;br /&gt;- ASP.NET MVC&lt;br /&gt;- FubuMVC&lt;br /&gt;- jQuery/jQuery UI&lt;br /&gt;&lt;br /&gt;10:58&lt;br /&gt;James spent the last 20ish minutes explaining the above technologies.  I like AutoMapper concept.&lt;br /&gt;&lt;br /&gt;11:08 - &lt;a href="http://www.codeplex.com/AutoMapper"&gt;AutoMapper&lt;/a&gt; is super slick.&lt;br /&gt;&lt;br /&gt;Automapper really only flattens structures (domain -&gt; dto/view object), you can't go the other way as generally you shouldn't be setting domain values without some thought/validation.&lt;br /&gt;&lt;br /&gt;11:21 - you can map to an interface using AutoMapper, not really sure of the value, but it's there.&lt;br /&gt;&lt;br /&gt;11:45 - rest of the talk focused on nHibernate Fluent Configuration.  Interesting talk, but I've seen most of it before.  except Automapper.  Very cool.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-7076137892566973203?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/7076137892566973203/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=7076137892566973203' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7076137892566973203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7076137892566973203'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-day-3-session-two.html' title='Dev Teach 2009 - Day 3 Session Two'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-2333279414949690500</id><published>2009-06-11T08:02:00.000-07:00</published><updated>2009-06-11T09:08:16.841-07:00</updated><title type='text'>Dev Teach 2009 - Day 3 Session One</title><content type='html'>Oren Eini - Building Domain Specific Languages in Boo&lt;br /&gt;&lt;br /&gt;What are Domain Specific Languages?&lt;br /&gt;&lt;br /&gt;9:04 - Second introduction to DSLs&lt;br /&gt;&lt;br /&gt;Domain Specific Languages split the How and the What from the Intent.&lt;br /&gt;&lt;br /&gt;9:06 - Oren wrote a book with this same name&lt;br /&gt;&lt;br /&gt;DSL Types -&lt;br /&gt;Graphical DSL&lt;br /&gt;External DSL&lt;br /&gt;Internal /Imbedded DSL (a DSL written in the language you are writing with ie: C#)&lt;br /&gt;Fluent Interface (Oren does not really like Fluent interfaces as he feels they are overused and not necessarily understandable).&lt;br /&gt;&lt;br /&gt;9:11 - We need to decide whether or not it is valuable to use a DSL, because they can become complex in complex cases (ie: complex SQL)&lt;br /&gt;&lt;br /&gt;9:16 - Internal DSL&lt;br /&gt;Based on existing (dynamic) language&lt;br /&gt;Uses language ambiguities&lt;br /&gt;Allows us to leverage the existing language strengths.&lt;br /&gt;Common Languages&lt;br /&gt;-&gt; Boo&lt;br /&gt;-&gt; Ruby&lt;br /&gt;-&gt; Python&lt;br /&gt;-&gt; Lisp&lt;br /&gt;-&gt; Etc.&lt;br /&gt;&lt;br /&gt;9:18 - Boo&lt;br /&gt;Python derivative&lt;br /&gt;Statically Typed&lt;br /&gt;Runs on the CLR&lt;br /&gt;Open Compiler architecture&lt;br /&gt;Extremely malleable&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;9:20 - Boo Code Sample&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using session = sessionFactory.OpenSession():&lt;br /&gt;  people = sess.Find("from Person")&lt;br /&gt;  for p as Person in people:&lt;br /&gt;    print (p.Name)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;9:25 - Sample DSL&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;OnCreate Account: Entity.AccountNumber = date.now.Ticks&lt;br /&gt;OnCreate Order:&lt;br /&gt;  if Entity.Total &gt; Entity.Account.MaxOrderTotal:&lt;br /&gt;    BeginManualApprovalFor Entity&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Account and Order are already part of my domain model&lt;br /&gt;&lt;br /&gt;Boo vs C#&lt;br /&gt;&lt;br /&gt;Boo&lt;br /&gt;OnCreate Account: Entity.AccountNumber=date.Now.Ticks&lt;br /&gt;&lt;br /&gt;C#&lt;br /&gt;OnCreate(typeof(Account), delegate{Entity.AccountNumber=DateTime.Now.Ticks});&lt;br /&gt;&lt;br /&gt;9:26&lt;br /&gt;Implementation - Use a base class DslBase.  Time for a code demo!&lt;br /&gt;&lt;br /&gt;9:28&lt;br /&gt;So your boo code is run through the CRL and you get all the power you have with the .NET framework.  So you can walk both through your DSL language and see what's actually going on in your C# code.&lt;br /&gt;&lt;br /&gt;9:39&lt;br /&gt;When you are writing a DSL you are not trying to write in English.  English is too ambiguous.  You have to write in a dialect that is clear to a machine.&lt;br /&gt;&lt;br /&gt;ie: &lt;br /&gt;if Entity.Total &gt; Entity.MaxTotal&lt;br /&gt;vs &lt;br /&gt;Entity's Total bigger than Entity's Max Total&lt;br /&gt;&lt;br /&gt;We are not trying to make the DSL writeable for the business.  Just readable.&lt;br /&gt;&lt;br /&gt;9:50&lt;br /&gt;So there is a bunch of C# code that needs to be implemented in order to allow for the DSL.  It seems somewhat complex, however, would only need to be written once in order to allow for use with all DSLs created within a system.  Again as Oren said, we need to be aware that there is a cost to creating a DSL.  If the cost of the DSL outweighs the benefit then you should look at alternatives. &lt;br /&gt;&lt;br /&gt;10:03&lt;br /&gt;The demo has been going on for a while.  It has been interesting, but I will need to look deeper into the topic.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-2333279414949690500?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/2333279414949690500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=2333279414949690500' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/2333279414949690500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/2333279414949690500'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-day-3-session-one.html' title='Dev Teach 2009 - Day 3 Session One'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-1584757549689421569</id><published>2009-06-10T16:20:00.000-07:00</published><updated>2009-06-10T17:38:17.407-07:00</updated><title type='text'>Dev Teach 2009 - Day 2 Session Six</title><content type='html'>&lt;span class="Speaker"&gt;Erik Renaud - Top Ten Umbrellas&lt;br /&gt;&lt;br /&gt;What is Umbrella&lt;br /&gt;&lt;br /&gt;- This is source code&lt;br /&gt;- on CodePlex&lt;br /&gt;- it is not a Framework&lt;br /&gt;- Complements existing APIs&lt;br /&gt;- .net BCL&lt;br /&gt;&lt;br /&gt;Fixes the issue where the .NET framework is missing things such as the fact that a IList contains .AddRange and a IDictionary does not.&lt;br /&gt;&lt;br /&gt;5:35 - Oooh exciting, appears the WPF composite application block is much easier and better than the WinForms Composite Application Block.&lt;br /&gt;&lt;br /&gt;What is Umbrella con't&lt;br /&gt;&lt;br /&gt;-Extensions to OO principles and patterns&lt;br /&gt;-Design Patterns&lt;br /&gt;-PPP (Patterns, Principles and Practices)&lt;br /&gt;-Configurable&lt;br /&gt;&lt;br /&gt;5:40 - interesting comment (came from a different talk yesterday) Best practices don't exist.  They are generally based on old habits and should be re-evaluated for each system you are writing.&lt;br /&gt;&lt;br /&gt;6:00 - Just spent a while looking at extension methods. hmmm.&lt;br /&gt;&lt;br /&gt;6:01 - The Umbrellas have a bunch of extensions methods extending the .NET BCL.  I think this is the #10 Umbrella.&lt;br /&gt;&lt;br /&gt;6:10 - There is an Umbrella for INotifyPropertyChanged (required for databinding)&lt;br /&gt;&lt;br /&gt;6:18 - Umbrella contains extension points that allows allow indirection and simplify such as:&lt;br /&gt;&lt;br /&gt;int foo = 5;&lt;br /&gt;foo.conversion().To&lt;string&gt;();&lt;br /&gt;&lt;br /&gt;They also have the extension points for reflection, validation, serialization, etc.&lt;br /&gt;The idea is to simplify the API to just provide the pieces of the API you actually need to access.&lt;br /&gt;&lt;br /&gt;6:20 - .NET 4.0 will have contracts to allow for precondition checks at the beginning of method calls.&lt;br /&gt;&lt;br /&gt;6:33 - So essentially, the Umbrellas provide a whole slew of extension methods.  This could be valuable, however, it is probably more valuable to understand what extension methods are and how to create your own.&lt;br /&gt;&lt;br /&gt;Time for beer.  Cheerio!&lt;br /&gt;&lt;/string&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-1584757549689421569?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/1584757549689421569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=1584757549689421569' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1584757549689421569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1584757549689421569'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-day-2-session-six.html' title='Dev Teach 2009 - Day 2 Session Six'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-6078655547372110928</id><published>2009-06-10T14:52:00.000-07:00</published><updated>2009-06-10T16:20:21.974-07:00</updated><title type='text'>Dev Teach 2009 - Day 2 Session Five</title><content type='html'>Micheal Stiefel - Architecting Software as a Service&lt;br /&gt;&lt;br /&gt;Cloud Computing is yet another technology revolution... therefore Services are important?&lt;br /&gt;&lt;br /&gt;Cloud Computing basically implies that there is an illusion of infinite computer resources.&lt;br /&gt;&lt;br /&gt;Session Focal Points&lt;br /&gt;- Business Model drives Software Architecture&lt;br /&gt;- Currently more relevant to SMB than Enterprise&lt;br /&gt;- Magnifies Classic architectural and design issues&lt;br /&gt;- Move to Windows Azure&lt;br /&gt;&lt;br /&gt;4:05 - This guy has some serious loud voice.  He is moving REALLY fast as well.&lt;br /&gt;&lt;br /&gt;The Business Model Drives Architecture&lt;br /&gt;&lt;br /&gt;Problem - A business problem must be solved&lt;br /&gt;Model - Business model solves a business problem.&lt;br /&gt;Architecture - software architecture is an implementation of the model.&lt;br /&gt;&lt;br /&gt;4:09 - We are looking at a case study on a company that provides driving for the elderly when they can no longer drive safely.&lt;br /&gt;&lt;br /&gt;We are looking at how the Model solves the business problem.  So we are looking at the Ride Request Use Case.&lt;br /&gt;&lt;br /&gt;4:15 - The first solution was a monolithic vb6 system.  It provides the validated business model. (it works)&lt;br /&gt;Problems:&lt;br /&gt;Not scalable.&lt;br /&gt;Can not integrate with third parties&lt;br /&gt;&lt;br /&gt;Application Options:&lt;br /&gt;&lt;br /&gt;Traditional On-Premises Application&lt;br /&gt;-Desktop&lt;br /&gt;-Client/Server&lt;br /&gt;Off Premises Application&lt;br /&gt;-Private Cloud&lt;br /&gt;-Public Cloud&lt;br /&gt;&lt;br /&gt;Service Based Solution (Web Services) gives the most flexibility.  Hosting on the cloud means you only pay for the infrastructure you need.&lt;br /&gt;&lt;br /&gt;The solution they decided was a web based application with a web service backend.&lt;br /&gt;&lt;br /&gt;4:23 - when you are validating your business model you need to know what you are measuring.  Ie measure things in domain concepts rather than database lines, etc.&lt;br /&gt;&lt;br /&gt;4:27 - Services and Cloud programming makes the impossible possible&lt;br /&gt;&lt;br /&gt;Cheaper to deliver solution to customers&lt;br /&gt;Integrate with third parties easily&lt;br /&gt;protect your intellectual property&lt;br /&gt;&lt;br /&gt;4:28 - Familiar Design Principles but...&lt;br /&gt;The Cloud is Different from on-premises application&lt;br /&gt;You do not control the network&lt;br /&gt;- Network latency/network responsiveness&lt;br /&gt;- Connectivity Loss is a Problem (solution -&gt; smart client)&lt;br /&gt;&lt;br /&gt;4:30  - Messages across the Internet&lt;br /&gt;- Distributed objects across the Internet will not scale&lt;br /&gt;- Therefore Messages are a discrete unit of business interaction&lt;br /&gt;Ride Request, Payment, Membership Application&lt;br /&gt;New Membership is Payment + Membership Application.&lt;br /&gt;&lt;br /&gt;4:33 -&lt;br /&gt;Messages go across the internet&lt;br /&gt;The objects live within the Business Services, that's where your domain model lives.&lt;br /&gt;&lt;br /&gt;4:34 -&lt;br /&gt;Services should be stateless, the allow you to scale more effectively and rapidly.  They also allow partial failure.&lt;br /&gt;Domain objects do not last beyond message call (Unit of work Pattern)&lt;br /&gt;ACID transactions within service call, composition across several messages.&lt;br /&gt;&lt;br /&gt;4:38 -&lt;br /&gt;When using WCF services, use the namespaces to do versioning.&lt;br /&gt;Do not show domain objects to the services.  Keep them decoupled.&lt;br /&gt;&lt;br /&gt;4:49 - This is a dizzying talk.  The guy moves constantly!  And talks loudly and quickly.&lt;br /&gt;&lt;br /&gt;4:51 - Federated Security&lt;br /&gt;every requests come with a X509 certificates to validate applications&lt;br /&gt;claims validate users (no idea what claims is) basically a claim is anything you want to assert about a user.  How old are they, how were they identified, etc.  Authetication generates a list of claims, then when you do authorization you do claims against your system.  So it doesn't matter how they actually authenticate as long as they provide the correct claims.  Allows you to allow for a certain amount of trust based on how many claims they provide.&lt;br /&gt;&lt;br /&gt;4:55&lt;br /&gt;Where to authorize&lt;br /&gt;&lt;br /&gt;Security Infrastructure, unless there are specific business rules regarding users and rides.&lt;br /&gt;Geneva Framework is supposed to help with this.  No idea what Geneva Framework is.  Worth looking up.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;4:58  In a cloud, you can't use a debugger.&lt;br /&gt;You have to log, or you will be dead in the water.&lt;br /&gt;Think about logging as a primary architectural construct from the beginning.&lt;br /&gt;Auditing is based on business requirements.&lt;br /&gt;Business Health Monitoring (need to know if your system/model is working properly)&lt;br /&gt;&lt;br /&gt;So the architectural problems that we have are magnified in the cloud&lt;br /&gt;&lt;br /&gt;- Messages are not remote procedure caslls&lt;br /&gt;prepare for the future by using claims&lt;br /&gt;multiple tenants&lt;br /&gt;data customization&lt;br /&gt;keep tiers decoupled&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5:03 - Moving to Windows Azure&lt;br /&gt;&lt;br /&gt;Amazon -&gt; EC2, VM, no failover, recovery&lt;br /&gt;Google App Engine, restricted app, failover, recovery&lt;br /&gt;Azure, cloud platform, metadata, failover, recovery&lt;br /&gt;&lt;br /&gt;Cloud Economics&lt;br /&gt;Economic Calculation&lt;br /&gt;-&gt; Pay as you go&lt;br /&gt;-&gt; avoid need to build to peak capacity&lt;br /&gt;-&gt; data available over a wide geographic area&lt;br /&gt;Risk Sharing&lt;br /&gt;-&gt; Cloud provider must meet peak capacity&lt;br /&gt;-&gt; Cloud provider handles upgrades&lt;br /&gt;Availability &amp;amp; Service Level Agreements are critical&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Moving to Azure&lt;br /&gt;To move to Azure, think about getting off Azure (if you decide you no longer want to be on Azure you want to be able to get off it)&lt;br /&gt;&lt;br /&gt;You need to understand the Windows Azure platform before you can know how to get on/off the platform.&lt;br /&gt;&lt;br /&gt;5:08&lt;br /&gt;We could access a hosted SQL Server on the cloud so as to not have to host SQL Server our selves.  SQL Server in the cloud will use the same protocol as every other SQL Server.  It would be easy to get on and off the cloud.&lt;br /&gt;&lt;br /&gt;5:14&lt;br /&gt;Mapping your app to Azure&lt;br /&gt;Pure .NET applications are easy&lt;br /&gt;If you want to use the Azure stuff like blobs, queues, tables (azure data structures) then you will have to rewrite your data tier.&lt;br /&gt;&lt;br /&gt;5:15&lt;br /&gt;You don't have to be all in the cloud or all off the cloud.  You can move pieces to the cloud as you need.  This is a Long Term Process.&lt;br /&gt;&lt;br /&gt;Regardless the economics are compelling for SMB (small medium business) but so are the architectural challenges.&lt;br /&gt;&lt;br /&gt;Using analogy is to electric power, but data has identity and latency, electrons do not.  I'm confused by this.&lt;br /&gt;&lt;br /&gt;You need to think about what happens if a cloud provider goes under?  Where does your data and application go? Institutional change has come as well&lt;br /&gt;&lt;br /&gt;Conclusions&lt;br /&gt;-Architecture is based on a Business Model.  An architect must be able to be between the developers and the business.&lt;br /&gt;- Business Models will drive cloud adoption&lt;br /&gt;- Architects have to think about business&lt;br /&gt;- design concepts you know apply to the cloud&lt;br /&gt;- It is not an all or nothing opportunity.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5:20 - Holy monkey that was a presentation.  My head hurts.  Oi one more today yee haw.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-6078655547372110928?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/6078655547372110928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=6078655547372110928' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/6078655547372110928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/6078655547372110928'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-day-2-session-five.html' title='Dev Teach 2009 - Day 2 Session Five'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-7651452569297134142</id><published>2009-06-10T13:28:00.000-07:00</published><updated>2009-06-10T14:51:58.247-07:00</updated><title type='text'>Dev Teach 2009 - Day 2 Session Four</title><content type='html'>Dave Larabee - Release by the Feature&lt;br /&gt;&lt;br /&gt;2:30 - Back on the Agile Track, let's see what this Dave dude's got.&lt;br /&gt;&lt;br /&gt;Question 1: Why would we want to release per feature?&lt;br /&gt;&lt;br /&gt;1)ROI the sooner we release a feature, the sooner we start making money on it.&lt;br /&gt;2)The sooner we get out a feature, the quicker we get feedback for each feature.&lt;br /&gt;&lt;br /&gt;This is desirable, but not always achievable.&lt;br /&gt;&lt;br /&gt;2:38&lt;br /&gt;Values -&gt; Practices -&gt; Tools&lt;br /&gt;&lt;br /&gt;Team values are the fundamental&lt;br /&gt;-&gt; example -Fun, Integrity, Quality, Cleverness&lt;br /&gt;To drive out your team values have everybody yell out their values, then vote on the top 5 most important for everybody.  This will give you a good idea about what everybody on the team values.&lt;br /&gt;&lt;br /&gt;The values drive out the practices which then are used to choose tools.&lt;br /&gt;&lt;br /&gt;The culture will determine the productivity and eventually the success of your development team.&lt;br /&gt;&lt;br /&gt;2:42 - Why Lean?&lt;br /&gt;There are always plateaus in productivity gains -&gt; ie you will find that after learning TDD, you will hit a plateau, so it's important to keep looking for ways to "trim fat"&lt;br /&gt;&lt;br /&gt;Start Ferreting Out Waste&lt;br /&gt;Iterations (Sprints etc) are quite useful, however, they do add time waste.  In agile, we shouldn't be dumping the software on the support team, but rather should be focused on making small adjustments and changes as we go.&lt;br /&gt;&lt;br /&gt;2:45 -JIT (Just In Time)&lt;br /&gt;&lt;br /&gt;You can JIT with this,&lt;br /&gt;You can JIT with that,&lt;br /&gt;or you JIT with this,&lt;br /&gt;because JIT is where it's at.&lt;br /&gt;&lt;br /&gt;Rather than getting everybody in all the time, you get them there when they are needed.  Eliminates waste.&lt;br /&gt;&lt;br /&gt;Retrospectives&lt;br /&gt;Problems -&lt;br /&gt;1) Participation&lt;br /&gt;2) Follow up&lt;br /&gt;&lt;br /&gt;Tying a retrospective to the iteration is not the most effective.  We should be dealing with the issues as they come up, rather than waiting till the end of the iteration.&lt;br /&gt;&lt;br /&gt;2:51 - Lean means focus on not having too much work in progress.  If you have 80 items in your backlog and you have spent 1 hour on each item, but turns out that it's go time without them, then you have wasted 80 hours.  Humans are not very good at multitasking.  Minimize your work in progress so we don't do context switching.&lt;br /&gt;&lt;br /&gt;2:53 - This talk is a little disjointed.  It's sorta tough for me to write notes, but I'm working on it!&lt;br /&gt;&lt;br /&gt;Recommends David Anderson Agile Management (something or other)&lt;br /&gt;&lt;br /&gt;2:55 - Value stream map.  Interesting little flow diagram, detailing touch time (active work) and wait time (down time)  Drawing out this out allows you to see where things in your flow are slow and how you can trim the time where you have overly long touch time or more importantly wait time.  Wait time is waste time.&lt;br /&gt;&lt;br /&gt;2:57 - Coaching Philosophy - People support a world they help create - Collaborative Process Design.&lt;br /&gt;&lt;br /&gt;As a team -&gt; draw out your value stream map.  How do you work, not how you want to work, just how you work.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3:00 - Put a feature in the value stream map, (que card).  The queue card should have a name "Alert to New Document" Date started, date ended and effort (1 - 3)  The cards are pulled by the next step in the value stream (ie - QA pulls the step).   If any queue fills up (more than 5 in QA for example) a developer goes to help the QA.  The idea is that the team is only as fast as the slowest piece of the chain.  No point haveing developers complete 1000 things if the qa can't actually handle the work required.&lt;br /&gt;&lt;br /&gt;3:05 - RESTful -&gt; The Board is a Representation.  It really represents the way that we do work.&lt;br /&gt;&lt;br /&gt;3:10 - &lt;a href="http://www.google.ca/search?q=rolling+wave+planning&amp;amp;ie=utf-8&amp;amp;oe=utf-8&amp;amp;aq=t&amp;amp;rls=org.mozilla:en-US:official&amp;amp;client=firefox-a"&gt;Rolling Wave Planning &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;3:15 - Techniques&lt;br /&gt;Deal with your technical debt.  It costs you more than you would expect.  Your Kanban (value stream map) should help you see the technical debt.&lt;br /&gt;&lt;br /&gt;3:19 -&lt;br /&gt;Most teams will become much better just by adopting XP practices.&lt;br /&gt;User stories are essentially their features.&lt;br /&gt;&lt;br /&gt;3:20 - The team at home is struggling getting into QA, so I'm working on that, but I can't connect to the database over VPN.&lt;br /&gt;&lt;br /&gt;3:28 -&lt;br /&gt;Fix all bugs as soon as they come up.&lt;br /&gt;Independence set-based concurrent engineering - Identify the problem, split two groups off, then converge to compare notes.&lt;br /&gt;&lt;br /&gt;3:33 -&lt;br /&gt;How do you release per feature?&lt;br /&gt;1) Use Branches to Isolate features&lt;br /&gt;Branching breaks CI&lt;br /&gt;So create a fishbone branch, the developer commits to their feature branch, but the CI mirrors that feature to fishbone (simulator branch).  This branch is there to tell us ASAP that there is a merge conflict.  Feature branching is hard regardless.  I'm not a big fan and neither is David Larabee.&lt;br /&gt;&lt;br /&gt;GIT makes this much easier and beyond compare is by far the best comparison/merge tool.&lt;br /&gt;&lt;br /&gt;2) Make features isolated via architecture&lt;br /&gt;- plugin based architectures&lt;br /&gt;- Composite Applications&lt;br /&gt;&lt;br /&gt;3:45 - Database refactoring&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.liquibase.org/"&gt;Liquibase&lt;/a&gt;, database refactoring tool (xml)&lt;br /&gt;Migrations (ruby based)&lt;br /&gt;&lt;br /&gt;3:50 - Changing UX experience&lt;br /&gt;Make changes slowly.&lt;br /&gt;ebay changed their colour from yellow to white very slowly over time.&lt;br /&gt;&lt;br /&gt;3:50 - Talks over.  Interesting talk.  Some good stuff there, I need to look more at lean.  I think that it might fit well into my current organization.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-7651452569297134142?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/7651452569297134142/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=7651452569297134142' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7651452569297134142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7651452569297134142'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-day-2-session-four.html' title='Dev Teach 2009 - Day 2 Session Four'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-4198649537773298012</id><published>2009-06-10T10:54:00.000-07:00</published><updated>2009-06-10T12:08:15.178-07:00</updated><title type='text'>Dev Teach 2009 - Day 2 Session Three</title><content type='html'>Amanda Laucher - DSLs and LOP&lt;br /&gt;&lt;br /&gt;12:00 - She called me a liar for saying that I don't use a DSL - I guess that SQL and build scripts can be considered a DSL.&lt;br /&gt;&lt;br /&gt;What is a DSL?&lt;br /&gt;&lt;br /&gt;A Domain Specific Language - A programming language that allows us to communicate more effectively with the business, the owners of the domain.&lt;br /&gt;&lt;br /&gt;12:03 - Interesting statement -&gt; If you decide that you don't want to write code anymore, it means that you aren't actually any good at writing code.&lt;br /&gt;&lt;br /&gt;12:07 - The goal of DSLs is to allow the Business Analysts to look at the code and understand it.&lt;br /&gt;&lt;br /&gt;Ubiquitous Language - Everybody should use the same language so that when somebody says some thing everybody understands what they are saying.&lt;br /&gt;&lt;br /&gt;DSLs Enhance&lt;br /&gt;- Productivity - learn the domain and learn the code&lt;br /&gt;- Reliability - everybody can read the code and understand what's going on&lt;br /&gt;- Reusability&lt;br /&gt;- Signal to noise&lt;br /&gt;&lt;br /&gt;12:11&lt;br /&gt;&lt;br /&gt;Domain user types:&lt;br /&gt;Add User Gill Anderson to database&lt;br /&gt;With information blah&lt;br /&gt;&lt;br /&gt;We Type&lt;br /&gt;UserRepository.Add("Gill Anderson", "555-555-5555");&lt;br /&gt;&lt;br /&gt;DSL vs GPL (general purpose language)&lt;br /&gt;- limited expressiveness (if you don't want your users to do something stupid, make it really hard for them to do it)&lt;br /&gt;- Not turing complete (means you can't build your language with your language)&lt;br /&gt;- No ability to build abstractions (if you can build abstractions you've probably gone to far)&lt;br /&gt;- Limited power&lt;br /&gt;- Focused on a specific domain and makes us more productive within that domain.&lt;br /&gt;&lt;br /&gt;Textual DSLs&lt;br /&gt;-SQL&lt;br /&gt;-JavaScript&lt;br /&gt;-XML&lt;br /&gt;-Build Script Languages&lt;br /&gt;-Unix Shell Scripts&lt;br /&gt;-LINQ&lt;br /&gt;&lt;br /&gt;Visual DSLs&lt;br /&gt;- Sheet Music&lt;br /&gt;&lt;br /&gt;12:19&lt;br /&gt;Testability&lt;br /&gt;- Validation occurs at the domain level&lt;br /&gt;- Things written in the dsl are not tested, they are validated by the user and assumed to be correct&lt;br /&gt;- DSLs for testing&lt;br /&gt;- Writing a DSL around and API to make it easier to test - When_... Should_&lt;br /&gt;&lt;br /&gt;12:23&lt;br /&gt;A fluent interface gets us closer to the DSL as they are easier to understand.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Use your languages features!&lt;br /&gt;Reflection&lt;br /&gt;Open Classes/Extension Methods&lt;br /&gt;Dynamic Typing&lt;br /&gt;Type Inference/Duck Typing&lt;br /&gt;Pattern Matching/Active Patterns&lt;br /&gt;HOF/Partial Application&lt;br /&gt;Discriminated Unions&lt;br /&gt;Quotations&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;12:26 - let's look at some F#&lt;br /&gt;&lt;br /&gt;let FruitMuffins fruit =&lt;br /&gt;let container = "muffinPan"&lt;br /&gt;let dryIngredients = sift (2.5&lt;cups&gt;, "flour") |&gt; mix (1.5&lt;cups&gt;,"sugar")&lt;br /&gt;let moistIngredients = mix (250&lt;ml&gt;,"milk") (1.3&lt;cups&gt;,"oil")(2, "eggs") \&gt; mix (1.25&lt;cups&gt;, fruit)&lt;br /&gt;mixture = combine dryIngredients moistIngredients |&gt; fillContainer&lt;br /&gt;bake mixture 15&lt;min&gt; |&gt; cool 10&lt;min&gt;&lt;br /&gt;&lt;br /&gt;This requires some helper methods, but these are not required by the business to understand the code.&lt;br /&gt;&lt;br /&gt;12:31  DSLs have a special layer called the magic carpet layer, the helper methods that allow the users to write their DSL without having to understand the plumbing.&lt;br /&gt;&lt;br /&gt;12:34 Amanda just showed us that F# is much more concise than C#.  I need to learn another language this year, I wonder if F# is perhaps the language to learn.&lt;br /&gt;&lt;br /&gt;12:37 Oslo - Allows us to define a DSL in an external DSL workbench.&lt;br /&gt;&lt;br /&gt;12:39 - Issues with the projector... ... ...&lt;br /&gt;&lt;br /&gt;12:40 - Fixed!&lt;br /&gt;&lt;br /&gt;12:41 - So it appears that OSLO allows us to create a language that can parse a DSL.  Basically what happens is you write the DSL, then it creates a tree structure that you can then use within another programming language (such as C#).  OSLO is essentially a DSL to create a DSL.  Kinda cool.  We could probably consider using something like this for routing.&lt;br /&gt;&lt;br /&gt;12:45 - OSLO provides syntax and error checking on both the DSL, and the magic carpet layer.&lt;br /&gt;&lt;br /&gt;12:53 - Turns out that OSLO is still in development and therefore in flux.   Should get better with the next release, but also going to change.  I guess JetBrains has a tool that could be used for the same idea. Intentional Software also does one.&lt;br /&gt;&lt;br /&gt;12:58 - Things to consider with the DSLs&lt;br /&gt; Involve Domain Experts in development&lt;br /&gt; DSLs have to be able to change&lt;br /&gt; DSLs evolve independently of other code and of each other&lt;br /&gt; DSLs are used in combination with other DSLs&lt;br /&gt;&lt;br /&gt;13:01 - The cost of DSLs&lt;br /&gt;Learning new languages takes time&lt;br /&gt;Writing and maintaining DSLs is hard.  That's why they need to be very restrictive.&lt;br /&gt;Not to be used everywhere. - Not every problem needs a DSL.  We need to avoid the same problem that we have now with XML.&lt;br /&gt;&lt;br /&gt;1:07 - Talk is complete.  Interesting talk.  Definitely worth thinking about some of the concepts behind DSLs.  They would certainly help solve a few of the problems that we have right now.&lt;br /&gt;&lt;br /&gt;&lt;/min&gt;&lt;/min&gt;&lt;/cups&gt;&lt;/cups&gt;&lt;/ml&gt;&lt;/cups&gt;&lt;/cups&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-4198649537773298012?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/4198649537773298012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=4198649537773298012' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/4198649537773298012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/4198649537773298012'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-day-2-session-three.html' title='Dev Teach 2009 - Day 2 Session Three'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-1427070196022647269</id><published>2009-06-10T09:26:00.000-07:00</published><updated>2009-06-10T10:51:59.678-07:00</updated><title type='text'>Dev Teach 2009 - Day 2 Session Two</title><content type='html'>James Kovacs - Light Up Your Apps with IoC Conventions&lt;br /&gt;&lt;br /&gt;What is dependency injection:&lt;br /&gt;&lt;br /&gt;Dependencies are provided to objects via constructor or properties&lt;br /&gt;- Setter vs Constructor&lt;br /&gt;&lt;br /&gt;Inversion of Control Containers&lt;br /&gt;Hashtable of interface vs implementing type&lt;br /&gt;- As we do: Dictionary&lt;type, object=""&gt;&lt;br /&gt;Full fledged containers offer a lot more...&lt;br /&gt;&lt;br /&gt;10:38 - James is actually a pretty good speaker.  I've never seen him talk before.&lt;br /&gt;&lt;br /&gt;James recommends Castle Windsor - Says that Oren just released v2.0.&lt;br /&gt;&lt;br /&gt;10:40 - Interesting humour.  I guess he is friends with most of the dudes who wrote/maintain the major IOC containers.  Ha... Ha...&lt;br /&gt;&lt;br /&gt;Why should we use a Popular Container?&lt;br /&gt;&lt;br /&gt;- Wider configuration options&lt;br /&gt;XML, code, script&lt;br /&gt;&lt;br /&gt;Don't use XML, the configuration for Generics is just ugly.  Most containers provide other ways using code and scripts.  The best way to configure it is in Code.  Deployment is not the time to be swapping out dependencies.  It's a development decision.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- Lifetime management&lt;br /&gt;Singleton(Default), transient, per-thread, or pooled&lt;br /&gt;&lt;br /&gt;Typically we will use this for the infrastructure, not the domain model.  These should be fine as Singletons as they &lt;span style="font-weight: bold;"&gt;SHOULD &lt;/span&gt;be thread safe.  All containers use singletons as their default. Unity is not, uses transient instead.&lt;br /&gt;&lt;br /&gt;- auto-wiring dependencies&lt;br /&gt;- run-time configurability&lt;br /&gt;- plugins&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One Assembly to Rule Them All&lt;br /&gt;&lt;br /&gt;Common Service Locator&lt;br /&gt;- http://www.codeplex.com/CommonServiceLocator&lt;br /&gt;&lt;br /&gt;All the popular containers have adapters so you don't need to create manual adapters if you need to swap out frameworks if you need to.  This is unlikely for us, but still a nifty little concept.&lt;br /&gt;&lt;br /&gt;10:53 - In order to ensure that all dependencies are being written.  There are things that we can use, structuremap actually has a very elegant solution.  It allows environmental dependency checks.  Integration tests are perhaps the best way to solve this issue.&lt;br /&gt;&lt;br /&gt;10:58 - Now we are diving into some tests that he wrote to test his containers.&lt;br /&gt;&lt;br /&gt;Basically the test is to ensure that all components within his container can be initialized.  This would help to ensure that all nested dependencies are also registered within the container.&lt;br /&gt;&lt;br /&gt;Another argument to using a real IOC as opposed to a hand rolled is that they handle order of dependencies so you don't have to worry about order.&lt;br /&gt;&lt;br /&gt;11:06 - We need to start doing integration tests.&lt;br /&gt;&lt;br /&gt;11:09 - A big anti-pattern -&gt; do not use your IoC container as a service locator.  (heh.. heh... oups) You should isolate your IoC container behind factories so that there are only a handful of locations that actually are dependent on your IoC.  We need to spend some time revisiting our dependency resolver work.&lt;br /&gt;&lt;br /&gt;11:13 - XML configuration is very verbose.  I think we knew this already.  Looks yucky. Yucky Yucky.  Very very yucky.  No compile time checks.  Definitely don't want to do this.  Very painful.  Alright, let's talk about conventions!&lt;br /&gt;&lt;br /&gt;11:14 - Windors FluentAPI looks like:&lt;br /&gt;&lt;br /&gt;Component.For&lt;ismtpserver&gt;().ImplementedBy&lt;smtpserver&gt;().DependsOn(new { host = "localhost", port=25});&lt;br /&gt;&lt;br /&gt;The DependsOn passes things into the constructor of the object you are constructing.  This is a pretty cool API.  Definitely think we need to spend some time looking into a real container.&lt;br /&gt;&lt;br /&gt;11:21 - Fluent Configuration is not discoverable.  You need to know the starting point or have good documentation.&lt;br /&gt;&lt;br /&gt;11:25 - Component.For(typeof(IRepostitory&lt;&gt;)).ImplementedBy(typeof(Repostitory&lt;&gt;));&lt;br /&gt;This will dynamically fill in the type, so if we need a IRepository&lt;foo&gt; we don't need to explicitly define it.  This could be extremely powerful.&lt;br /&gt;&lt;br /&gt;11:27 - Component.For&lt;idbgateway&gt;().ImplementedBy&lt;dbgateway&gt;().Named(DatabaseKey.Corporate).DependsOn(new { connectionString = ConnectionString.Corporate})&lt;br /&gt;Allows you to actually decide which implementation you want to get out depending on the key.  Could be powerful for when you are using multiple databases.&lt;br /&gt;&lt;br /&gt;11:29 - Convention Based Configuration&lt;br /&gt;&lt;br /&gt;AllTypes.FromAssembly(Assembly.GetExecutingAssembly())&lt;br /&gt;.Where(type=&gt;type.Namespace.StartsWith("Project.Foo.UI.View")&lt;br /&gt;.WithService.FirstInterface();&lt;br /&gt;&lt;br /&gt;This will register all the views in the namespace.  This actually forces you to be consistent with you class locations.  Because if you place things in the right places then everything will work properly for you.  This allows you to "Fall into the pit of success" make the easy thing to do, the right thing.&lt;br /&gt;&lt;br /&gt;As this is a LINQ expression, you can pretty much define your conventions as you feel fit.  This actually seems extremely powerful and will effectively eliminate the issue that we have were we forget to add a particular dependency to the container.&lt;br /&gt;&lt;br /&gt;You can mix and match this with your Component Fluent configuration from above.  This actually is pretty slick.&lt;br /&gt;&lt;br /&gt;11:36 - Structure Map has some slick ways to read from configuration while Windsor requires you to use the .NET configuration reader.&lt;br /&gt;&lt;br /&gt;11:38 - We are now going to talk about some advanced usages of IoC containers including interceptors.&lt;br /&gt;&lt;br /&gt;This is pretty slick, can't type it all out, so hopefully he'll have to source code up somewhere.  Basically, what happens is that using conventions, you can define what types of classes you will add the interceptors to.  This gives you full control including adding transactions, logging, and error handling.&lt;br /&gt;&lt;br /&gt;The fact that IoC containers have support for this already is another very good argument against rolling your own.&lt;br /&gt;&lt;br /&gt;11:40 - Conclusion - Use IoC.  It helps decouple your business logic from your infrastructure.&lt;br /&gt;&lt;br /&gt;11:45 - Talk is over.  Really good talk, learned some valuable stuff here.  Not sure what's next.  Another talk by Oren Eini or one by Amanda Launcher.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/dbgateway&gt;&lt;/idbgateway&gt;&lt;/foo&gt;&lt;/smtpserver&gt;&lt;/ismtpserver&gt;&lt;/type,&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-1427070196022647269?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/1427070196022647269/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=1427070196022647269' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1427070196022647269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1427070196022647269'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-day-2-session-two.html' title='Dev Teach 2009 - Day 2 Session Two'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-1938154352583001311</id><published>2009-06-10T08:07:00.000-07:00</published><updated>2009-06-10T09:26:48.608-07:00</updated><title type='text'>Dev Teach 2009 - Day 2 Session One</title><content type='html'>So I was going to go to a talk on Automated UI Testing using Prism.  Turned out the talk was something else about VSTS.  I opted out.  So here I am listening to how to isolate my dependencies using Mocks.  I'm not really expecting to learn much here, but you never know what little tidbits on knowledge I can glean.&lt;br /&gt;&lt;br /&gt;9:09 - We are using MVVM which is the dominating pattern for WPF and Silverlight.  It replaces MVC and MVP.  Pretty much the same concept but slightly different.  I believe that the main difference is that the "presenter" is actually a state container to which we can bind the view.  Worth looking into I think.&lt;br /&gt;&lt;br /&gt;9:15 - Isolate your dependencies because otherwise there are too many things that can fail.&lt;br /&gt;&lt;br /&gt;9:17 - Dude uses MSTEST and context based specifications.  With underscores! Hooray for readability!&lt;br /&gt;&lt;br /&gt;9:26 - Learning about manual mocking right now... this is really starting from the basics of mocking.  I kinda expected that though.&lt;br /&gt;&lt;br /&gt;9:35 - Manual mocking is extremely painful.  I'm actually surprised that he is even showing it.  I hope that this will move into a mocking framework soonish...&lt;br /&gt;&lt;br /&gt;9:40 - Battery is about to die... I'm too far from a plugin.  Guess I'll post any further thoughts later.&lt;br /&gt;&lt;br /&gt;10:23 - My final thoughts are - far too basic.  I'm unsure why he even bothered with manual mocks.  He could easily have spent the time talking about his framework of choice and still demonstrated the differences between State Based and Behavior Based Testing.&lt;br /&gt;&lt;br /&gt;Next Up : Local Legend James Kovac lighten up your app with IOC conventions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-1938154352583001311?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/1938154352583001311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=1938154352583001311' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1938154352583001311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1938154352583001311'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-day-2-session-one.html' title='Dev Teach 2009 - Day 2 Session One'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-5156118750200337682</id><published>2009-06-09T14:52:00.001-07:00</published><updated>2009-06-09T16:20:42.284-07:00</updated><title type='text'>Dev Teach 2009 - Session Five</title><content type='html'>Done Done - Erik Renaud&lt;br /&gt;&lt;br /&gt;What is Done Done?&lt;br /&gt;&lt;br /&gt;- Best comparison is a checklist&lt;br /&gt;- Best tool is a checklist&lt;br /&gt;- it's format it's auditable, it's accepted&lt;br /&gt;- it's a tax but it allows to predict velocity&lt;br /&gt;&lt;br /&gt;Why do we want to be done done?&lt;br /&gt;&lt;br /&gt;- Manages expectations&lt;br /&gt;- Success is clearly defined&lt;br /&gt;- Sense of accomplishment and recognition promotes responsibility&lt;br /&gt;- Moral contract for team members&lt;br /&gt;&lt;br /&gt;4:37 - argument over whether we should automate everything or not has peaked my interest again.&lt;br /&gt;&lt;br /&gt;When do we define Done Done?&lt;br /&gt;- Sprint 0&lt;br /&gt;- Non-static, continuously revisited and updated&lt;br /&gt;&lt;br /&gt;If you do not complete the done done list, then you don't get the story points.&lt;br /&gt;&lt;br /&gt;Agile Planning&lt;br /&gt;Based on Scrum&lt;br /&gt;- Product Owner&lt;br /&gt;- Development team, sprints and sprint backlogs&lt;br /&gt;- Ceremonies&lt;br /&gt; - Sprint plannings and demos&lt;br /&gt; - Stand-up meetings&lt;br /&gt; - Retrospectives&lt;br /&gt;-Potentially shippable software&lt;br /&gt;&lt;br /&gt;Agile Modeling&lt;br /&gt;- Documentation is focused more on creating artifacts rather than word documents.&lt;br /&gt;- He recommends entity diagrams and business flow charts.&lt;br /&gt;&lt;br /&gt;These are abstracts that provide a basis for communication between the team members.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I feel like I could be giving this talk...&lt;br /&gt;&lt;br /&gt;4:22 - Done Done Levels&lt;br /&gt;&lt;br /&gt;Release: Applying additional effort within a sprint to release a version outside of the development environment&lt;br /&gt;&lt;br /&gt;Sprint: Effort which is time boxed where selected business value is developed and incrementally added to software.&lt;br /&gt;&lt;br /&gt;User story: We don't necessarily need to ensure that regression testing is done on the user story level, but rather at the sprint or release level.&lt;br /&gt;&lt;br /&gt;4:37 - Argument over whether we can automate everything has peeked my interest again.&lt;br /&gt;&lt;br /&gt;4:47 - One thing that he's talking about that really makes sense is to ensure that you have a list of things that you always have to have completed every time that you complete a user story.&lt;br /&gt;&lt;br /&gt;5:00 - He recommends reading Agile Software Development, Principles, Patterns, and Practices.&lt;br /&gt;&lt;br /&gt;5:10 - In a done done scenario we should have a list of all done done steps required for every story.  The list should be agreed to by the team.&lt;br /&gt;&lt;br /&gt;Example for a sprint:&lt;br /&gt;&lt;br /&gt;tracking tools updated&lt;br /&gt;coded reviewed (or paired)&lt;br /&gt;models up to date&lt;br /&gt;documentation user, system&lt;br /&gt;deployment packages&lt;br /&gt;graphics designed&lt;br /&gt;deployed to dev server&lt;br /&gt;demo ready&lt;br /&gt;tests passes&lt;br /&gt;coded&lt;br /&gt;&lt;br /&gt;This will be a reminder for us to do all the things we are supposed to do.&lt;br /&gt;&lt;br /&gt;Tips &amp; Tricks:&lt;br /&gt;Make the time during your sprint 0 at the beginning of a project to define what it will mean for you to be Done Done.  Involve everybody (infrastructure, prod ops, etc)&lt;br /&gt;&lt;br /&gt;For user stories (sprints &amp; releases) assign items to someone in particular. Group ownership makes sense but somebody has to be responsible for Done Done (be the done done guardian)&lt;br /&gt;&lt;br /&gt;Transform your done done list so that it becomes the moral contract that defines Success.&lt;br /&gt;&lt;br /&gt;If done done is not completed, then the product can not be demoed to the product owner.&lt;br /&gt;&lt;br /&gt;We finished with this one: &lt;a href="www.youtube.com/watch?v=l1wKO3rID9g"&gt;Agile Hitler&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-5156118750200337682?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/5156118750200337682/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=5156118750200337682' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5156118750200337682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5156118750200337682'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-session-five.html' title='Dev Teach 2009 - Session Five'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-3912724485788899903</id><published>2009-06-09T13:30:00.000-07:00</published><updated>2009-06-09T14:50:33.245-07:00</updated><title type='text'>Dev Teach 2009 - Session Four</title><content type='html'>Lunch was actually decent.  Pretty standard conference fair.&lt;br /&gt;&lt;br /&gt;Here is the next talk!&lt;br /&gt;&lt;br /&gt;Oren Eini - Producing Production Quality Software&lt;br /&gt;&lt;br /&gt;What is production quality?&lt;br /&gt;- High Availability&lt;br /&gt;- High Performance&lt;br /&gt;- High Maintainability&lt;br /&gt;- Scalability&lt;br /&gt;(The ities again)&lt;br /&gt;But more than that it needs to work in production&lt;br /&gt;&lt;br /&gt;The problem is that all software fails! (example the Mars Rover)&lt;br /&gt;&lt;br /&gt;Murphy's law exist - &lt;br /&gt;The prayers that bring him are: &lt;br /&gt;"What's the worst that can happen?"  &lt;br /&gt;"It will never happen"&lt;br /&gt;&lt;br /&gt;Production Failures:&lt;br /&gt;&lt;br /&gt;System goes down - easiest to fix, we have logging or a stack trace.  We need to make sure that the system can restart properly.&lt;br /&gt;System runs too slow - slow systems have a large effect on the bottom line!&lt;br /&gt;System does something it's not supposed to do &lt;br /&gt;System not responding - System takes a request and doesn't come back&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Everybody should read "Release It"  Michael T. Nygard&lt;br /&gt;&lt;br /&gt;Destabilizers&lt;br /&gt;- Slow network&lt;br /&gt;- other processes&lt;br /&gt;- configuration changes&lt;br /&gt;- permissions changed on a shared directory&lt;br /&gt;- Memory Leaks&lt;br /&gt;- Poor exception handling&lt;br /&gt;- bad release processes (forgot to run a script)&lt;br /&gt;- select id, subject, content from documents (uncontrolled result set can take down your systems)&lt;br /&gt;&lt;br /&gt;Integration Points&lt;br /&gt;- unstable third party hosted apps&lt;br /&gt;- integration point is down&lt;br /&gt;- database goes down&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This talk is pretty highlevel.  So far all we've done is visit why some software craps out.  I'm hoping that we will dig into more some details on how to actually get around this issues.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3:11 - Third parties are bad.  They are often stupid.  We give them threads and this might not be a good idea.  Especially if the third party doesn't come back.  When communicating outside the trust boundary we should be using async operations.&lt;br /&gt;&lt;br /&gt;Systems that are running jobs on a schedule should have some way to inform if the job doesn't run.&lt;br /&gt;&lt;br /&gt;3:20 - It's 3:20, do you know what your software is doing?&lt;br /&gt;Building visibility into your system is a very important thing!&lt;br /&gt;Logging is not effective, too much data created.&lt;br /&gt;&lt;br /&gt;Built in system information. aka -Operation Database&lt;br /&gt;The operation database is a place where the operation people can take a look at what the system is doing. We might be able to get away with just saying what the actual state of the system is at the current time.  This can give you some insight into what's actually going on.&lt;br /&gt;&lt;br /&gt;Oren recommends that our software writes a blog.&lt;br /&gt;&lt;br /&gt;- We have a problem with connectiveity to Visa&lt;br /&gt;My last 10 attempts to validate a credit card with Visa has failed, and I am not sure what is going on.  I an getting SocketException.  The remote machine actively refused the connection.  For now I am accepting orders on a tentitive basis.&lt;br /&gt;&lt;br /&gt;Someone please help me.&lt;br /&gt;&lt;br /&gt;3:30 - Automated system audits (similar concept to the Ping that we implemented in Core)  Ensure that everything required is up and working.  Report on it and ensure that you throttle the reports.&lt;br /&gt;&lt;br /&gt;3:35 - Service Level Agreements - How stable does the application have to be? There are often penalties and fines associated.&lt;br /&gt;&lt;br /&gt;3:40 - SLA's should be enforced!  (on any third party services)&lt;br /&gt;&lt;br /&gt;3:40 - Separation of Concerns: Every component should be responsible for itself, every component should have a status reporting and a SLA.&lt;br /&gt;&lt;br /&gt;3:45 - Separate administration and production.  This prevents the sys admins not being able to fix the issues because the service is pinging the server.&lt;br /&gt;&lt;br /&gt;3:45 - Validate your environment on a continuous basis.  This means that as soon as there is an issue you will know.&lt;br /&gt;&lt;br /&gt;3:50 - Design the software for you Ops team.  They are the ones who know how they need to support the software.  You should separate your developer config from your ops config.&lt;br /&gt;&lt;br /&gt;Next up... Done Done!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-3912724485788899903?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/3912724485788899903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=3912724485788899903' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/3912724485788899903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/3912724485788899903'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-session-four.html' title='Dev Teach 2009 - Session Four'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-1098879951787718388</id><published>2009-06-09T11:02:00.000-07:00</published><updated>2009-06-09T12:29:46.488-07:00</updated><title type='text'>Dev Teach 2009 - Session Three</title><content type='html'>Pragmatic Architecture&lt;br /&gt;&lt;br /&gt;I decided to skip out the next Silverlight talk given how I wasn't terribly impressed with the last talk about Silverlight.&lt;br /&gt;&lt;br /&gt;So here we are learning about Terry's job.&lt;br /&gt;&lt;br /&gt;What is a software architect?&lt;br /&gt;&lt;br /&gt;Interesting term: &lt;a href="http://en.wikipedia.org/wiki/Cargo_cult"&gt;Cargo Culting&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Interesting articles on the darkside of architecture:&lt;br /&gt;&lt;a href="http://discuss.joelonsoftware.com/default.asp?joel.3.219431.12"&gt;Why I Hate Frameworks&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.joelonsoftware.com/articles/fog0000000018.html"&gt;Archictecture Astronauts&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;What do we expect of a good architecture:&lt;br /&gt;&lt;br /&gt;The ities: Integrity, Simplicity, Reliability, Extensibility, Maintainability, Modularity, Recoverability, Composability, Parsimony, Scalability, Security, Performability, Logevity&lt;br /&gt;--&gt; We never describe our architecture based on this.  We need to consider using these to describe our architectures.&lt;br /&gt;&lt;br /&gt;make it easy for developers to make "right" decisions. (where "right" =&gt; "right for this project or system")&lt;br /&gt;&lt;br /&gt;in other words, enable "correctness by default"&lt;br /&gt;or rather have developers using our architecture "fall naturally into the pit of success"&lt;br /&gt;&lt;br /&gt;Fundamentally, the architect needs to understand two things:&lt;br /&gt;1) goals&lt;br /&gt;go back to the "ities"&lt;br /&gt;If we are building an HR system for a company with 50ppl, the software will be different than built for a company with 100,000.&lt;br /&gt;If you don't know where you are going how can you figure out how to get there.&lt;br /&gt;2) constraints&lt;br /&gt;Money&lt;br /&gt;Time,&lt;br /&gt;Resources (developers, machines, etc)&lt;br /&gt;Domain&lt;br /&gt;Abilities of the team members. (This is often a hidden constraint that's hard to track.  If your team members can't grok your architecture, then you are going to have problems.  Either you have to figure out how to teach them or change your architecture)&lt;br /&gt;&lt;br /&gt;Without understanding the goals and constraints, you have no idea what or how you are even going to build it.&lt;br /&gt;&lt;br /&gt;Architects reassess&lt;br /&gt;- goals&lt;br /&gt;  changing business climate changes goals&lt;br /&gt;- constraints&lt;br /&gt;  changing business climate changes constraints (How do we handle less bodies?)&lt;br /&gt;- projects progress against those goals&lt;br /&gt;- projects impact on the business&lt;br /&gt;  competitive advantage, users' reactions&lt;br /&gt;  productivity, costs/benefits/ROI&lt;br /&gt;&lt;br /&gt;Business don't stop.  So you need to be agile.&lt;br /&gt;&lt;br /&gt;Architects need to explore..&lt;br /&gt;- new technologies&lt;br /&gt;- new methodologies&lt;br /&gt;- new "isms"&lt;br /&gt;- in short, determine the viability of new technologies to fit the needs current system(s)&lt;br /&gt;- NOTE: be careful of "The Coolness Trap"&lt;br /&gt;"cool" doesn't mean "appropriate"...&lt;br /&gt;&lt;br /&gt;Patterns&amp;Architecture&lt;br /&gt;- isn't architecture just judicious application of patterns?&lt;br /&gt;No.  Patterns are often overused.&lt;br /&gt;- aren't patterns in of themselves architecture?&lt;br /&gt;No.  Patterns help describe architectural elements but they aren't architecture in of themselves.&lt;br /&gt;- so what do patterns do for us?&lt;br /&gt;Give us a way to talk to other developers with a higher-level of abstraction.&lt;br /&gt;&lt;br /&gt;Summary:&lt;br /&gt;&lt;br /&gt;Architecture is important: if it's not defined explicitly, it will be defined implicitly.&lt;br /&gt;- and may not be something you'd like&lt;br /&gt;Architecture represents a higher level perspective than implementers typically think at, and therefore keeps an eye on different issues.&lt;br /&gt;Architecture defines a style for the system and as such answers some questions even before they're asked.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Great presentation!  I'm going to be going to for lunch now!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-1098879951787718388?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/1098879951787718388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=1098879951787718388' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1098879951787718388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/1098879951787718388'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-session-three.html' title='Dev Teach 2009 - Session Three'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-3077729343053755579</id><published>2009-06-09T09:29:00.000-07:00</published><updated>2009-06-09T10:42:30.566-07:00</updated><title type='text'>Dev Teach 2009 - Session Two</title><content type='html'>Silverlight 2 - A Through Introduction&lt;br /&gt;&lt;br /&gt;The speaker seems to think that Silverlight is a complete game changer, allowing us to write desktop type applications in a web browser.&lt;br /&gt;&lt;br /&gt;10:33 - Silverlight v1 provided lots of media tools, but is not great for business software.&lt;br /&gt;&lt;br /&gt;10:34 - You can build games in Silverlight.&lt;br /&gt;&lt;br /&gt;10:35 - Silverlight v2 provides more business development support than v1.  You do not require the full .NET framework.  The download is only 4.6megs.  Nokia might preinstall the silverlight framework.&lt;br /&gt;&lt;br /&gt;10:40 - It is a composite framework, so you will have to use wcf client/server applications to provide a rich domain.  Silverlight can interoperate with AJAX and HTML DOM.  Stores stuff on the users computers.&lt;br /&gt;&lt;br /&gt;10:50 - Microsoft has alot of open source controls on codeplex.  These allow developers to extend silverlight.&lt;br /&gt;&lt;br /&gt;10:55 - This is indeed a thorough introduction.  The speaker seems good.&lt;br /&gt;&lt;br /&gt;10:57 - Animations - seem relatively easy way to add visual flair to our applications.  Any property in XAML can be animated.&lt;br /&gt;&lt;br /&gt;11:08 - Deep Zoom is really cool.&lt;br /&gt;&lt;br /&gt;11:10 - There is more indepth databinding than you have in winforms - Twoway, oneway, OneTime.  Things to look up.  This can allow some really cool things like updating charts or allow for realtime monitoring of live systems (such as say an integration system).&lt;br /&gt;&lt;br /&gt;11:15 - Blend is a really nice way to make the xaml alot easier than trying to use the visual studio designer.  However, I believe that visual studio 2010 will make blend slightly more obsolete.  That said, visual studio and microsoft in general has failed to live up to potential many many times.&lt;br /&gt;&lt;br /&gt;11:30 - We've moved into whether or not we should be using Silverlight vs Flash vs Flux etc.  Basically the speakers opinion is that we should use Silverlight cause he is a .NET developer.  Silverlight itself is HD, and he doesn't believe that Flash is HD.&lt;br /&gt;&lt;br /&gt;Here are the slides:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.devteach.com/wconnect/wc.dll?FournierTransformation~1,20,1,003547\SLV256\Intro+to+Silverlight+2+for+DevTeach%2Epptx"&gt;Slides!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;11:45 - Silverlight v3 (currently Beta)&lt;br /&gt;Offline Apps&lt;br /&gt;3D graphics 1080p True HD streaming&lt;br /&gt;Seems cool&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-3077729343053755579?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/3077729343053755579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=3077729343053755579' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/3077729343053755579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/3077729343053755579'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-session-two.html' title='Dev Teach 2009 - Session Two'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-8010641552078394234</id><published>2009-06-09T08:08:00.000-07:00</published><updated>2009-06-09T09:09:25.593-07:00</updated><title type='text'>Dev Teach 2009 - Session One</title><content type='html'>So here I am at devteach. The next series of posts are going to be my thoughts on the conference as we go.&lt;br /&gt;&lt;br /&gt;So starting with the Keynote Talk.  I have to say that I was not terribly thrilled with the concept of the Keynote Speech (Tom Huckaby).  Visual Studio "Your Development Happy Place".   I expected it to be a rah rah Microsoft speech.  My actual thoughts will come as we go.&lt;br /&gt;&lt;br /&gt;9:15 - Dude's been talking about his history of developing so far.  We just got through his vb3.0 days.  So far we have avoided any sort of sales pitch.  Good speaker.&lt;br /&gt;&lt;br /&gt;9:17 - I think I've heard enough about his history.  Talking about Microsoft Site Server, arguably the worst product that Microsoft ever released.  I guess Keynote speeches are usually stories about the speaker.  What does this have to do with visual studio?&lt;br /&gt;&lt;br /&gt;9:21 - Time for a Demo... let's see what this guy has...&lt;br /&gt;&lt;br /&gt;9:25 - Showing us a demo of a WPF application of a fast food management console.  Mmmm burgers.  So this is part of the Windows 7 touch screen stuff.  Looks pretty cool actually.  I guess that kiosks are going to become more important in the fast food industry.  People don't feel guilty when they order too much fatty food from a machine.&lt;br /&gt;&lt;br /&gt;9:30 - The Rich Client Stack for .NET (Our Options Nowadays) &lt;br /&gt;WPF(Windows Presentation)&lt;br /&gt;Silverlight&lt;br /&gt;Surface&lt;br /&gt;Windows 7 Touch&lt;br /&gt;&lt;br /&gt;All of these are xaml based and if you master the first, they all become easy to learn.&lt;br /&gt;&lt;br /&gt;This guys just scuttled himself in my eyes by saying that he ASP.NET is a great way to develop software.  Sigh.&lt;br /&gt;&lt;br /&gt;9:35 - Demo for touch screen, there is some sort of windows surface.  Haven't heard of it before, but it's pretty cool.  Looks pretty geeky, I think Terry would like it.  Seems Windows 7 has complete .NET touch screen support.  Looks pretty cool.&lt;br /&gt;&lt;br /&gt;9:40 - Rah Rah Visual Studio!  This is the tool, the competitors just don't stand up.  Rah Rah!&lt;br /&gt;&lt;br /&gt;9:45 - It's important to integrate the designers.  I guess that Visual Studio is supposed to allow the designers to live in Visual Studio.  As much as microsoft is pushing for that I don't quite think they are their yet.&lt;br /&gt;&lt;br /&gt;9:46 - Another demo of a touch screen application written in .NET.  Something that was built for/before the elections.  Lots of draggy touchy goodness.  This windows surface thing is actually kinda cool because it allows users to work with their computers in a more natural/understandable way.&lt;br /&gt;&lt;br /&gt;9:49 - Visual Studio 2010&lt;br /&gt;&lt;br /&gt;- New Visual Studio Shell&lt;br /&gt;- Tear-off Windows (finally!)&lt;br /&gt;- New Project Dialog (wtf... hasn't this been around for a while??)&lt;br /&gt;- Snippets in html&lt;br /&gt;- Other stuff... I need to type faster.  Didn't seem terribly revolutionary.&lt;br /&gt;&lt;br /&gt;9:51 - So a chick just came up (Beth Massi) and laid the hammer down on Tom for talking about himself for 45 minutes.  Nice work.  Nervous laughter around the room.  I think she hit the nail on the head.  She's going to do a demo of 2010 now.&lt;br /&gt;&lt;br /&gt;Oooh I'm supposed to call in Visual Studio Twenty Ten.&lt;br /&gt;&lt;br /&gt;9:56 - The bulb went out.&lt;br /&gt;&lt;br /&gt;9:57 - I guess that the new designer will be better for WPF than the old one.&lt;br /&gt;&lt;br /&gt;10:00 - More code generation based on data sources.  Databinding scares me.&lt;br /&gt;&lt;br /&gt;10:05 - Talk is winding down.  Oh my god.  This video is ridiculous.  "YOU NEED A TEAM SYSTEM!!!"&lt;br /&gt;&lt;br /&gt;So, the final word on the talk was: Fluffy as I had expected.  The $5 worth of pastries I got by waking up early enough for the keynote talk were not worth it.&lt;br /&gt;&lt;br /&gt;Ah well, next talk is in 20 minutes.  Introduction to Silverlight.  Should be interesting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-8010641552078394234?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/8010641552078394234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=8010641552078394234' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8010641552078394234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8010641552078394234'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/06/dev-teach-2009-session-one.html' title='Dev Teach 2009 - Session One'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-7057470976912735339</id><published>2009-03-15T15:28:00.000-07:00</published><updated>2009-03-15T18:50:20.208-07:00</updated><title type='text'>Context based specifications</title><content type='html'>I have been using context based specifications for almost a year now.&lt;br /&gt;&lt;br /&gt;Originally I would have used something like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class EBCClientFactorySpecs&lt;br /&gt;{&lt;br /&gt;  protected MockRepository mockery = new MockRepository();&lt;br /&gt;  protected IClientFactory sut;&lt;br /&gt;&lt;br /&gt;  protected virtual IClientFactory CreateSUT()&lt;br /&gt;  {&lt;br /&gt;    return new ClientFactory();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[TestFixture]&lt;br /&gt;public class When_a_EBC_Client_Factory_is_asked_to_create_a_new_client : EBCClientFactorySpecs&lt;br /&gt;{&lt;br /&gt;  [Test]&lt;br /&gt;  public void Should_create_a_new_client()&lt;br /&gt;  {&lt;br /&gt;    sut = CreateSUT();&lt;br /&gt;    var accountNumber = new AccountNumber(25);&lt;br /&gt;    var newClient = sut.CreateNewClient(accountNumber);&lt;br /&gt;    newClient.ShouldBeAValidNewEntity();&lt;br /&gt;    newClient.ShouldBeANewClientWith(accountNumber);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I then pulled a base class out of this to use in most general situations, though the base class was pretty simple:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;namespace Test&lt;br /&gt;{&lt;br /&gt;  public abstract class BaseSpecs&amp;lt;suttype&amp;gt;&lt;br /&gt;  {&lt;br /&gt;    protected SUTType sut;&lt;br /&gt;    protected MockRepository mockery = new MockRepository();&lt;br /&gt;    protected abstract SUTType CreateSUT();  &lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I went on to working at Cortex Business Solutions in January and &lt;a href="http://weblogs.asp.net/sfeldman/"&gt;Sean Feldman&lt;/a&gt; had set up a more sophisticated way of doing context based specifications.&lt;br /&gt;&lt;br /&gt;The tests would look something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;[Concern(typeof(Partners))]&lt;br /&gt;[TestFixture]&lt;br /&gt;public abstract class Partners_Specs : ContextSpecification&amp;lt;partners&amp;gt;&lt;br /&gt;{&lt;br /&gt;  protected override Partners create_system_under_test()&lt;br /&gt;  {&lt;br /&gt;    return new Partners();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected override void establish_context()&lt;br /&gt;  {&lt;br /&gt;    system_under_test = create_system_under_test();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class When_Partners_is_asked_to_return_customers_for_a_specified_supplier : Partners_Specs&lt;br /&gt;{&lt;br /&gt;  //setup test variables&lt;br /&gt;&lt;br /&gt;  protected override void establish_context()&lt;br /&gt;  {&lt;br /&gt;    // setup things required for the test&lt;br /&gt;    base.establish_context();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected override because()&lt;br /&gt;  {&lt;br /&gt;    result = system_under_test.GetCustomers(supplier1);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  [Observation]&lt;br /&gt;  public void Should_return_customers_for_the_supplier()&lt;br /&gt;  {&lt;br /&gt;    result.should_only_contain(customer1, customer2);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And the base class looked something like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;[TestFixture]&lt;br /&gt;public abstract void ContextSpecification&amp;lt;suttype&amp;gt;&lt;br /&gt;{&lt;br /&gt;  [Setup]&lt;br /&gt;  public void Setup()&lt;br /&gt;  {&lt;br /&gt;    establish_context();&lt;br /&gt;    because();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  //... other stuff&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There are several drawbacks that should come to mind relatively quickly:&lt;br /&gt;1) Each test fixture can only have a single "because"&lt;br /&gt;2) Each test fixture can only have a single "establish_context"&lt;br /&gt;&lt;br /&gt;This leads to issues when you have several cases that you need to test.  The solution is either really really long class names:&lt;br /&gt;When_Logger_is_asked_to_log_and_a_logger_handler_has_been_added&lt;br /&gt;When_Logger_is_asked_to_log_and_no_logger_handlers_have_been_added&lt;br /&gt;&lt;br /&gt;or as I decided to try (and didn't stop trying so it kinda got adopted by defacto standard):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class And_a_logger_handler_has_been_added : When_Logger_is_asked_to_log&lt;br /&gt;{&lt;br /&gt;  protected override void establish_context()&lt;br /&gt;  {&lt;br /&gt;    Logger.LogWith(new LoggerImpl());&lt;br /&gt;    Logger.AddHandler(new TraceHandler_Mock());&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  [Observation] // attribute inherits from TestAttribute&lt;br /&gt;  public void Should_log_to_the_specified_logger()&lt;br /&gt;  {&lt;br /&gt;    testListenerMock.messages[0].should_be_equal_to(string.Format("ABC {0}", message);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class And_no_logger_handlers_have_been_added : When_Logger_is_asked_to_log&lt;br /&gt;{&lt;br /&gt;  .. other observations&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This actually leads to some confusion due to the readability issues and the inheritance (things are hidden in the base classes), but both Sean &amp;amp; I, and I believe other members of the development team at cortex were ok dealing with the added complexity.&lt;br /&gt;&lt;br /&gt;Unfortunately, like every story of the itzy bitzy spider, the rain did come along.  A couple of contractors, came along and pointed out the high level of complexity of the tests as opposed to what they were used to.  Additionally, they pushed for Strict mocking as opposed to dynamic mocking.  Strict mocking is an issue for context_based specifications as each observation should only verify one thing and since each is a [Test] and therefore independent, strict mocking will by definition fail.  (My opinion of strict mocking is that it is a painful waste of time, but that's a topic for a different post)&lt;br /&gt;&lt;br /&gt;While I was working on the Calgary XNA usergroups game of the month (Astroids), for which I am giving a talk about unit testing on April 8th.  I spent a bit of time playing around with trying to deal with the issues that were brought up and simply existed with the way that we did context based specifications.&lt;br /&gt;&lt;br /&gt;To summarize the issues:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1) Can't do strict mocking (meh)&lt;br /&gt;2) only one "because" per TestFixture leads to too much inheritance (confusion)&lt;br /&gt;&lt;br /&gt;This is the test code that I wrote up last night to attempt to solve these issues:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;public class MovementBehavior_Specs : BaseSpecs&amp;lt;imovementbehavior&amp;gt;&lt;br /&gt;{&lt;br /&gt;  protected override IMovementBehavior CreateSUT()&lt;br /&gt;  {&lt;br /&gt;    return new MovementBehavior();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[TestFixture]&lt;br /&gt;public class When_movement_behavior_is_asked_to_accelerate : MovementBehavior_Specs&lt;br /&gt;{&lt;br /&gt;  private const int maxSpeed = 7;&lt;br /&gt;  private const int acceleration = 5;&lt;br /&gt;&lt;br /&gt;  protected void and_the_resulting_velocity_is_below_the_max_velocity()&lt;br /&gt;  {&lt;br /&gt;    sut.Velocity = 0;&lt;br /&gt;    sut.Accelerate(acceleration, maxSpeed);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected void and_the_resulting_velocity_is_above_the_max_velocity()&lt;br /&gt;  {&lt;br /&gt;    sut.Velocity = 4;&lt;br /&gt;    sut.Accelerate(acceleration, maxSpeed);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected void and_the_inputed_maxSpeed_is_less_than_the_acceleration()&lt;br /&gt;  {&lt;br /&gt;    sut.Accelerate(5, 1);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  [Observation("and_the_resulting_velocity_is_below_the_max_velocity")]&lt;br /&gt;  public void Should_increase_the_current_velocity_by_the_amount_passed_in()&lt;br /&gt;  {&lt;br /&gt;    sut.Velocity.ShouldBeEqualTo(acceleration);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  [Observation("and_the_resulting_velocity_is_above_the_max_velocity")]&lt;br /&gt;  public void Should_set_the_velocity_to_the_max_velocity()&lt;br /&gt;  {&lt;br /&gt;    sut.Velocity.ShouldBeEqualTo(maxSpeed);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  [Observation("and_the_inputed_maxSpeed_is_less_than_the_acceleration")]&lt;br /&gt;  [ShouldThrowException(typeof(InvalidVelocityException))]&lt;br /&gt;  public void Should_throw_InvalidVelocityException()&lt;br /&gt;  {}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class SpaceShip_Specs : BaseSpecs&lt;SpaceShip&gt;&lt;br /&gt;{&lt;br /&gt;  protected Mock&lt;IMovementBehavior&gt; mockMovementBehavior = new Mock&lt;IMovementBehavior&gt;(MockBehavior.Strict);&lt;br /&gt;  protected Mock&lt;IAttackBehavior&gt; mockAttackBehavior = new Mock&lt;IAttackBehavior&gt;(MockBehavior.Strict);&lt;br /&gt;&lt;br /&gt;  protected override SpaceShip CreateSUT()&lt;br /&gt;  {&lt;br /&gt;    return new SpaceShip(mockMovementBehavior.Object, mockAttackBehavior.Object);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[TestFixture]&lt;br /&gt;public class When_a_space_ship_is_told_to_attack : SpaceShip_Specs&lt;br /&gt;{&lt;br /&gt;  private readonly Angle angle;&lt;br /&gt;  &lt;br /&gt;  protected override void Because()&lt;br /&gt;  {&lt;br /&gt;    mockMovementBehavior.SetupGet(x =&gt; x.Direction)&lt;br /&gt;      .Returns(angle);&lt;br /&gt;    mockAttackBehavior.Setup(x =&gt; x.Attack(angle));&lt;br /&gt;    sut.Attack();&lt;br /&gt;  }&lt;br /&gt;    &lt;br /&gt;  [Observation]&lt;br /&gt;  public void Should_get_the_direction_from_the_movement_behavoir()&lt;br /&gt;  {&lt;br /&gt;    mockMovementBehavior.VerifyGet(x =&gt; x.Direction);&lt;br /&gt;  }&lt;br /&gt;  [Observation]&lt;br /&gt;  public void Should_leverage_its_attack_behavior_to_attack()&lt;br /&gt;  {&lt;br /&gt;    mockAttackBehavior.Verify(x =&gt; x.Attack(angle));&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The testdriven.net output looks like this:&lt;br /&gt;------ Test started: Assembly: Astroids.Test.dll ------&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;When movement behavior is asked to accelerate&lt;br /&gt;    and the resulting velocity is below the max velocity Should increase the current velocity by the amount passed in... passed!&lt;br /&gt;    and the resulting velocity is above the max velocity Should set the velocity to the max velocity... passed!&lt;br /&gt;&lt;br /&gt;1 passed, 0 failed, 0 skipped, took 2.23 seconds.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Sexy, ain't it?&lt;br /&gt;&lt;br /&gt;The essence is that there is a single test in the base class called "observations", this test runs through the current class to find any methods with the [Observation] attribute.  If the observation attribute exists and there is text passed in, then it will look for a method with that name and execute it before executing the observation. If there is no text, then the virtual method "Because" will be called.&lt;br /&gt;&lt;br /&gt;In my mind there are three drawbacks to this method:&lt;br /&gt;1) Can't leverage TD.NET to execute a single [Observation], you need to execute the entire [TestFixture] &lt;i&gt;Could add a constructor which calls Setup to the base class, but could be dangerous as there is no way to call TearDown&lt;/i&gt;&lt;br /&gt;2) [Observation("&lt;b&gt;something_exists&lt;/b&gt;")] is text and must match a method within the [TestFixture]. &lt;i&gt;Resharper handles this nicely if you rename the method&lt;/i&gt;&lt;br /&gt;3) There is alot of reflection and magic going on in the back ground and this could lead to more confusion. &lt;i&gt;This is testing, there is alot of magic and reflection going on anyway&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;What it gives you are:&lt;br /&gt;&lt;br /&gt;1) All test code related to a single method call is within a single TestFixture (solves problem 2)&lt;br /&gt;2) Since all observations are fired within the same [Test], Strict Mocking is fully supported (solves problem 1)&lt;br /&gt;3) The reports are much nicer and more readable (yay)&lt;br /&gt;4) Gives you the flexibility to swing both ways ([Test] or [Observation])&lt;br /&gt;&lt;br /&gt;Thoughts?&lt;br /&gt;&lt;br /&gt;I'm going to be playing with this further on my own projects, I don't know if anybody at work will actually be interested in following this and there are a few potential issues that have my spidey senses tingling, but right now from a readability and understandability perspective, I like it alot.&lt;br /&gt;&lt;br /&gt;A couple of other things I learnt:&lt;br /&gt;1) I really don't like mbUnit and Gallio.  Perhaps it's a noble goal but seriously why do I need to include my test runner as a reference in my testing project?  Nunit offers everything that I use in mbUnit (including rowtest).&lt;br /&gt;2) Rhino.Mocks is buggy and looking a little old in the tooth.  I'm really like the clean, separated and easy to use interface of MOQ.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-7057470976912735339?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/7057470976912735339/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=7057470976912735339' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7057470976912735339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7057470976912735339'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/03/context-based-specifications.html' title='Context based specifications'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-7234508461545552034</id><published>2009-02-18T11:23:00.000-08:00</published><updated>2009-02-18T11:24:52.267-08:00</updated><title type='text'>Multiple Monitor Users</title><content type='html'>Just a shout out to those who can use multiple monitors at work.  DisplayFusion is a free app that allows you to move apps back and forth across the monitors (and more) and also allows you to have a different background for each monitor.  Highly recommend you check it out.&lt;br /&gt;&lt;br /&gt;http://www.binaryfortress.com/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-7234508461545552034?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/7234508461545552034/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=7234508461545552034' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7234508461545552034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7234508461545552034'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2009/02/multiple-monitor-users.html' title='Multiple Monitor Users'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-7771851554964660353</id><published>2008-12-03T15:43:00.000-08:00</published><updated>2008-12-04T13:36:21.812-08:00</updated><title type='text'>The Unlisted Conference Day II</title><content type='html'>So the conference ended two days ago, and I just want to put in my thoughts and feelings about yesterday as well.  The day started in it's normally unglamourous way with my cell phone awakening me at an ungodly hour (7:30... I don't get up that early for work!)   Breakfast was again, phenomenal and I really have to credit the Banff Centre for providing us with really quality food.  (Me like good food...)&lt;br /&gt;&lt;br /&gt;The first session of the day was actually a really interesting session about balance and wellness put on by a pair of personal trainers from PHAT training in Edmonton.    The main concept that they brought up was the concept of "Mind, Body and Spirit", you have to have balance between the three of them.  This makes alot of sense, without a strong body, (fit) you can't have a strong mind, and if you are depressed you'll have a hard time being strong or performing to your intellectual capabilities.  They also went through a bunch of exercises that we can do in the office in order to keep the blood moving.  All in all, it was quite an interesting session.  You can find a summary &lt;a href="http://www.unlimitedmagazine.com/blog/?p=36"&gt;here&lt;/a&gt;(there are actually several summaries &lt;a href="http://www.unlimitedmagazine.com/blog/index.php"&gt;here&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;The next session was actually delivered by my personal coach Chris Hammer of &lt;a href="http://www.silverhammercoaching.ca/"&gt;Silver Hammer Coaching&lt;/a&gt;.  He focused on SMART goals and again there is a summary above.  Over all I think that he gave a quality presentation, but I feel that he focused too much on the Psychology of goals setting rather than on practical tips to staying motivated.  He actually did have those, they were kinda glosed over due to lack of time.&lt;br /&gt;&lt;br /&gt;Lunch was again fantastic.  Great buffet selection.  (Mmmm food)  At lunch I said goodbye to several of the friends I had made over the couple of days as they were heading home early.&lt;br /&gt;&lt;br /&gt;Following lunch we had a presentation on resume building (summary above) which was pretty interesting.  It was really interesting to see a recruiter's perspective.  I honestly, in the interviews I have done, saw many of the issues she brought up.  She was a fantastic speaker and I feel I gained alot from it.&lt;br /&gt;&lt;br /&gt;The next talk focused on Leadership with a Cross Cultural focus.  Chris Hammer provided the session and I think that he again covered some interesting topics.  The talk wasn't my favourite and I know that it wasn't really targeted at me.&lt;br /&gt;&lt;br /&gt;The final talk of the weekend was actually a combined talk between a lady from BullFrog power and Tigress Ventures.  Both ladies were extremely dedicated to passing on the message of green power and green businesses.  The message that I got from them is that there is actually a business ROI (return on investment) from becoming green.  For example reducing power consumption by turning off your computers at night saves power and $$$.  Becoming a paperless organization saves money for printing and paper disposal whether you recycle or not.  Interesting talk, definitely food for thought.&lt;br /&gt;&lt;br /&gt;All in all I feel that the conference was quite good and I feel that it was well worth the money I might have spent to attend had I not been given free attendance by my personal coach Chris Hammer.  If any reader here is considering being a young entrepreneur, I highly recommend looking into next years conference.  The food and venue were fantastic.  I really hope that I can attend next year.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-7771851554964660353?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/7771851554964660353/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=7771851554964660353' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7771851554964660353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7771851554964660353'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/12/unlisted-conference-day-ii.html' title='The Unlisted Conference Day II'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-8164347952377125219</id><published>2008-12-01T09:01:00.000-08:00</published><updated>2008-12-01T22:59:58.731-08:00</updated><title type='text'>The unlisted conference</title><content type='html'>I recently got an opportunity to attend the unlisted conference right now.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.unlimitedmagazine.com/index.php?option=com_content&amp;amp;task=view&amp;amp;id=330&amp;amp;ed=11&amp;amp;cat=22"&gt;http://www.unlimitedmagazine.com/index.php?option=com_content&amp;amp;task=view&amp;amp;id=330&amp;amp;ed=11&amp;amp;cat=22&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I figured, why the heck not.  Nothing to lose.  Actually to be perfectly honest I thought, holy fucking shit, what an amazing opportunity I'd be retarded not to take advantage of it, but this is a children friendly blog so I won't write that.&lt;br /&gt;&lt;br /&gt;Anyway, the basic premise of the conference in the "Professional Development for the New Business Culture."  I guess that I'm part of the new business culture now.  Ya me.  Actually most of the people in my age (all the people) are part of this new business culture.  We are the generation that needs to push change and growth in the business world.  Once all the old farts retire, we will be the ones in charge (god help the world if I'm one of the people in charge...)&lt;br /&gt;&lt;br /&gt;Last night I attended the reception and to be perfectly honest, I sat got there early and thought to myself, "What the hell am I doing here???"  I didn't know ANYBODY except for my awesome personal coach Chris Hammer of &lt;a href="http://www.silverhammercoaching.ca"&gt;www.silverhammercoaching.ca&lt;/a&gt;; whom I have to thank for this awesome opportunity in the first place.  Regardless, he's my coach, and while he is becoming a friend, he is still my coach and I hesitated to use him as a social crutch.  I called up Emilie and asked what I was doing there?  Anyway, after a short conversation I walked into the room.  A fellow from the Business School in Alberta introduced himself to me and we had a good "small talk" conversation.  The ice was broken.  From there, I went on to meet a total of 8 new people.  I haven't met 8 new people in the last 2 years.&lt;br /&gt;&lt;br /&gt;I met another 4 new people in the morning and the breakfast was phenomenal.  The banff centre is really a great place.  Really nice for this sort of thing.&lt;br /&gt;&lt;br /&gt;The meat of the conference was started today.   The first talk focused on philantropy and volunteering for organizations.  The talk itself was actually far more interesting that I had expected and raised some interesting questions for me.  The truths that he spoke made alot of sense to me.  Though, I have to say that it became obvious to me that the speaker was an experienced business man as he really focused on ROI from the volunteering as opposed to doing good.  I suppose that charities thrive on people like that, but it does seem to somewhat cheapen the act for me.  The ROI in question, being mostly focused on connections made with CEO's and other people of power that we would never have the opportunity to meet otherwise. Regardless, the questions that I asked of myself, are along the lines of what can I do to both volunteer my time and gain the ROI that volunteering provides.  I have done some volunteering for the stampede lotteries, but I guess that I really didn't feel passionate about what I was creating and the value that it would provide.  I do wonder what sort of opportunitiest there are out there where software developers like myself can both grow as software developers and gain contacts in the industry.&lt;br /&gt;&lt;br /&gt;The second talk of the morning talked about strategic planning.  The basic idea that the presenter attempted to pass on is that we need to make plans whether they be for personal life or business.  We had to do an exercise on creating a story of how our day went in 5 years.  I struggled mightly with it as I am very unclear of my path in the future.  There was also a holistic goal setting exercise taken from the story where we would set our goals based on (order matters) "Do, Be, Have" in that order.  I believe the book referenced in the talk was  Go Green Live Rich, By David Bach.  Not sure I'm sold on the book (more accurately the author) but, the concept of goal setting focusing on the self rather than on the possessions was pretty novel.&lt;br /&gt;&lt;br /&gt;Lunch was an interesting workshop on creative leadership.  We did a few visualization exercises to help get a slightly deeper connection with the people at the table.  The content of the workshop was fantastic and covered a few active techniques that we can use to be creative in our leadership.  There wasn't alot of time so we just did a few interesting activities including passing energy balls back and forth with a partner.  It was pretty cool.&lt;br /&gt;&lt;br /&gt;Following lunch was the worst part of the day.  The presentation was on networking (something I have been really working on! I sat with 5 new people at lunch, and met a global reporter during the talks (whom I didn't recognize)) but the presenters were staleand read from their notes %100.  It was not a well delivered talk.  Unfortunate as my attention wandered.&lt;br /&gt;&lt;br /&gt;The next talk was absolutely fantastic!  Lesley  Scorgie, wrote the the book Rich By Thirty &lt;a href="http://www.richbythirty.com/"&gt;http://www.richbythirty.com/&lt;/a&gt; a book which I of course bought shortly after the talk.  She is an amazingly talented speaker, who in an informal way, really connects with the audience.  It helped that the topic she spoke on talked to so many people in the audience.  Especially me.  I don't do money saving so good.  I came out of the session with a list of action items and a book to read.  RRSP land here I come!  I got 4 years left to become rich, yippy.&lt;br /&gt;&lt;br /&gt;Following this there was a short break.  There was another reception before the keynote dinner (my very first keynote dinner) and there I interacted with several new people again.  When dinner time came, I consciously decided to sit at a table where I knew nobody.  It worked out quite nicely and I believe that I have met some invaluable contacts.  The content of the keynote dinner was actually pretty impressive.  The speaker got himself into a gig as the owner of a modeling agency at the age of 14.  Currently he is challenging the status quo of the fashion industry and it was pretty inspiring to see.  A fellow conferencite told me afterward that he didn't feel that the talk really applied to him.  I explained to the fellow that the talk wasn't really about changing an industry as most of us will never get to that place.  But rather, the talk was about changing injustice or something that is wrong.  This change can come within an industry or perhaps just your team.  The message is that you have to have the confidence to take the action required to institute that change, and further more take the risk that the change may never happen.&lt;br /&gt;&lt;br /&gt;This of course has me thinking about the software consultant industry... but that's a post for another day (perhaps month at my current rate).&lt;br /&gt;&lt;br /&gt;PS: if you are in Calgary, reading this and interested, post me a comment as I am doing a talk on Sim Climber on Wednesday the 10th.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-8164347952377125219?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/8164347952377125219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=8164347952377125219' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8164347952377125219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8164347952377125219'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/12/unlisted-conference.html' title='The unlisted conference'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-2538593990092679578</id><published>2008-08-20T21:37:00.000-07:00</published><updated>2008-08-20T21:54:31.024-07:00</updated><title type='text'>Abstract Base Classes and design by contract</title><content type='html'>So after viewing how &lt;a href="http://www.jpboodhoo.com"&gt;JP Boodhoo&lt;/a&gt; does his design by contract I kinda went a little far.  Everything got an interface.  This isn't necessarily a bad thing and in fact I completely agree with the practise.  However, I have found that there is one caveat to this concept.&lt;br /&gt;&lt;br /&gt;Both Interfaces and Abstract Base Classes are considered contracts.  Because you can't instantiate an abstract base class, it doesn't need to implement an interface.  In fact, having an interface can lead to confusion amongst the development team about which to implement.&lt;br /&gt;&lt;br /&gt;For example, in a project that I have the unique joy of refactoring as we speak (read sarcasm), there were many abstract base presenters and their equivalent interfaces.  The problem came when the developers didn't know whether to implement the interface or the base abstract class.  And they did everything.  Some implemented the base presenters, some implemented the interfaces, some didn't do anything.  Basically there was no consistency.  It was so complex that I needed to draw out the relationships on the board before I figured it all out.&lt;br /&gt;&lt;br /&gt;So in my refactor I got rid of all the interfaces (except the original interface) and ended up with classes that looked like this:&lt;br /&gt;&lt;br /&gt;IPresenter&lt;br /&gt;BasePresenter : IPresenter&lt;br /&gt;BaseTaskPresenter : BasePresenter&lt;br /&gt;BaseTaskSavablePresenter : BaseTaskPresenter&lt;br /&gt;BaseFormPresenter : BasePresenter&lt;br /&gt;BasePanelPresenter : BasePresenter&lt;br /&gt;&lt;br /&gt;This makes it clean and clear what the intent of the framework is for, ie if you have a task presenter implement the abstract base task presenter, need to save, implement the BaseTaskSavablePresenter.&lt;br /&gt;&lt;br /&gt;The only potential drawback that comes from this is that it is now impossible for somebody to do something like&lt;br /&gt;&lt;br /&gt;interface ISpecialTaskPresenter : BaseTaskPresenter&lt;br /&gt;&lt;br /&gt;and forces the future path down abstract base classes.  This is a trade off but I believe that the understandability added by removing the redundant interfaces is more than worth it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-2538593990092679578?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/2538593990092679578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=2538593990092679578' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/2538593990092679578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/2538593990092679578'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/08/abstract-base-classes-and-design-by.html' title='Abstract Base Classes and design by contract'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-7483421146829798882</id><published>2008-08-06T09:36:00.000-07:00</published><updated>2008-08-06T09:40:56.003-07:00</updated><title type='text'>The pain and power of mental toughness</title><content type='html'>I like to think I'm mentally tough... I can put my body through some pretty intense pain and keep on going.  But the truth is that when at 7:30am I'm struggling to get out of bed, I know I simply don't have the mental toughness that many have and that I'd like to have.  &lt;a href="http://www.cbc.ca/olympics/blog/athletes/adam_kreek/the_pain_and_power_of_mental_t.html"&gt;This&lt;/a&gt; is a great blog post about the true nature of mental toughness.  I'm going to need to read it a few more times, but I think that it can make a difference both in my sporting aspirations and my professional career.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-7483421146829798882?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/7483421146829798882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=7483421146829798882' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7483421146829798882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/7483421146829798882'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/08/pain-and-power-of-mental-toughness.html' title='The pain and power of mental toughness'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-8799836345328216140</id><published>2008-07-22T07:36:00.000-07:00</published><updated>2008-07-22T11:04:20.158-07:00</updated><title type='text'>I have been called out</title><content type='html'>My good friend Mo Khan  &lt;a href="http://mokhan.ca/blog/2008/07/12/Tag+MOs+IT.aspx"&gt;called me out&lt;/a&gt; (about a week or more ago... but I digress) so here it is:&lt;br /&gt;&lt;p&gt;&lt;strong&gt;How old were you when you first started in programming?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I believe that my first programming was when I was 10 or 11 on the Apple IIe.  My dad put me in summer computer courses at the Edmonton Science Centre.  First typing courses then programming courses&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;How did you get started in programming?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Pretty much been programming since I started using computers.  I had a relatively natural ability in programming.  Serious programming didn't start until highschool though.&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;What was your first programming language?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Apple Basic&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;What was the first real program you wrote?&lt;/strong&gt;&lt;/p&gt;The first real program would probably have been written for my graphing calculator in calculator basic.  There were many programs written during English and Biology the biggest being a strategy game which I had to stop writing because I ran outta space on my calculator.&lt;br /&gt;&lt;br /&gt;From a professional stand point, the first real program was an automatic build scheduler for the IBM DB2 build team.  It was written in PERL and worked out pretty well.&lt;br /&gt;&lt;p&gt;&lt;strong&gt;What languages have you used since you started programming?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Assembler, Java, C/C++, C#, Basic (in many shapes), Perl, Lisp, Python, Prolog, T-SQL, Matlab&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;What was your first professional programming gig?&lt;/strong&gt;&lt;/p&gt;I worked for IBM Canada on the DB2 product for the windows build system as a 16 month intern while I was at school.  It wasn't technically a programming gig, more of a manual build job, however, I did spend some time programming a tool to handle kicking off the builds for me.&lt;p&gt;&lt;strong&gt;If you knew then what you know now, would you have started programming?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Without a doubt. &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;If there is one thing you learned along the way that you would tell new developers, what would it be?&lt;/strong&gt;&lt;/p&gt;Programming isn't just about writing code that does the right thing, programming is about writing code that does the right thing and is easy to maintain and extend. &lt;br /&gt;&lt;p&gt;&lt;strong&gt;What's the most fun you've ever had programming?&lt;/strong&gt;&lt;/p&gt;  4 months of working on SimClimber was probably the most fun I've ever had programming.  There were many nights when I couldn't sleep because I was so tied up in the game that I would be up till 3 -4 am on work nights.  It wasn't great for the work but it was an absolute blast.&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Who am I calling out?&lt;/strong&gt;&lt;/p&gt;&lt;a href="http://www.invisible-city.com/sharon"&gt;Sharon Cichelli&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hmmm... I don't really know 4 other developers who blog (and haven't already been called out!.  If you know me and blog consider yourself called out!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-8799836345328216140?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/8799836345328216140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=8799836345328216140' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8799836345328216140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8799836345328216140'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/07/i-have-been-called-out.html' title='I have been called out'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-5781271125077707119</id><published>2008-07-11T09:39:00.000-07:00</published><updated>2008-12-09T04:42:44.631-08:00</updated><title type='text'>Camel Case Intellisense with Resharper</title><content type='html'>I just noticed this today:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_-DGD9abNBI0/SHeNj0TUjLI/AAAAAAAAAAM/Wvq42aLtF6E/s1600-h/IntelliSense.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://1.bp.blogspot.com/_-DGD9abNBI0/SHeNj0TUjLI/AAAAAAAAAAM/Wvq42aLtF6E/s320/IntelliSense.png" alt="" id="BLOGGER_PHOTO_ID_5221797939433999538" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Camel Case Intellisense, man that's going to make a huge productivity gain!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-5781271125077707119?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/5781271125077707119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=5781271125077707119' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5781271125077707119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/5781271125077707119'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/07/camel-case-intellisense-with-resharper.html' title='Camel Case Intellisense with Resharper'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_-DGD9abNBI0/SHeNj0TUjLI/AAAAAAAAAAM/Wvq42aLtF6E/s72-c/IntelliSense.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-3923056647908580132</id><published>2008-07-10T13:52:00.000-07:00</published><updated>2008-07-10T13:54:58.467-07:00</updated><title type='text'>Teaching old dogs</title><content type='html'>Two posts in a day, holy monkey... anyway,&lt;br /&gt;&lt;br /&gt;I currently have the pleasure of working with an individual who has been developing since before I started university, yet he was willing to listen to the new fandangled ideas of unit testing, tdd and proper software design.  It'll be a pity when he leaves the team to go to Ontario.  I guess this means more to me now, given that I heard several stories of developers who are so set in their ways that they are unwilling to learn or grow.  I made sure to thank him for being receptive.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-3923056647908580132?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/3923056647908580132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=3923056647908580132' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/3923056647908580132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/3923056647908580132'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/07/teaching-old-dogs.html' title='Teaching old dogs'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-508878579448169477</id><published>2008-07-10T09:31:00.000-07:00</published><updated>2008-07-10T09:47:22.824-07:00</updated><title type='text'>The Unit Testing Falacy</title><content type='html'>So, currently I am working on a piece of software where there is absolutely no Unit Testing.  Well actually that's not true.  The truth is that the early stages of the project had unit testing, however, the "senior" developer on the team claimed (this is paraphrased hearsay) that there was no way that they could do unit testing and meet the deadlines.  This type of thinking is pretty rampant in our industry and it is based on several highly flawed views of what unit testing is and what it isn't.&lt;br /&gt;&lt;br /&gt;The concept that unit testing is being written to speed up development is highly flawed.  There is pretty much no way that you can write unit tests and code faster than you could just write the code by itself.  It's simply a fact of typing speed.  10 lines of code is quicker to type than 20 lines of code.  Where the speed gains come are in the maintenance of the code, the debugging of the code and generally the part of the programming cycle that takes significantly more time than actually hashing out code.  People can't seem to understand that being a good developer is more than being able to make something function.  A blind monkey can make something function.  Making something function in such a way that other people can quickly and easily update it is the mark of a good programmer.&lt;br /&gt;&lt;br /&gt;The second fallacy when it comes to unit testing is that unit testing is actually about testing at all.   The testing part of unit testing is secondary to the true goals.  These goals include, designing good, low coupled software, proving that your software does what it's &lt;span style="font-weight: bold;"&gt;supposed&lt;/span&gt; to do and to document your code.  This is the reason behind the movement toward behaviour driven design.  BDD is an evolution of the TDD (test driven development) concept and moves unit testing away from the testing aspect and more toward the design aspect.  It's worth looking at.&lt;br /&gt;&lt;br /&gt;If you are working with a senior developer that says to you that they can't write unit tests because of time, inform them that they are not a senior developer and that if they don't want to write unit tests they will be paid as a junior.  Any body past a junior developer should be proficient at writing unit tests.  It's a brave new world, get used to it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-508878579448169477?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/508878579448169477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=508878579448169477' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/508878579448169477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/508878579448169477'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/07/unit-testing-falacy.html' title='The Unit Testing Falacy'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-6160642289086802622</id><published>2008-06-09T20:39:00.000-07:00</published><updated>2008-06-09T20:49:59.004-07:00</updated><title type='text'>Work Madness and jQuery Coolness</title><content type='html'>So my company recently spent 12 weeks wasting several hundred thousand dollars on a failed bid for a project.  Can't say that this terribly surprised me, as the project was pretty much a gong show from day one.  I was only involved with the effort about a month ago.  Unfortunately, they needed an html designer rather than a programmer.  In theory, there was a designer on the team but he was pulled onto another project about half way through.  Anyway, in the end I wasted a ton of time trying to figure out how to lay things out in html.  My html skills are pathetic.  This sorta leads me to a lesson for all my loyal readers.  Microsoft designer tools bleed you of technical skill.  It is too easy to drag and drop things on the screen.  One day when the designer is no longer available you are left by yourself and you realize how little you know.  So anyway, the project was a pretty big eye opener for me.  I need to spend a bunch of time learning basic html and css.  That's the next thing on my list.&lt;br /&gt;&lt;br /&gt;Anyway, the project itself was not a complete loss for me, I spent time, as alluded to before, playing with the brand spanking new ASP MVC framework (which exposed the emperors new clothes) and jQuery.  An anonymous request came through and asked me to post a few code snippets of things that I played with in jQuery.&lt;br /&gt;&lt;br /&gt;So here are some of the cooler things:&lt;br /&gt;&lt;br /&gt;1) Ajax Post:&lt;br /&gt;&lt;br /&gt;$("#ddlVetClinic").change(function(){&lt;br /&gt;   $.post("/SelfService.mvc/SetVetClinic", { clinic: $(this).val()},&lt;br /&gt;       function(data){$("#VetSelect").html(data);});&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Lets go through this line by line&lt;br /&gt;1. Set's up an listener on the ddlVetClinic's Change Event.&lt;br /&gt;2. Post to the server specifically /SelfService.mvc/SetVetClinic/ with clinic as the current value of the dropdown list.&lt;br /&gt;3. Set up a callback when the post completes which will write the data (presumably well formed html) to the element VetSelect.&lt;br /&gt;&lt;br /&gt;So in three lines, I've ajaxified the clinic dropdown list to display the vets who actually work at that clinic.&lt;br /&gt;&lt;br /&gt;2) Autocomplete&lt;br /&gt;&lt;br /&gt;This fellow made a super slick autocomplete with jQuery/Ajax.  Well worth taking a look at.&lt;br /&gt;&lt;br /&gt;http://fromvega.com/wordpress/2007/05/08/auto-complete-field-with-jquery-code-explained/&lt;br /&gt;&lt;br /&gt;3) Hiding/Showing a div&lt;br /&gt;&lt;br /&gt;This is pretty slick:&lt;br /&gt;&lt;br /&gt;$("#pictureUploadDiv").show('slow');&lt;br /&gt;&lt;br /&gt;Basically this makes a div slide slowly into place.  It's pretty cool looking and takes no effort what so ever.&lt;br /&gt;&lt;br /&gt;Anyway, I played a bit with jQuery and I know that next project I work on, jQuery and ASP MVC will play a significantly greater role than the rushed prototype I delivered.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-6160642289086802622?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/6160642289086802622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=6160642289086802622' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/6160642289086802622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/6160642289086802622'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/06/work-madness-and-jquery-coolness.html' title='Work Madness and jQuery Coolness'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-8314486457926026352</id><published>2008-05-13T10:23:00.000-07:00</published><updated>2008-05-13T10:26:17.877-07:00</updated><title type='text'>I'm addicted</title><content type='html'>Well, despite the request from my "boss" right now, I've gone ahead and played with ASP MVC and jQuery rather than using the .NET 2.0 WebForms framework.  And I have to say it is slick slick slick!  Ajax is so simple with the jQuery framework that it is almost like cheating.  And the MVC framework turns the mess that was WebForms into a joy to work with.  It takes a bit of getting used to, but man it's slick.  Everything is testable and again AJAX is so easy to use.  Anyway, I'm going to spend a bit more time playing with it before I write a bigger blogpost on it.  Just wanted to say, if you have the chance to play with them, do it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-8314486457926026352?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/8314486457926026352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=8314486457926026352' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8314486457926026352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8314486457926026352'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/05/im-addicted.html' title='I&apos;m addicted'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-3964228027632740190</id><published>2008-05-07T15:18:00.000-07:00</published><updated>2008-05-07T15:29:06.555-07:00</updated><title type='text'>Book Review - Who Moved My Cheese</title><content type='html'>Who Moved My Cheese, by Spencer Johnson, was a book that I was destined to read.  Funnily enough, JP recommended the book when I was at his Nothing But .NET course in Austin Texas.  Then less than a week after I returned from that course Emilie was lent a copy of Who Moved My Cheese by a co-worker of hers.  It took me a little while to get to this book because I was reading several other books (Pragmatic Programmer and Head First Design Patterns).  I haven't finished either of those books, but in order to assist myself with some difficult decisions that I'm going to have to make in the coming week I sat down to read it.&lt;br /&gt;&lt;br /&gt;The book is extremely short.  I read quickly and I finished it in less than an hour.  But within that book were poised some extremely important lessons on how to handle change in your life.  The book features 4 characters in a maze, two mice - sniff and scurry, and two little people - Hem and Haw.  The book follows each of these characters and how they handle the removal of their cheese.  It is well worth reading.&lt;br /&gt;&lt;br /&gt;Interestingly enough, I was affected by reading the novel no later than the following morning.  I play semi-competitive soccer and in order to play we need to be registered and the coach needs to have our player cards.  There was a problem with the registration and my card didn't make it to the game.  This meant that I would be unable to play.  Initially I was somewhat bitter, it's not fair, they moved my cheese.  But then I realized that sitting there being negative about the situation wasn't going to in anyway help me.  So instead, I put my cleats back on and went for a run while kicking the ball around.  So instead of being negative about the registration screw up, I went searching for new cheese and got a bit fitter during that time.&lt;br /&gt;&lt;br /&gt;Bottom line is: read this book, it may not change your life, but it will help you when your life changes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-3964228027632740190?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/3964228027632740190/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=3964228027632740190' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/3964228027632740190'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/3964228027632740190'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/05/book-review-who-moved-my-cheese.html' title='Book Review - Who Moved My Cheese'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-4823266070667393287</id><published>2008-05-02T14:10:00.000-07:00</published><updated>2008-05-02T14:21:51.255-07:00</updated><title type='text'>My Goals</title><content type='html'>I was recently treated for lunch by JP Boodhoo, who despite his statements that nobody should be on a pedestal, sits squarely at the top of mine.  JP's course, Nothing But .NET was one of the two major change points in my life.  I've commented on this below and will comment more in the future I'm sure.&lt;br /&gt;&lt;br /&gt;Regardless, JP challenged the array of developers at lunch yesterday to post our 6 month goals online.  The idea is that having my goals in the open will make them more likely to succeed as all my loyal readers will push me to complete them.&lt;br /&gt;&lt;br /&gt;So here is my list of goals before 2009 rolls around:&lt;br /&gt;&lt;br /&gt;1) For more than one week, be able to want to go to work in the morning.&lt;br /&gt;2) Finally fix my shoulder issue so that I can train over the winter for next climbing season&lt;br /&gt;3) Get to and maintain 225lbs&lt;br /&gt;3a) Work out 3 -4  times a week on a consistent basis&lt;br /&gt;3b) Plan out my meals every weekend for the week&lt;br /&gt;4) Complete NoteTaker Express&lt;br /&gt;5) Write a little Time Tracking Software along the lines of the NoteTaker Express Mantra&lt;br /&gt;6) Compete in an adventure race&lt;br /&gt;7) Bike 100kms after work&lt;br /&gt;8) Compete in the Tour d'Alberta&lt;br /&gt;&lt;br /&gt;I think that's it for now.  It's nice to have them down on paper(ish).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-4823266070667393287?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/4823266070667393287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=4823266070667393287' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/4823266070667393287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/4823266070667393287'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/05/my-goals.html' title='My Goals'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-8194475209377625372</id><published>2008-04-29T21:41:00.000-07:00</published><updated>2008-04-29T22:09:32.311-07:00</updated><title type='text'>NoteTaker Express</title><content type='html'>While at the Nothing But .NET course in Austin recently, I noticed a need for a quick lightweight tool to allow me to quickly create and save notes.  I cast around for a few options but could find little that really gave me what I wanted.&lt;br /&gt;&lt;br /&gt;Here is what I wanted:&lt;br /&gt;&lt;br /&gt;1) The ability to quickly create notes.&lt;br /&gt;2) The ability for the note to save itself without my intervention.&lt;br /&gt;3) The ability for the note to be minimized by pressing esc.&lt;br /&gt;4) The ability for the note to be brought back with a keyboard hook.&lt;br /&gt;&lt;br /&gt;#4 was probably the key for me.  I truly hate starting up something like notepad or gvim in order to save a small one off note.&lt;br /&gt;&lt;br /&gt;So I set about creating one for myself.  The original idea was to be very simple.  ie: only allow a single note that could be added to and cleared.  I architectured the tool towards that but found that it was slightly limiting.  So I added the ability for the user to save each note as a subject.  The idea behind this is that then eventually I will be able to add a similarly lightweight note management system so you can quickly and easily view old notes.  That's getting slightly more complex so for now I'm going to stick with this.&lt;br /&gt;&lt;br /&gt;I'm pretty excited.  I was able to achieve all of my goals and the app runs on a paltry 2,932 K when minimized.  I think there might be a memory leak, but not sure.  Regardless, I think that the app is really cool and I'm pretty excited to try it out.  Send me an e-mail if you are interested in trying it out!&lt;br /&gt;&lt;br /&gt;Instructions:&lt;br /&gt;&lt;br /&gt;Press esc to minimize NoteTaker Express&lt;br /&gt;Press Alt-N to bring NoteTaker Express Back&lt;br /&gt;Right click to bring up the context menu and to see the keyboard shortcuts.&lt;br /&gt;&lt;br /&gt;Make notes with Passion?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-8194475209377625372?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/8194475209377625372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=8194475209377625372' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8194475209377625372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/8194475209377625372'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/04/notetaker-express.html' title='NoteTaker Express'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-4797788618147346066</id><published>2008-04-29T07:56:00.000-07:00</published><updated>2008-04-29T08:12:18.735-07:00</updated><title type='text'>Book Review - Programming as if People Mattered</title><content type='html'>Programming as if People Mattered is a book that's been sitting on my reading list for the last few years.  I think my mom bought it for me shortly after I became a professional programmer (or possibly while I was still in University).  Anyway, it sat on my bookshelf neglected for probably 6 -7 years which obviously added 6 -7 years to it's already dated material.  Part of me hoped that despite the 20 year technology gap that the book would still be interesting and useful to me in my quest to become a not awful UI designer.  And based on that, I was satisfied.  The first half of the book summarized "what is"  or more accurately "what was."  This was mostly useless historical information that had little relevance to modern UI design.  The second half of the book was far more interesting and the author gave ten commandments for UI design.&lt;br /&gt;&lt;br /&gt;1. Never underestimate your users&lt;br /&gt;2. Pretend that small is beautiful by don't believe it&lt;br /&gt;3. Tune defaults to the novice&lt;br /&gt;4. Don't neglect the experts&lt;br /&gt;5. Your program stinks and so do you&lt;br /&gt;6. Listen to your users but ignore what they say&lt;br /&gt;7. Lie to your managers&lt;br /&gt;8. Cut corners proudly&lt;br /&gt;9. Remember your ignorance&lt;br /&gt;10. Dabble in mysticism&lt;br /&gt;11. Break all the rules&lt;br /&gt;&lt;br /&gt;In the next couple of days I'll get to summarizing each of the commandments.  Basically within those 10 (11) commandments, there are many good tips on how to handle UI design and if you look at some of the UI designs that we work with we can see how they either fail or&lt;br /&gt;succeed.&lt;br /&gt;&lt;br /&gt;The evolution of the book was quite interesting as it followed an interesting path.  He started the book writing about using Waterfall method and getting big up front specifications for applications, then as he got deeper into the details of the UI design he really started proposing an agile method.  Instead of being a true agile method, he recommend iterations of prototypes then once the UI was approved then going away and writing the software either from scratch or modifying the prototype.   So not quite agile but almost there.&lt;br /&gt;&lt;br /&gt;Regardless, a very interesting read.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-4797788618147346066?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/4797788618147346066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=4797788618147346066' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/4797788618147346066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/4797788618147346066'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/04/book-review-programming-as-if-people.html' title='Book Review - Programming as if People Mattered'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-46103822332655158</id><published>2008-04-25T09:57:00.000-07:00</published><updated>2008-04-25T10:08:42.166-07:00</updated><title type='text'>The relitive popularity of programming languages</title><content type='html'>I saw this interesting site today.  Thought I should share it. &lt;a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html"&gt;http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The TIOBE Software index has been rating the relative popularity of various programming languages for the past 6 years.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;The TIOBE Programming Community index gives an indication of the popularity of programming  languages. The index is updated once a month. The ratings are based on the number of  skilled engineers world-wide, courses and third party vendors. The popular search engines Google, MSN, Yahoo!, and  YouTube are used to calculate the ratings. Observe that the TIOBE index is not about the &lt;i&gt;best&lt;/i&gt; programming  language or the language in which &lt;i&gt;most lines of code&lt;/i&gt; have been written.&lt;/blockquote&gt;&lt;table class="ttable" bordercolordark="#003366" bordercolorlight="#c0c0c0" id="Table2" align="center" border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th align="center" nowrap="nowrap"&gt;Position&lt;br /&gt;Apr 2008&lt;/th&gt;&lt;th align="center" nowrap="nowrap"&gt;Position&lt;br /&gt;Apr 2007&lt;/th&gt;&lt;th align="center" nowrap="nowrap"&gt;Delta in Position&lt;/th&gt;&lt;th align="center" nowrap="nowrap"&gt;Programming Language&lt;/th&gt;&lt;th align="center" nowrap="nowrap"&gt;Ratings&lt;br /&gt;Apr 2008&lt;/th&gt;&lt;th align="center" nowrap="nowrap"&gt;Delta&lt;br /&gt;Apr 2007&lt;/th&gt;&lt;th align="center" nowrap="nowrap"&gt;Status&lt;/th&gt;&lt;/tr&gt; &lt;tr height="25"&gt;  &lt;td align="center"&gt;1&lt;/td&gt;  &lt;td align="center"&gt;1&lt;/td&gt;  &lt;td align="center"&gt;&lt;img src="http://www.tiobe.com/tiobe_index/images/Same.gif" border="0" /&gt;&lt;/td&gt;  &lt;td&gt;&lt;a href="http://www.tiobe.com/content/paperinfo/tpci/Java.html"&gt;Java&lt;/a&gt;&lt;/td&gt;  &lt;td align="center"&gt;20.529%&lt;/td&gt;  &lt;td align="center"&gt;+2.17%&lt;/td&gt;  &lt;td align="left"&gt;  A&lt;/td&gt; &lt;/tr&gt;  &lt;tr height="25"&gt;  &lt;td align="center"&gt;2&lt;/td&gt;  &lt;td align="center"&gt;2&lt;/td&gt;  &lt;td align="center"&gt;&lt;img src="http://www.tiobe.com/tiobe_index/images/Same.gif" border="0" /&gt;&lt;/td&gt;  &lt;td&gt;&lt;a href="http://www.tiobe.com/content/paperinfo/tpci/C.html"&gt;C&lt;/a&gt;&lt;/td&gt;  &lt;td align="center"&gt;14.684%&lt;/td&gt;  &lt;td align="center"&gt;-0.25%&lt;/td&gt;  &lt;td align="left"&gt;  A&lt;/td&gt; &lt;/tr&gt;  &lt;tr height="25"&gt;  &lt;td align="center"&gt;3&lt;/td&gt;  &lt;td align="center"&gt;5&lt;/td&gt;  &lt;td align="center"&gt; &lt;img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /&gt;&lt;img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /&gt; &lt;/td&gt;  &lt;td&gt;&lt;a href="http://www.tiobe.com/content/paperinfo/tpci/%28Visual%29_Basic.html"&gt;(Visual) Basic&lt;/a&gt;&lt;/td&gt;  &lt;td align="center"&gt;11.699%&lt;/td&gt;  &lt;td align="center"&gt;+3.42%&lt;/td&gt;  &lt;td align="left"&gt;  A&lt;/td&gt; &lt;/tr&gt;  &lt;tr height="25"&gt;  &lt;td align="center"&gt;4&lt;/td&gt;  &lt;td align="center"&gt;4&lt;/td&gt;  &lt;td align="center"&gt;&lt;img src="http://www.tiobe.com/tiobe_index/images/Same.gif" border="0" /&gt;&lt;/td&gt;  &lt;td&gt;&lt;a href="http://www.tiobe.com/content/paperinfo/tpci/PHP.html"&gt;PHP&lt;/a&gt;&lt;/td&gt;  &lt;td align="center"&gt;10.328%&lt;/td&gt;  &lt;td align="center"&gt;+1.69%&lt;/td&gt;  &lt;td align="left"&gt;  A&lt;/td&gt; &lt;/tr&gt;  &lt;tr height="25"&gt;  &lt;td align="center"&gt;5&lt;/td&gt;  &lt;td align="center"&gt;3&lt;/td&gt;  &lt;td align="center"&gt; &lt;img src="http://www.tiobe.com/tiobe_index/images/Down.gif" border="0" /&gt;&lt;img src="http://www.tiobe.com/tiobe_index/images/Down.gif" border="0" /&gt; &lt;/td&gt;  &lt;td&gt;&lt;a href="http://www.tiobe.com/content/paperinfo/tpci/C__.html"&gt;C++&lt;/a&gt;&lt;/td&gt;  &lt;td align="center"&gt;9.945%&lt;/td&gt;  &lt;td align="center"&gt;-0.77%&lt;/td&gt;  &lt;td align="left"&gt;  A&lt;/td&gt; &lt;/tr&gt;  &lt;tr height="25"&gt;  &lt;td align="center"&gt;6&lt;/td&gt;  &lt;td align="center"&gt;6&lt;/td&gt;  &lt;td align="center"&gt;&lt;img src="http://www.tiobe.com/tiobe_index/images/Same.gif" border="0" /&gt;&lt;/td&gt;  &lt;td&gt;&lt;a href="http://www.tiobe.com/content/paperinfo/tpci/Perl.html"&gt;Perl&lt;/a&gt;&lt;/td&gt;  &lt;td align="center"&gt;5.934%&lt;/td&gt;  &lt;td align="center"&gt;-0.10%&lt;/td&gt;  &lt;td align="left"&gt;  A&lt;/td&gt; &lt;/tr&gt;  &lt;tr height="25"&gt;  &lt;td align="center"&gt;7&lt;/td&gt;  &lt;td align="center"&gt;7&lt;/td&gt;  &lt;td align="center"&gt;&lt;img src="http://www.tiobe.com/tiobe_index/images/Same.gif" border="0" /&gt;&lt;/td&gt;  &lt;td&gt;&lt;a href="http://www.tiobe.com/content/paperinfo/tpci/Python.html"&gt;Python&lt;/a&gt;&lt;/td&gt;  &lt;td align="center"&gt;4.534%&lt;/td&gt;  &lt;td align="center"&gt;+0.72%&lt;/td&gt;  &lt;td align="left"&gt;  A&lt;/td&gt; &lt;/tr&gt;  &lt;tr height="25"&gt;  &lt;td align="center"&gt;8&lt;/td&gt;  &lt;td align="center"&gt;8&lt;/td&gt;  &lt;td align="center"&gt;&lt;img src="http://www.tiobe.com/tiobe_index/images/Same.gif" border="0" /&gt;&lt;/td&gt;  &lt;td&gt;&lt;a href="http://www.tiobe.com/content/paperinfo/tpci/C_.html"&gt;C#&lt;/a&gt;&lt;/td&gt;  &lt;td align="center"&gt;3.834%&lt;/td&gt;  &lt;td align="center"&gt;+0.28%&lt;/td&gt;  &lt;td align="left"&gt;  A&lt;/td&gt; &lt;/tr&gt;  &lt;tr height="25"&gt;  &lt;td align="center"&gt;9&lt;/td&gt;  &lt;td align="center"&gt;10&lt;/td&gt;  &lt;td align="center"&gt; &lt;img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /&gt; &lt;/td&gt;  &lt;td&gt;&lt;a href="http://www.tiobe.com/content/paperinfo/tpci/Ruby.html"&gt;Ruby&lt;/a&gt;&lt;/td&gt;  &lt;td align="center"&gt;2.855%&lt;/td&gt;  &lt;td align="center"&gt;+0.06%&lt;/td&gt;  &lt;td align="left"&gt;  A&lt;/td&gt; &lt;/tr&gt;  &lt;tr height="25"&gt;  &lt;td align="center"&gt;10&lt;/td&gt;  &lt;td align="center"&gt;11&lt;/td&gt;  &lt;td align="center"&gt; &lt;img src="http://www.tiobe.com/tiobe_index/images/Up.gif" border="0" /&gt; &lt;/td&gt;  &lt;td&gt;&lt;a href="http://www.tiobe.com/content/paperinfo/tpci/Delphi.html"&gt;Delphi&lt;/a&gt;&lt;/td&gt;  &lt;td align="center"&gt;2.665%&lt;/td&gt;  &lt;td align="center"&gt;+0.33%&lt;/td&gt;  &lt;td align="left"&gt;  A&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;So that's the top ten languages. &lt;br /&gt;&lt;br /&gt;It kinda hurts me to see Visual Basic so high on the list, but I suppose it's been around a long time.  It also includes most of the other Visual Basics including QBasic, VBA etc.  Regardless, this page has been an interesting view of the relative popularity of the various languages.  The bottom line though is that every language on the list is good for it's own little section of the programming world.  The pragmatic programmer should understand that and know which language will best support the task at hand.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-46103822332655158?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/46103822332655158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=46103822332655158' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/46103822332655158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/46103822332655158'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/04/relitive-popularity-of-programming.html' title='The relitive popularity of programming languages'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-3455525577444460903</id><published>2008-04-21T16:36:00.000-07:00</published><updated>2008-04-21T16:45:42.750-07:00</updated><title type='text'>Jobs and the eternal search for happiness</title><content type='html'>I've been talking to alot of people recently, about happiness specifically relating to job satisfaction.  Thus far the common concensis that I have heard is that it is impossible to be happy at your job because there is always going to be someone or something that makes you unhappy.&lt;br /&gt;&lt;br /&gt;I think that I can understand this general feeling because in reality there is no perfect job where you can be happy all the time.  However, my response to people is, are you willing to stop your search for perfection simply because it is unattainable?  There is really no such thing as perfection and I think that everybody can understand this concept.  For me though, the search for perfection will continue on regardless of whether or not it is attainable.  This means personal perfection or job perfection.  I believe that there exists the perfect job for me.  And I will continue to do the things that I need to do in order to find that perfect job.  And in the end, if there is no perfect job, then I will make that perfect job.  The bottom line is, you simply can't accept mediocrity because everybody thinks that perfection doesn't exist.&lt;br /&gt;&lt;br /&gt;There's an old saying: "Aim for the stars and you'll at least hit the moon"   Some might think that hitting the moon would be considered a failure, but the truth is that the moon is far closer to the stars that most people will ever get.  Don't accept mediocraty.  Strive for perfection, you might find yourself closer than you would have ever expected.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-3455525577444460903?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/3455525577444460903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=3455525577444460903' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/3455525577444460903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/3455525577444460903'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/04/jobs-and-eternal-search-for-happiness.html' title='Jobs and the eternal search for happiness'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-3721169787492493710</id><published>2008-04-15T11:19:00.000-07:00</published><updated>2008-04-15T11:32:28.449-07:00</updated><title type='text'>Keyboard Junkies</title><content type='html'>It wasn't until relatively recently that I have come to embrace the keyboard only "revolution" that some developers are embracing.  I put the "revolution" in quotes because most of us actually know that the revolution is no more a revolution than saying that walking or biking is a revolution.  In reality typing has been long known as quicker than using the mouse and only those who are unwilling to go through the pain that is required to ditch the mouse don't agree.&lt;br /&gt;&lt;br /&gt;In my quest to become a true keyboard junky I have started to utilize the following tools:&lt;br /&gt;&lt;br /&gt;1) ViEmu (www.viemu.com) - A visual studio plugin that utilizes the vi interface.  With enough practice it can increase my code speed exponentially.&lt;br /&gt;2) Resharper (www.jetbrains.com) - Another visual studio plugin with enough keyboard shortcuts to allow the hands to never leave the keyboard.&lt;br /&gt;3) launchy - Windows smart command line tool, which allows you to launch all your applications with nothing more than a few keystrokes.&lt;br /&gt;4) Remap Right Ctrl to the Caps Key - This is the trick that really makes the above work like magic.  Many of the key combinations in ViEmu and Resharper require the ctrl so if we lower the flight path for the ctrl key then everything else becomes that much faster. (http://www.usnetizen.com/fix_capslock.php)&lt;br /&gt;5) There are many other tools that can be used and I am slowly working my way through them. Vimperator failed integration test one, it's going to start integration test two tomorrow.  I'm convinced I'll be able to make it work.&lt;br /&gt;&lt;br /&gt;Everystep along the way has been painful, however, by keeping at it I believe that I am giving myself a better chance to be a more productive programmer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-3721169787492493710?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/3721169787492493710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=3721169787492493710' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/3721169787492493710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/3721169787492493710'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/04/keyboard-junkies.html' title='Keyboard Junkies'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5808375369110654128.post-2714880725353138237</id><published>2008-04-13T22:28:00.000-07:00</published><updated>2008-04-13T22:42:31.280-07:00</updated><title type='text'>Nothing But .NET</title><content type='html'>So it's interesting, the way life sorta ebbs and flows in an almost impossible to follow manner.  My life so far has been pretty hectic and really without a whole lot of purpose.  I've pretty much floated from on opportunity to another without a lot of thought or goal in it.  Everything, however, has seemed to work out all right, but really at this point in my life, I have not actually done anything to really advance myself.&lt;br /&gt;&lt;br /&gt;That all changed about a month ago when I decided to ask my current company to allow me to attend the Nothing but .NET course given by JP Boodhoo a Microsoft MVP and extremely driven and dedicated developer.  I had the pleasure of seeing and meeting Mr. Boodhoo at a local .NET user group and saw a mindblowing presentation that opened my eyes to what a true master of the art can accomplish.  As soon as I saw him,  I looked him up and decided to take his course.  There was no question from me.  I had to sell my soul for it, but fortunately the devil I sold it to only owns it for five months.  This leads me to one of the most interesting things that I learnt over the past week at the nothing but .Net course in Austin this week.  I am the master of my own destiny, I have to make myself a better programmer.  I have the power to effect change in my organization, and if I can't because there are too many people in my organization that are not interested in bettering myself or the organization, then it is time to move on.&lt;br /&gt;&lt;br /&gt;My decision therefore, is that I have to first become the best god damn developer I can be.  This means studying and practicing programming.  Many programmers feel that we can simply work the 9-5 and then call it a day, but those people are going to be doomed to wallow in their shitty jobs for ever.  Every master of every task, be it a sport, job, game, etc spend time and effort outside of there work bettering themselves.  I intend to become a master at programming.  Now, that said, there must be a balance in life, so in order to best allow myself to become a master programmer and maintain a healthy home life, I need to eliminate the waste in my life.  This doesn't mean eliminating the game playing or the climbing, it simply means that my life needs to be optimized.  I'm not sure right now exactly how that's going to work but I know that it will.&lt;br /&gt;&lt;br /&gt;I think that's going to be enough for tonight.  I don't intend to publish this blog.  It's just for me.  If you read it and you gain something useful from it let me know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5808375369110654128-2714880725353138237?l=davidmorgantini.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://davidmorgantini.blogspot.com/feeds/2714880725353138237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5808375369110654128&amp;postID=2714880725353138237' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/2714880725353138237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5808375369110654128/posts/default/2714880725353138237'/><link rel='alternate' type='text/html' href='http://davidmorgantini.blogspot.com/2008/04/nothing-but-net.html' title='Nothing But .NET'/><author><name>David</name><uri>http://www.blogger.com/profile/06027525499493990953</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
