<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-6538953</atom:id><lastBuildDate>Sat, 28 Jan 2012 00:28:08 +0000</lastBuildDate><category>Vs2008</category><category>tools</category><category>debugging</category><category>unit tests</category><category>htmlcontrol</category><category>tinymce</category><category>how to</category><category>business intelligence</category><category>crm</category><category>browsers</category><category>c#</category><category>readibility</category><category>janus</category><category>Console</category><category>vs2010</category><category>dynamic data</category><category>tdd</category><category>performance</category><category>access</category><category>SSIS</category><category>.NET4</category><category>usability</category><category>database</category><category>wcf</category><category>LINQ</category><category>xml</category><category>winforms</category><category>devexpress</category><category>personal</category><category>silverlight</category><category>controls</category><category>TFS</category><category>deployment</category><category>infragistics</category><category>links</category><category>sql server</category><category>oracle</category><category>tip</category><category>mvc</category><category>jquery</category><category>Enterprise Library</category><category>databinding</category><category>coding</category><category>SSRS</category><category>blend</category><category>asp.net</category><category>testing</category><category>entity framework</category><category>Vs2005</category><category>conferences</category><category>.NET</category><title>Peter Gfader 's .NET Blog</title><description>Programming and Coding Stuff | Tips and tricks on .NET , C#, Usability and Best Practices</description><link>http://blog.gfader.com/</link><managingEditor>noreply@blogger.com (Peter Gfader)</managingEditor><generator>Blogger</generator><openSearch:totalResults>288</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/PeterGfader" /><feedburner:info uri="petergfader" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>PeterGfader</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-4406739875965077876</guid><pubDate>Sun, 22 Jan 2012 10:42:00 +0000</pubDate><atom:updated>2012-01-22T11:50:57.511+01:00</atom:updated><title>Tumblr! Not an excuse for not “blogging”</title><description>&lt;p&gt;&lt;strong&gt;&lt;a href="http://gfader.tumblr.com/" target="_blank"&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="Peter thinks" border="0" alt="Peter thinks" src="http://lh4.ggpht.com/-AUWlsW6E3fs/TxvoHbiDRSI/AAAAAAAAHjE/wLeyRk97r7U/peter-gfader-thinks%25255B6%25255D.png?imgmax=800" width="304" height="290" /&gt;&lt;/a&gt;      &lt;br /&gt;&lt;/strong&gt;&lt;strong&gt;Figure: &lt;/strong&gt;… &lt;em&gt;Comic effect created with &lt;/em&gt;&lt;a href="http://www.photoshoproadmap.com/Photoshop-blog/2007/09/13/give-your-photos-a-retro-comic-book-effect/" target="_blank"&gt;&lt;em&gt;this Photoshop tutorial&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Is my &lt;a href="http://gfader.tumblr.com/" target="_blank"&gt;new tumblr stream&lt;/a&gt; just an excuse for not blogging??    &lt;br /&gt;Instead of saying: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“I am way too &lt;strike&gt;lazy&lt;/strike&gt;&amp;#160;&lt;strong&gt;busy&lt;/strong&gt; to write a proper blog. I just post random stuff”&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;No!   &lt;br /&gt;It is my effort of publishing more. As I said in my &lt;a href="http://blog.gfader.com/2012/01/2011-retrospective-year-in-review.html" target="_blank"&gt;2012 retrospective&lt;/a&gt; I want to publish more, because I like the feedback and discussions that come out of it.&lt;/p&gt;  &lt;p&gt;So... there you have it: &lt;a href="http://gfader.tumblr.com/" target="_blank"&gt;Peter’s little link list + comments&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;PS     &lt;br /&gt;&lt;/strong&gt;Via &lt;a href="http://feedburner.google.com/fb/a/mailverify?uri=PeterGfadersLittleLinkList" target="_blank"&gt;feedburner&lt;/a&gt; I get all these “tumbles” in my inbox (special folder), so I can easily search for these notes later on…&lt;/p&gt;  &lt;p&gt;PPS   &lt;br /&gt;Thanks to &lt;a href="http://blog.js-development.com/2011/10/my-tumblr-stream-developers-work-log.html" target="_blank"&gt;Juri for this&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;What do you think?&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-4406739875965077876?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/01JA1yne00w" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/01JA1yne00w/tumblr-not-excuse-for-not-blogging.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-AUWlsW6E3fs/TxvoHbiDRSI/AAAAAAAAHjE/wLeyRk97r7U/s72-c/peter-gfader-thinks%25255B6%25255D.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.gfader.com/2012/01/tumblr-not-excuse-for-not-blogging.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-1968501585955077645</guid><pubDate>Sat, 07 Jan 2012 15:42:00 +0000</pubDate><atom:updated>2012-01-08T10:55:46.407+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">personal</category><category domain="http://www.blogger.com/atom/ns#">coding</category><title>2011 retrospective – a year in review</title><description>&lt;p&gt;This is the 3rd time at the beginning of the year in a row, where I wanted to recap last year in a blog post. This time I am actually doing it, or let me rephrase it. This time around I actually publish my recap on my blog. &amp;quot;Publish more&amp;quot; is one of my goals for 2012 which is topic for another blog post.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;! This blog post is all about me, addressed to my future self. Feel free to skip it ;-)      &lt;br /&gt;&lt;/em&gt;    &lt;br /&gt;&lt;a href="http://blog.gfader.com/2012/01/2011-retrospective-year-in-review.html"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title=" Goal for 2012: Avoid getting hit with keyboard from girlfriend" border="0" alt=" Goal for 2012: Avoid getting hit with keyboard from girlfriend" src="http://lh6.ggpht.com/-0qgrw2k-7YE/TwhnrNMxBFI/AAAAAAAAHi0/c1mNr92QlGo/image7%25255B3%25255D.png?imgmax=800" width="700" height="184" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Goal for 2012: Avoid getting hit with keyboard from girlfriend&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;TL;DR;&lt;/strong&gt; 2011 was a great year. Not only professionally.     &lt;br /&gt;4 long holidays made sure that I had an awesome year! (Thailand, New Zealand, Europe over Xmas, Italy in Autumn)&lt;/p&gt;  &lt;h2&gt;&lt;strong&gt;&amp;#160;&lt;/strong&gt;&lt;/h2&gt;  &lt;h2&gt;&lt;strong&gt;Teaching &lt;/strong&gt;&lt;/h2&gt;  &lt;p&gt;The beginning of this year I taught the class “&lt;a title="UTS" href="http://www.it.uts.edu.au/courses/short/programming/dotnet.html" target="_blank"&gt;Developing Windows and web applications using Visual Studio.NET&lt;/a&gt;” at the University of Technology in Sydney (UTS), which is always great. I really enjoy teaching, having discussions, getting &lt;a href="http://blog.gfader.com/2010/10/ssis-and-ssrs-qa-from-bi-class.html" target="_blank"&gt;interesting questions&lt;/a&gt;, &lt;a href="http://blog.gfader.com/2010/10/ssrs-qa-from-bi-class.html" target="_blank"&gt;digging deeper with students&lt;/a&gt; on certain topics. It requires a lot of work after hours, because I have to prepare the topics, demos, homework, but I gain a lot out of it. Most importantly: I enjoy it. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“Find a Job You Love and Never Work Again”&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h2 align="left"&gt;&lt;strong&gt;&amp;#160;&lt;/strong&gt;&lt;/h2&gt;  &lt;h2 align="left"&gt;&lt;strong&gt;Speaking&lt;/strong&gt;&lt;/h2&gt;  &lt;p align="left"&gt;I gave 2 public talks this year. One at &lt;a href="http://blog.gfader.com/2011/06/continuous-testing-with-visual-studio.html" target="_blank"&gt;Sydney Alt.NET about Continuously Testing&lt;/a&gt; and one at about &lt;a href="http://blog.gfader.com/2011/07/continuous-delivery-with-tfs-msbuild.html" target="_blank"&gt;Continuous Delivery @ Sydney .NET UG&lt;/a&gt;. I enjoyed those a lot, especially the discussions afterwards.     &lt;br /&gt;Preparing those talks is similar to teach a 3hour night session at UTS. I have to really dig into the topic, do a lot investigations (sometimes months before by taking notes) and then finally do an internal talk where I get heaps of valuable feedback from my &lt;a href="http://www.ssw.com.au/ssw/" target="_blank"&gt;peers at SSW&lt;/a&gt;.     &lt;br /&gt;I improved my speaking quite a bit. I remember my first talk at UTS about SQL Server, where I almost forgot my own name, because I was so nervous.     &lt;br /&gt;I saw some &lt;a href="http://tv.ssw.com/245/peter-gfader-deployment-continuous-delivery-with-tfs" target="_blank"&gt;recent recordings&lt;/a&gt; of myself and found heaps of things to improve my speaking. &lt;em&gt;No, not just the English pronunciation &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh3.ggpht.com/-xr2aqsm16QM/TwhnsFl6cRI/AAAAAAAAHhs/NmZaNM-0tIE/wlEmoticon-smile2.png?imgmax=800" /&gt;&lt;/em&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="left"&gt;&lt;em&gt;Its Both What You Say and the Way You Say It        &lt;br /&gt;&lt;/em&gt;Tip 10, Chapter 1, &lt;a href="http://pragprog.com/the-pragmatic-programmer" target="_blank"&gt;Pragmatic Programmer&lt;/a&gt; Great book BTW!&lt;/p&gt;    &lt;p align="left"&gt;&amp;#160;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h2 align="left"&gt;&lt;strong&gt;&amp;#160;&lt;/strong&gt;&lt;/h2&gt;  &lt;h2 align="left"&gt;&lt;strong&gt;User groups &lt;/strong&gt;&lt;/h2&gt;  &lt;p align="left"&gt;Sydney is great for user groups. There is almost no night during the week when there is not an interesting user group geek night on. Sad, that I left Sydney this June, in order to go to Europe where girlfriend, family and friends are. But there are great user groups over here as well, and if not, we have to start some!    &lt;br /&gt;During those user groups there was always something new to learn, and I got to know great people of the Australian Developer community (which is an awesome community BTW). Did I mention Free Pizza?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Invest Regularly in Your Knowledge Portfolio        &lt;br /&gt;&lt;/em&gt;Tip 8, Chapter 1, &lt;a href="http://pragprog.com/the-pragmatic-programmer" target="_blank"&gt;Pragmatic Programmer&lt;/a&gt; &amp;lt;-- Did I mention that this is a great book!&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h2&gt;&lt;strong&gt;&amp;#160;&lt;/strong&gt;&lt;/h2&gt;  &lt;h2&gt;&lt;strong&gt;Blogging&lt;/strong&gt;&lt;/h2&gt;  &lt;p&gt;I just had a look at my &lt;a href="http://blog.gfader.com/search?updated-min=2011-01-01T00:00:00%2B01:00&amp;amp;updated-max=2012-01-01T00:00:00%2B01:00&amp;amp;max-results=29" target="_blank"&gt;2011 Archive&lt;/a&gt; and found 29 blog posts (Actually 30 if you include this one &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh6.ggpht.com/-QcQ9kmywJbE/TwhnsqwTF1I/AAAAAAAAHh0/HEnj60yxfSA/wlEmoticon-winkingsmile2.png?imgmax=800" /&gt; ). That is not a lot, but I am actually very happy about my blogging year, especially because I think the quality has improved a lot. I am all about Quality over Quantity (see upcoming Coding section).     &lt;br /&gt;&lt;a href="http://lh6.ggpht.com/-3qitvvv_DUE/TwhntBDdd3I/AAAAAAAAHh8/QlZYz-ZY0d4/s1600-h/image18.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-uHW3-t1fOkI/TwhnuPZXssI/AAAAAAAAHiE/xQXLl7teiyI/image_thumb11.png?imgmax=800" width="640" height="335" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Number of blog posts per year oscillating around 30, which is 2.5 blog posts a month. &lt;/p&gt;  &lt;p&gt;I enjoy blogging a lot, especially when I get feedback and raise discussions, then I &lt;a href="http://johnliu.net/blog/2011/12/15/the-bloggers-eternal-struggle-for-blog-reader-comments.html" target="_blank"&gt;get a warm fuzzy feeling as John Liu&lt;/a&gt; &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh6.ggpht.com/-QcQ9kmywJbE/TwhnsqwTF1I/AAAAAAAAHh0/HEnj60yxfSA/wlEmoticon-winkingsmile2.png?imgmax=800" /&gt;. I blog to gather my thoughts together, publish my notes, have an online presence, save cool stuff for my future self and learn something new from blog commenters.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;My top 3 blog posts&lt;/h2&gt;  &lt;p&gt;The 3 part series about ASP.NET was a big success regarding blog post views and feedback. Someone even recommended to write a book about it.    &lt;br /&gt;&lt;em&gt;Why the need for a book when you can get it on the web for free? &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh6.ggpht.com/-QcQ9kmywJbE/TwhnsqwTF1I/AAAAAAAAHh0/HEnj60yxfSA/wlEmoticon-winkingsmile2.png?imgmax=800" /&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;#1    &lt;br /&gt;&lt;a href="http://blog.gfader.com/2011/07/website-check-list-part-1-aspnet-4.html"&gt;Part 1 ASP.NET - 4 essential steps before going live&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://blog.gfader.com/2011/07/website-check-list-part-2-aspnet-8.html"&gt;Part 2 ASP.NET - 8 performance tips before going live&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://blog.gfader.com/2011/08/part-3-aspnet-8-user-experience-tips.html"&gt;Part 3 ASP.NET - 9 User Experience tips before going live&lt;/a&gt;     &lt;br /&gt;I got heaps of views on the 1st blog post on that series, which showed up as a big spike in Google Analytics (3000 page views in 1 day).&amp;#160; &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;#2    &lt;br /&gt;&lt;a href="http://blog.gfader.com/2011/03/code-contracts-is-it-only-about.html" target="_blank"&gt;Code contracts - Is it only about argument validation?&lt;/a&gt;     &lt;br /&gt;My personal best blog post from 2011: I like Code Contracts.&lt;/p&gt;  &lt;p&gt;#3    &lt;br /&gt;&lt;a href="http://blog.gfader.com/2011/05/microsoft-aspnet-too-many-options.html" target="_blank"&gt;Microsoft ASP.NET - Too many options&lt;/a&gt;     &lt;br /&gt;I saw a lot more feed subscribers after publishing this post.     &lt;br /&gt;Maybe cause people like bloggers ranting about Microsoft &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh3.ggpht.com/-xr2aqsm16QM/TwhnsFl6cRI/AAAAAAAAHhs/NmZaNM-0tIE/wlEmoticon-smile2.png?imgmax=800" /&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;&lt;strong&gt;Coding&lt;/strong&gt;&lt;/h2&gt;  &lt;p&gt;2011 was a successful year for me and my teams. We (&lt;a href="http://www.ssw.com.au/ssw/" target="_blank"&gt;me and my workmates at SSW&lt;/a&gt;) rolled out 3 major software products in production.     &lt;br /&gt;Rolling out software to production is quite hard and one of my favorite discussion topics by a beer.&amp;#160; &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“Successful Software is not about time, scope and budget. If your software is not in production you failed”        &lt;br /&gt;Peter Gfader&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;a href="http://blog.gfader.com/2011/07/continuous-delivery-with-tfs-msbuild.html" target="_blank"&gt;I found a couple of things useful&lt;/a&gt; in order to develop and ship successfully software: There is automation which is important (see below), testing and everyone (dev+business) working together. &lt;/p&gt;  &lt;h2&gt;&amp;#160;&lt;/h2&gt;  &lt;h2&gt;Aspects of software development&lt;/h2&gt;  &lt;p&gt;&lt;strong&gt;#1&lt;/strong&gt; &lt;strong&gt;Practice Practice Practice      &lt;br /&gt;&lt;/strong&gt;&lt;em&gt;Instead of writing this blog post, I should really be practicing right now!      &lt;br /&gt;&lt;/em&gt;I should write some code. I should write some tests. I should &lt;a href="http://codekata.pragprog.com/" target="_blank"&gt;do a Kata&lt;/a&gt;. I should try a new tool. I should work on some cool private project.     &lt;br /&gt;I spent quite a bit of time doing Katas and learnt a lot by doing them. Basically I try the same problems in different ways by testing different tools or a different solution approach: recursive, OOP or more functional etc.     &lt;br /&gt;Katas are fun, but I realized working on a real problem is more engaging to me.     &lt;br /&gt;&lt;em&gt;There is a huge room for improvement here and I have already a couple of goals on my “Goals 2012 list” &lt;/em&gt;&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh6.ggpht.com/-QcQ9kmywJbE/TwhnsqwTF1I/AAAAAAAAHh0/HEnj60yxfSA/wlEmoticon-winkingsmile2.png?imgmax=800" /&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“Demand technical excellence”        &lt;br /&gt;&lt;/em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/hh350860.aspx" target="_blank"&gt;#1 key success factor in Agile software development – Recap on MSDN&lt;/a&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;#2&lt;/strong&gt; &lt;strong&gt;Teams&lt;/strong&gt;&amp;#160; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Is a team better than a single (rockstar) developer? &lt;/li&gt;    &lt;li&gt;How can we be productive as a team? &lt;/li&gt;    &lt;li&gt;How can we get a team to deliver more? &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Interesting questions and the answers are hard. Every team is different because we have to deal with humans and communication problems. Human behavior is a very interesting topic that I want to invest more time in 2012. I started already to look into &lt;a href="http://en.wikipedia.org/wiki/Neuro-linguistic_programming" target="_blank"&gt;NLP&lt;/a&gt;, Psychology and similar topics. I might start a new study at a university… We’ll see…&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;#3&lt;/strong&gt; &lt;strong&gt;Automation&lt;/strong&gt;     &lt;br /&gt;We have this huge resources of CPU and memory under our desks and don’t utilize them to their full potential. We should try to automate much more:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Automated deployments &lt;/li&gt;    &lt;li&gt;Automated tests &lt;/li&gt;    &lt;li&gt;Automated performance stresstests over night (future blog post) &lt;/li&gt;    &lt;li&gt;Automated clicks and mouse movements to test the UI (discussion about +/- in another blog post) &lt;/li&gt;    &lt;li&gt;… &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;#4&lt;/strong&gt; &lt;strong&gt;Code Quality      &lt;br /&gt;&lt;/strong&gt;I realized that Code quality is one of the most important things in software development and I am glad there is this community around &lt;a href="http://manifesto.softwarecraftsmanship.org/" target="_blank"&gt;Software Craftsmanship that cares about Quality&lt;/a&gt;. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“Only Quality lets us go faster”        &lt;br /&gt;Uncle Bob Martin&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;h2&gt;&amp;#160;&lt;/h2&gt;  &lt;h2&gt;What else?&lt;/h2&gt;  &lt;p&gt;I attended Juval Lowy’s “Architects Master class” which I had interesting discussions with Juval to the point where he wouldn’t let me ask questions or speak and interrupt his presentation &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-disappointedsmile" alt="Disappointed smile" src="http://lh6.ggpht.com/-iYsVoi3c5So/TwhnuscnPUI/AAAAAAAAHiM/dnUfYUGgDIQ/wlEmoticon-disappointedsmile2.png?imgmax=800" /&gt;.     &lt;br /&gt;&lt;em&gt;&lt;strong&gt;To myself&lt;/strong&gt;: Recap those 10 pages of notes and blog about it. &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-_gCw09Sh8js/TwhnyNb4Q1I/AAAAAAAAHiY/nLmuwGmJKJA/s1600-h/image3.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-N79yFwz17bE/Twhn1O_HQYI/AAAAAAAAHig/vSai_mf_n4I/image_thumb1.png?imgmax=800" width="604" height="417" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Me and Juval Lowy, friends again after the class     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;I attended other cool developer events like: &lt;a href="http://www.dddsydney.com/" target="_blank"&gt;DDD Sydney&lt;/a&gt; or the &lt;a href="http://www.leanagilescrum.ch/" target="_blank"&gt;Lean Agile Scrum Conference in Zürich&lt;/a&gt;, where I got to know some of my future workmates from &lt;a href="http://www.zuehlke.com/" target="_blank"&gt;Zühlke Engineering AG&lt;/a&gt;.     &lt;br /&gt;I joined Zühlke December 2011 after 3 awesome years with SSW in Sydney. I have to thank Adam Cogan for a lot of things, especially the great time with great people in Sydney. (&lt;em&gt;TODO: Blog about it&lt;/em&gt;)&lt;/p&gt;  &lt;h2&gt;&amp;#160;&lt;/h2&gt;  &lt;h2&gt;Future&lt;/h2&gt;  &lt;p&gt;I have already a long list of goals for 2012 that I will publish in the next weeks. One of those goals is to publish more. I gather lots of notes from all different kind of sources and sharing and collaborating on those is important to me.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h2&gt;&lt;strong&gt;My mission statement&lt;/strong&gt;&lt;/h2&gt;  &lt;p&gt;I love to build things.    &lt;br /&gt;I love building software.     &lt;br /&gt;I love to surprise people.     &lt;br /&gt;I love to delight people with great software.     &lt;br /&gt;&lt;em&gt;&amp;#160;&lt;/em&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;There is so much crap software out there. My goal is to improve that by helping others and by doing it myself.        &lt;br /&gt;Peter Gfader         &lt;br /&gt;&amp;#160;&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Love, peace and harmony….. and coffee+&lt;a href="http://en.wikipedia.org/wiki/Panettone" target="_blank"&gt;panettone&lt;/a&gt; to everyone!     &lt;br /&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Panettone is yummy, not just in Winter time" border="0" alt="Panettone is yummy, not just in Winter time" src="http://lh3.ggpht.com/-4G_gCCTghqs/Twhn3yNz-5I/AAAAAAAAHio/2iZzsPDhhFE/image6.png?imgmax=800" width="338" height="285" /&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-1968501585955077645?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/3nEECpMXCu0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/3nEECpMXCu0/2011-retrospective-year-in-review.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-0qgrw2k-7YE/TwhnrNMxBFI/AAAAAAAAHi0/c1mNr92QlGo/s72-c/image7%25255B3%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.gfader.com/2012/01/2011-retrospective-year-in-review.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-3657782480845000073</guid><pubDate>Wed, 04 Jan 2012 11:03:00 +0000</pubDate><atom:updated>2012-01-04T19:20:15.438+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">readibility</category><category domain="http://www.blogger.com/atom/ns#">coding</category><title>Generated documentation is worse than useless (0 value) and causes pain in the future</title><description>&lt;p&gt;&lt;em&gt;I just came across a &lt;/em&gt;&lt;a href="http://geek.ianbattersby.com/2011/04/07/easing-the-stylecop-pain-with-atomineer" target="_blank"&gt;&lt;em&gt;blog post from Ian about GhostDoc and Atominerr&lt;/em&gt;&lt;/a&gt;&lt;em&gt; and had to share my thoughts here about those tools. I tried to leave a comment on his blog, but I couldn’t answer the SpamQuiz. LOL #StupidHuman&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Useless but fun" border="0" alt="Useless but fun.   Generated documentation is useless but not fun!" src="http://lh5.ggpht.com/-bDK-xf2a8qc/TwQx9K_4m9I/AAAAAAAAHhg/BVMHNFAKSss/image%25255B5%25255D.png?imgmax=800" width="174" height="200" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Useless but fun!&amp;#160; &lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;Generated documentation is useless and not fun&lt;/p&gt;  &lt;p&gt;I was excited the 1st time I came across GhostDoc as well. I even documented that as a must-have-addin for Visual Studio here &lt;a href="http://blog.gfader.com/2008/06/neuinstallation-visual-studio-link-tip.html"&gt;http://blog.gfader.com/2008/06/neuinstallation-visual-studio-link-tip.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;But these days I say it has 0 value.    &lt;br /&gt;Actually worse, it creates pain in the future.&lt;/p&gt;  &lt;p&gt;Problems with those tools:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Once you refactor your method, you have to change the documentation as well –&amp;gt; Violation of DRY &lt;/li&gt;    &lt;li&gt;When you forget to change your documentation you have inconsistencies in your code base –&amp;gt; Hell!!! &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Just to be clear: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I am not against documentation, but documentation that is generated is useless and &lt;/li&gt;    &lt;li&gt;60% of the time, it causes pain every time. LOL &lt;a href="http://www.youtube.com/watch?v=zLq2-uZd5LY"&gt;http://www.youtube.com/watch?v=zLq2-uZd5LY&lt;/a&gt;&amp;#160; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you document something, document why and not how    &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-3657782480845000073?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/T-tqH-aS290" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/T-tqH-aS290/generated-documentation-is-worse-than.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-bDK-xf2a8qc/TwQx9K_4m9I/AAAAAAAAHhg/BVMHNFAKSss/s72-c/image%25255B5%25255D.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.gfader.com/2012/01/generated-documentation-is-worse-than.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-3276157977484577347</guid><pubDate>Sun, 11 Dec 2011 13:51:00 +0000</pubDate><atom:updated>2011-12-11T16:26:52.164+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">tip</category><category domain="http://www.blogger.com/atom/ns#">TFS</category><category domain="http://www.blogger.com/atom/ns#">how to</category><category domain="http://www.blogger.com/atom/ns#">vs2010</category><title>TFS source control - Watch your application grow like a garden</title><description>&lt;p&gt;&lt;a href="http://blog.gfader.com/2011/12/tfs-see-your-application-grow-like.html"&gt;&lt;img title="Start little and grow a garden" alt="Start little and grow a garden" src="http://organicandgreenliving.files.wordpress.com/2011/01/25747_plant-grow2.jpg" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Not a garden yet, but everything starts small     &lt;br /&gt;    &lt;br /&gt;On every project that I am part of, I setup an email alert that sends me an email for each check-in that happens.     &lt;br /&gt;This helps me to follow what's going on on the codebase and to watch the application grow. I say &amp;quot;grow&amp;quot; because we construct software by growing it like a garden, and &lt;strong&gt;*not* &lt;/strong&gt;constructing it like a building.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;&amp;quot;Architecture is a bad metaphor. We don't construct our software like a building, we grow it like a garden.&amp;quot;        &lt;br /&gt;&lt;/em&gt;from Craig Larman, &lt;a href="http://www.infoq.com/articles/large-scale-agile-design-and-architecture"&gt;http://www.infoq.com/articles/large-scale-agile-design-and-architecture&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;   &lt;br /&gt;    &lt;br /&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="TFS checkins - follow how your application grows " border="0" alt="TFS checkins - follow how your application grows " src="http://lh5.ggpht.com/-bpZIEcPVupI/TuS1JiNyFEI/AAAAAAAAHhU/2_m_g5NM3b8/image%25255B26%25255D.png?imgmax=800" width="850" height="163" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: You can easily follow how your application grows - GERMAN screenshot&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="TFS2010 alert emails - Follow how your application grows  " border="0" alt="TFS2010 alert emails - Follow how your application grows  " src="http://lh6.ggpht.com/-HzUweciDekQ/TuS1M2BmKFI/AAAAAAAAHhY/gbgs-txfNow/image%25255B25%25255D.png?imgmax=800" width="800" height="302" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: TFS2010 alert emails - Follow how your application grows&amp;#160; - English screenshot&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;To get those emails in your project, you have to&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Install TFS Power tools &lt;a href="http://msdn.microsoft.com/en-us/vstudio/bb980963"&gt;http://msdn.microsoft.com/en-us/vstudio/bb980963&lt;/a&gt;&amp;#160; &lt;br /&gt;They contain the &amp;quot;Alert Explorer&amp;quot; that we need later &lt;/li&gt;    &lt;li&gt;Open VS2010 &lt;/li&gt;    &lt;li&gt;Go to [1] Team explorer &lt;/li&gt;    &lt;li&gt;[2] RIght Click on your Team Project &lt;/li&gt;    &lt;li&gt;Select [3] Alerts Explorer      &lt;br /&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Alerts Explorer" border="0" alt="Alerts Explorer" src="http://lh6.ggpht.com/-DGPc4dkFwyc/TuS1OTwk9KI/AAAAAAAAHg8/9lJzJQCikHs/image%25255B23%25255D.png?imgmax=800" width="446" height="275" /&gt; &lt;/li&gt;    &lt;li&gt;Add „New Alert“      &lt;br /&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="New Alert" border="0" alt="New Alert" src="http://lh5.ggpht.com/-ZpSjj7JSYgA/TuS1Ppq6YtI/AAAAAAAAHhE/UN40WxiiSjs/clip_image002%25255B6%25255D.png?imgmax=800" width="379" height="110" /&gt; &lt;/li&gt;    &lt;li&gt;Select &amp;quot;Check-in to a specific folder happens&amp;quot;      &lt;br /&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Check-in to a specific folder happens" border="0" alt="Check-in to a specific folder happens" src="http://lh3.ggpht.com/-7ak4iNft9Kk/TuS1Qlz4iBI/AAAAAAAAHhM/WeaQo3fOzNo/clip_image003%25255B6%25255D.png?imgmax=800" width="451" height="497" /&gt; &lt;/li&gt;    &lt;li&gt;Enter your email address and you are Done!      &lt;br /&gt;      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;I would recommend to create an Outlook rule to move those emails out of your inbox… Otherwise you get flooooded… &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Tip: We use these emails as private little code review mechanism as well, but all developers in 1 room with 1 beamer is much better!&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Note: I am strong believer in &amp;quot;small check-ins&amp;quot; as I mentioned already on my &lt;a href="http://blog.gfader.com/2011/05/3-keyboard-productivity-tips-for-vs2010.html" target="_blank"&gt;Keyboard tips&lt;/a&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Focus your work on small tasks &lt;/li&gt;    &lt;li&gt;Easier to describe what you did in your check-in comment &lt;/li&gt;    &lt;li&gt;Clear code history &lt;/li&gt;    &lt;li&gt;Easier merging &lt;em&gt;if you really need to branch and merge&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;Fast code reviews &lt;/li&gt;    &lt;li&gt;and more… &lt;/li&gt; &lt;/ol&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-3276157977484577347?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/U4jBJU4QQ2Y" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/U4jBJU4QQ2Y/tfs-see-your-application-grow-like.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-bpZIEcPVupI/TuS1JiNyFEI/AAAAAAAAHhU/2_m_g5NM3b8/s72-c/image%25255B26%25255D.png?imgmax=800" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://blog.gfader.com/2011/12/tfs-see-your-application-grow-like.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-6306784586562207505</guid><pubDate>Sun, 06 Nov 2011 15:28:00 +0000</pubDate><atom:updated>2011-11-06T16:31:02.561+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">sql server</category><category domain="http://www.blogger.com/atom/ns#">readibility</category><category domain="http://www.blogger.com/atom/ns#">database</category><category domain="http://www.blogger.com/atom/ns#">coding</category><title>SQL can stink too - Code smell in stored procedures</title><description>&lt;p&gt;&lt;a href="http://blog.gfader.com/2011/11/sql-can-stink-too-code-smell-in-stored.html"&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="image" border="0" alt="image" src="http://lh6.ggpht.com/-7HDpN0dQRrM/TranoZPauCI/AAAAAAAAHgk/v6gOHcje7-g/image%25255B8%25255D.png?imgmax=800" width="480" height="394" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: You don't need to dig deep to find smelly code&lt;/p&gt;  &lt;p&gt;I just found this nice piece of TSQL that I came across in a 500 line stored procedure on my current project. &lt;a name='more'&gt;&lt;/a&gt;   &lt;br /&gt;There are a couple of problems with the below query. &lt;/p&gt;  &lt;pre class="csharpcode"&gt;    &lt;span class="rem"&gt;-- Sanitized for blog&lt;/span&gt;
    insert &lt;span class="kwrd"&gt;into&lt;/span&gt; LinksBetweenPerson (LinkItemID, PersonID1, PersonID2, DateUpdated, DateCreated, EmpUpdated, EmpCreated)
    &lt;span class="kwrd"&gt;select&lt;/span&gt; newid(), A.PersonID1, A.PersonID2, getdate(), getdate(), suser_sname(), suser_sname()
    &lt;span class="kwrd"&gt;from&lt;/span&gt;
    (
          &lt;span class="kwrd"&gt;select&lt;/span&gt; &lt;span class="kwrd"&gt;distinct&lt;/span&gt; A.PersonWorkTimeID &lt;span class="kwrd"&gt;as&lt;/span&gt; PersonID1, B.PersonWorkTimeID &lt;span class="kwrd"&gt;as&lt;/span&gt; PersonID2 
          &lt;span class="kwrd"&gt;from&lt;/span&gt; PersonWorkTime A                
          &lt;span class="kwrd"&gt;inner&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt;
          (
                &lt;span class="kwrd"&gt;select&lt;/span&gt; A.PersonID, C.PersonWorkTimeID,  C.startTime, C.endTime 
                &lt;span class="kwrd"&gt;from&lt;/span&gt; PersonWorkplaceTemplate A              
                &lt;span class="kwrd"&gt;inner&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt; PersonWorkplaceTemplate B
                &lt;span class="kwrd"&gt;on&lt;/span&gt; A.PersonWorkplaceTemplateID = B.PersonWorkplaceTemplateID
                &lt;span class="kwrd"&gt;inner&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt; (
                      &lt;span class="kwrd"&gt;select&lt;/span&gt; B.PersonWorkTimeID, B.startTime, B.endTime,
                            &lt;span class="kwrd"&gt;case&lt;/span&gt; datepart(weekday,DATEADD(hh, DATEDIFF(hh, B.StartTime, B.EndTime)/2, B.StartTime))
                                  &lt;span class="kwrd"&gt;when&lt;/span&gt; 1 &lt;span class="kwrd"&gt;then&lt;/span&gt; A.Sunday
                                  &lt;span class="kwrd"&gt;when&lt;/span&gt; 2 &lt;span class="kwrd"&gt;then&lt;/span&gt; A.Monday
                                  &lt;span class="kwrd"&gt;when&lt;/span&gt; 3 &lt;span class="kwrd"&gt;then&lt;/span&gt; A.Tuesday
                                  &lt;span class="kwrd"&gt;when&lt;/span&gt; 4 &lt;span class="kwrd"&gt;then&lt;/span&gt; A.Wednesday
                                  &lt;span class="kwrd"&gt;when&lt;/span&gt; 5 &lt;span class="kwrd"&gt;then&lt;/span&gt; A.Thursday
                                  &lt;span class="kwrd"&gt;when&lt;/span&gt; 6 &lt;span class="kwrd"&gt;then&lt;/span&gt; A.Friday
                                  &lt;span class="kwrd"&gt;else&lt;/span&gt; A.Saturday
                            &lt;span class="kwrd"&gt;end&lt;/span&gt; &lt;span class="kwrd"&gt;as&lt;/span&gt; [Week]
                      &lt;span class="kwrd"&gt;from&lt;/span&gt; PersonWorkplaceTemplateLinkItem A             
                      &lt;span class="kwrd"&gt;inner&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt; #SourceWorkTime B &lt;span class="kwrd"&gt;on&lt;/span&gt; (A.[week]%@totalWeeks) = B.[week]
                      &lt;span class="kwrd"&gt;where&lt;/span&gt; A.PersonWorkplaceTemplateID = @PersonWorkplaceTemplateID ) c
                &lt;span class="kwrd"&gt;on&lt;/span&gt; ((DateDiff(&lt;span class="kwrd"&gt;day&lt;/span&gt;, B.StartDate, C.StartTime)/7+1)%@linkedTemplateTotalWeeks + A.[&lt;span class="kwrd"&gt;Order&lt;/span&gt;] *2)%@linkedTemplateTotalWeeks = C.[Week]%@linkedTemplateTotalWeeks
                &lt;span class="kwrd"&gt;where&lt;/span&gt; A.PersonWorkplaceTemplateID = @linkedTemplateID
          ) B &lt;span class="kwrd"&gt;on&lt;/span&gt; A.PersonID = B.PersonID &lt;span class="kwrd"&gt;and&lt;/span&gt; A.StartTime &amp;lt; B.EndTime &lt;span class="kwrd"&gt;and&lt;/span&gt; A.EndTime &amp;gt; B.StartTime
          &lt;span class="kwrd"&gt;where&lt;/span&gt; A.IsTemplateCreated = 1 &lt;span class="kwrd"&gt;and&lt;/span&gt; A.WorkPlaceID = @WorkPlaceID      
    ) A   
    &lt;span class="kwrd"&gt;left&lt;/span&gt; &lt;span class="kwrd"&gt;outer&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt; LinksBetweenPeople B
    &lt;span class="kwrd"&gt;on&lt;/span&gt; A.PersonID1 = B.PersonID1 &lt;span class="kwrd"&gt;and&lt;/span&gt; A.PersonID2 = B.PersonID2
    &lt;span class="kwrd"&gt;where&lt;/span&gt; B.LinkItemID &lt;span class="kwrd"&gt;is&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;    &lt;/pre&gt;

&lt;p&gt;&lt;style type="text/css"&gt;









.csharpcode, .csharpcode pre
{
	font-size: x-small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Before you read further try to spot some problems yourself…&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;.&lt;/p&gt;

&lt;p&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Wait!" border="0" alt="Wait!" src="http://lh3.ggpht.com/-bdq93W9yAXs/TranqcJHbGI/AAAAAAAAHgQ/dzz_kuvowC8/image%25255B6%25255D.png?imgmax=800" width="409" height="302" /&gt;&lt;/p&gt;

&lt;p&gt;.&lt;/p&gt;

&lt;p&gt;.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Wait! Did you really try to spot some problems??&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;There were some &lt;strong&gt;little issues&lt;/strong&gt; in this query that I fixed already before I published it here&lt;/p&gt;

&lt;p&gt;#1 Code layout was all over the place. &lt;/p&gt;

&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="TSQL - Code layout" border="0" alt="SQL - Code layout" src="http://lh4.ggpht.com/-kLu31_uKjZQ/TranraVsCpI/AAAAAAAAHgY/2mgOQKJmoRE/image151.png?imgmax=800" width="375" height="448" /&gt;&lt;/p&gt;

&lt;p&gt;Someone didn't care about the layout of the file. The next developer doesn't care either and we get into the problem of the &lt;a href="http://blog.gfader.com/2011/10/broken-window-theory-in-real-world.html" target="_blank"&gt;Broken Window Theory&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;#2 Commented out code&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;font style="background-color: #ffff00"&gt; &lt;span class="rem"&gt;-- insert into LinksBetweenPerson (LinkItemID, PersonID1, PersonID2)&lt;/span&gt;
 &lt;span class="rem"&gt;-- select newid(), A.PersonID1, A.PersonID2&lt;/span&gt;
&lt;/font&gt; insert &lt;span class="kwrd"&gt;into&lt;/span&gt; LinksBetweenPerson (LinkItemID, PersonID1, PersonID2, DateUpdated, DateCreated, EmpUpdated, EmpCreated)
 &lt;span class="kwrd"&gt;select&lt;/span&gt; newid(), A.PersonID1, A.PersonID2, getdate(), getdate(), suser_sname(), suser_sname()&lt;/pre&gt;

&lt;p&gt;Why is there some commented out code? 
  &lt;br /&gt;If you really can't delete code, because you feel so attached to it and it is a work of art, then leave a comment why this could be interesting for the next reader/developer.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;.&lt;/p&gt;

&lt;p&gt;.&lt;/p&gt;

&lt;p&gt;.&lt;/p&gt;

&lt;p&gt;.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Alright… Here are the big ones&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;#3 Naming of the result set: &amp;quot;A&amp;quot;, &amp;quot;B&amp;quot; and &amp;quot;C&amp;quot; is &lt;strong&gt;bad&lt;/strong&gt; cause there is no way to understand the intention &lt;/p&gt;

&lt;pre class="csharpcode"&gt;             &lt;span class="kwrd"&gt;select&lt;/span&gt; &lt;font style="background-color: #ffff00"&gt;A&lt;/font&gt;.PersonID, &lt;font style="background-color: #ffff00"&gt;C&lt;/font&gt;.PersonWorkTimeID,  &lt;font style="background-color: #ffff00"&gt;C&lt;/font&gt;.startTime, &lt;font style="background-color: #ffff00"&gt;C&lt;/font&gt;.endTime 
                &lt;span class="kwrd"&gt;from&lt;/span&gt; PersonWorkplaceTemplate &lt;font style="background-color: #ffff00"&gt;A &lt;/font&gt;             
                &lt;span class="kwrd"&gt;inner&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt; PersonWorkplaceTemplate &lt;font style="background-color: #ffff00"&gt;B&lt;/font&gt;
                &lt;span class="kwrd"&gt;on&lt;/span&gt; &lt;font style="background-color: #ffff00"&gt;A&lt;/font&gt;.PersonWorkplaceTemplateID = &lt;font style="background-color: #ffff00"&gt;B&lt;/font&gt;.PersonWorkplaceTemplateID
                &lt;/pre&gt;

&lt;p&gt;Please give it a nice name as: 
  &lt;br /&gt;&amp;quot;personsInWorkplace1&amp;quot; or &amp;quot;filteredPersons&amp;quot; or &amp;quot;personsWithLink&amp;quot; or &amp;quot;whatever_You_Come_Up_With&amp;quot; 

  &lt;br /&gt;but *NOT* 

  &lt;br /&gt;&amp;quot;A&amp;quot;, &amp;quot;B&amp;quot; or &amp;quot;C&amp;quot;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;#4 Reusing alias &amp;quot;A&amp;quot; and &amp;quot;B&amp;quot; in the same query multiple times, although they are completely distinct result sets&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;          select&lt;/span&gt; &lt;span class="kwrd"&gt;distinct&lt;/span&gt; A.PersonWorkTimeID &lt;span class="kwrd"&gt;as&lt;/span&gt; PersonID1, B.PersonWorkTimeID &lt;span class="kwrd"&gt;as&lt;/span&gt; PersonID2 
          &lt;font style="background-color: #ffff00"&gt;&lt;span class="kwrd"&gt;from&lt;/span&gt; PersonWorkTime A&lt;/font&gt;&lt;font style="background-color: #ffff00"&gt;  &lt;/font&gt;              
          &lt;span class="kwrd"&gt;inner&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt;
          (
                &lt;span class="kwrd"&gt;select&lt;/span&gt; A.PersonID, C.PersonWorkTimeID,  C.startTime, C.endTime 
                &lt;font style="background-color: #ffff00"&gt;&lt;span class="kwrd"&gt;from&lt;/span&gt; PersonWorkplaceTemplate A&lt;/font&gt;              
                &lt;span class="kwrd"&gt;inner&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt; PersonWorkplaceTemplate B
                &lt;span class="kwrd"&gt;on&lt;/span&gt; A.PersonWorkplaceTemplateID = B.PersonWorkplaceTemplateID
                &lt;span class="kwrd"&gt;inner&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt; (
                      &lt;span class="kwrd"&gt;select&lt;/span&gt; B.PersonWorkTimeID, B.startTime, B.endTime,
                            &lt;span class="kwrd"&gt;case&lt;/span&gt; datepart(weekday,DATEADD(hh, DATEDIFF(hh, B.StartTime, B.EndTime)/2, B.StartTime))
                                  &lt;span class="kwrd"&gt;when&lt;/span&gt; 1 &lt;span class="kwrd"&gt;then&lt;/span&gt; A.Sunday
                                  &lt;span class="kwrd"&gt;when&lt;/span&gt; 2 &lt;span class="kwrd"&gt;then&lt;/span&gt; A.Monday
                                  &lt;span class="kwrd"&gt;when&lt;/span&gt; 3 &lt;span class="kwrd"&gt;then&lt;/span&gt; A.Tuesday
                                  &lt;span class="kwrd"&gt;when&lt;/span&gt; 4 &lt;span class="kwrd"&gt;then&lt;/span&gt; A.Wednesday
                                  &lt;span class="kwrd"&gt;when&lt;/span&gt; 5 &lt;span class="kwrd"&gt;then&lt;/span&gt; A.Thursday
                                  &lt;span class="kwrd"&gt;when&lt;/span&gt; 6 &lt;span class="kwrd"&gt;then&lt;/span&gt; A.Friday
                                  &lt;span class="kwrd"&gt;else&lt;/span&gt; A.Saturday
                            &lt;span class="kwrd"&gt;end&lt;/span&gt; &lt;span class="kwrd"&gt;as&lt;/span&gt; [Week]
                      &lt;span class="kwrd"&gt;from&lt;/span&gt; PersonWorkplaceTemplateLinkItem A             
                      &lt;span class="kwrd"&gt;inner&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt; #SourceWorkTime B &lt;span class="kwrd"&gt;on&lt;/span&gt; (A.[week]%@totalWeeks) = B.[week]
                      &lt;span class="kwrd"&gt;where&lt;/span&gt; A.PersonWorkplaceTemplateID = @PersonWorkplaceTemplateID ) c
                &lt;span class="kwrd"&gt;on&lt;/span&gt; ((DateDiff(&lt;span class="kwrd"&gt;day&lt;/span&gt;, B.StartDate, C.StartTime)/7+1)%@linkedTemplateTotalWeeks + A.[&lt;span class="kwrd"&gt;Order&lt;/span&gt;] *2)%@linkedTemplateTotalWeeks = C.[Week]%@linkedTemplateTotalWeeks
                &lt;span class="kwrd"&gt;where&lt;/span&gt; A.PersonWorkplaceTemplateID = @linkedTemplateID
          ) B &lt;span class="kwrd"&gt;on&lt;/span&gt; A.PersonID = B.PersonID &lt;span class="kwrd"&gt;and&lt;/span&gt; A.StartTime &amp;lt; B.EndTime &lt;span class="kwrd"&gt;and&lt;/span&gt; A.EndTime &amp;gt; B.StartTime
          &lt;span class="kwrd"&gt;where&lt;/span&gt; A.IsTemplateCreated = 1 &lt;span class="kwrd"&gt;and&lt;/span&gt; A.WorkPlaceID = @WorkPlaceID      &lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;#5 The usage of DISTINCT is normally a sign of bad written queries, since the author tried to hack something together, instead of identified the planned result set. &lt;em&gt;Not necessarily too bad then..&lt;/em&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;select&lt;/span&gt; &lt;span class="kwrd"&gt;&lt;font style="background-color: #ffff00"&gt;distinct&lt;/font&gt;&lt;/span&gt; A.PersonWorkTimeID &lt;span class="kwrd"&gt;as&lt;/span&gt; PersonID1, B.PersonWorkTimeID &lt;span class="kwrd"&gt;as&lt;/span&gt; PersonID2 
          &lt;span class="kwrd"&gt;from&lt;/span&gt; PersonWorkTime A                
          &lt;span class="kwrd"&gt;inner&lt;/span&gt; &lt;span class="kwrd"&gt;join&lt;/span&gt;
       &lt;span class="rem"&gt;-- snip snip snip&lt;/span&gt;
         &lt;/pre&gt;

&lt;br /&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Can you spot more problems? 
  &lt;br /&gt;What if I tell you to fix something in this query? 

  &lt;br /&gt;How could we avoid this?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-6306784586562207505?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/un0M0qJmDlk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/un0M0qJmDlk/sql-can-stink-too-code-smell-in-stored.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-7HDpN0dQRrM/TranoZPauCI/AAAAAAAAHgk/v6gOHcje7-g/s72-c/image%25255B8%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.gfader.com/2011/11/sql-can-stink-too-code-smell-in-stored.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-3576606859149254926</guid><pubDate>Wed, 26 Oct 2011 08:12:00 +0000</pubDate><atom:updated>2011-10-26T10:18:40.400+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">personal</category><category domain="http://www.blogger.com/atom/ns#">testing</category><title>The broken window theory in the real world</title><description>&lt;p&gt;&lt;em&gt;I used to live in beautiful sunny Neutral Bay, Sydney where I walked along Bent Street every day. I moved back to Europe at the end of this July and just found this in my Draft blog folder..&lt;/em&gt;     &lt;br /&gt;I experienced the &amp;quot;&lt;a href="http://en.wikipedia.org/wiki/Broken_windows_theory" target="_blank"&gt;broken window theory&lt;/a&gt;&amp;quot; myself, in front of my door.&lt;/p&gt;  &lt;table border="0" cellspacing="2" cellpadding="2" width="409"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="133"&gt;&lt;a href="http://lh3.ggpht.com/-dFUj4NDMwgU/TqfAsqTh9GI/AAAAAAAAHbY/8oQuKuFsl1I/s1600-h/image17.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-g8MQjnMjsYo/TqfAuDgEb4I/AAAAAAAAHbg/MW4hQNpPNxE/image_thumb7.png?imgmax=800" width="252" height="150" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="133"&gt;&lt;a href="http://lh3.ggpht.com/-Mv2RsJeJ5Ww/TqfAzDWPSVI/AAAAAAAAHbo/zT_7sUexnE8/s1600-h/image12.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-QjjbF910g_s/TqfA0WVNoKI/AAAAAAAAHbw/llCjIm6cmMs/image_thumb4.png?imgmax=800" width="240" height="150" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="133"&gt;&lt;a href="http://lh3.ggpht.com/-m1Fsjqutqcw/TqfA4wZghiI/AAAAAAAAHb4/URPRdn4ZD3s/s1600-h/image22.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-_XSimLaJTvU/TqfA52iOzAI/AAAAAAAAHcA/9SfIEEyNpgU/image_thumb10.png?imgmax=800" width="237" height="150" /&gt;&lt;/a&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;18 February          &lt;br /&gt;&lt;/td&gt;        &lt;td valign="top" width="133"&gt;23 February&lt;/td&gt;        &lt;td valign="top" width="133"&gt;1 March          &lt;br /&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;em&gt;Click on pictures for larger views&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;I was on holidays in New Zealand in January, and I didn't notice the car till afterwards in February.      &lt;br /&gt;I noticed the car before, with a couple of bushes under the bottom but I thought it was just parked there for a while. In February I started to take pictures. The above pictures are the result.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;I found this interesting because I would have never thought that I would &amp;quot;experience&amp;quot; this myself, and the street I used to live in was pretty neat &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh5.ggpht.com/-VEOf67yQdDs/TqfA6uDbrvI/AAAAAAAAHcI/nXNlb0TNeuQ/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800" /&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Why do I care as a software developer?&lt;/strong&gt;     &lt;br /&gt;A little mess turns into a bigger mess pretty quickly, especially for code.     &lt;br /&gt;If you don't care about your code, you start to become sloppy. Sloppy code attracts more sloppy code. The next developers copies and imitates the previous developer. And &amp;quot;Bumm!&amp;quot; you have a mess.     &lt;br /&gt;&lt;em&gt;Have you ever come across a nice clean codebase and thought. &amp;quot;Uhhh… I am not sure if I want to touch this code, this is so beautiful and clean.&amp;quot;      &lt;br /&gt;&lt;/em&gt;&lt;a href="http://blog.gfader.com/2010/11/clean-code-development-talk-at-netug.html" target="_blank"&gt;Topic is covered in my talk about Clean Code Development&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Potential ways to avoid this&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Follow the &amp;quot;Boy Scout rule&amp;quot; &lt;/li&gt;    &lt;li&gt;Review your code with your peers &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.gfader.com/2010/10/why-are-automated-tests-so-important.html" target="_blank"&gt;Write tests that act as a playground fence for your refactorings&lt;/a&gt;       &lt;br /&gt;&lt;em&gt;Developers like to play, so why not create a playground fence yourself where you can play with refactorings, new tools, new technologies and possible improvements&lt;/em&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Tests act as a fence around your playground" border="0" alt="Tests act as a fence around your playground" src="http://lh3.ggpht.com/-97ebaAos_q4/TqfA7-GU02I/AAAAAAAAHcQ/4g1v1NsiFXI/image%25255B5%25255D.png?imgmax=800" width="340" height="328" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Tests act as a fence around your playground (and as a sandbox for new ideas)&lt;/p&gt;  &lt;p&gt;Playing supports learning, creativity and relationship building. Watch &lt;a href="http://www.ted.com/talks/stuart_brown_says_play_is_more_than_fun_it_s_vital.html" target="_blank"&gt;this TED talk from Stuart Brown&lt;/a&gt; for more on this topic…     &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-3576606859149254926?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/j5Sg9kHyN3c" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/j5Sg9kHyN3c/broken-window-theory-in-real-world.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-g8MQjnMjsYo/TqfAuDgEb4I/AAAAAAAAHbg/MW4hQNpPNxE/s72-c/image_thumb7.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.gfader.com/2011/10/broken-window-theory-in-real-world.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-930241070361644623</guid><pubDate>Fri, 21 Oct 2011 10:34:00 +0000</pubDate><atom:updated>2011-10-25T23:43:40.226+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">readibility</category><category domain="http://www.blogger.com/atom/ns#">coding</category><title>Code smell - LINQ to SQL Datacontext usage and more… - Refactoring work in progress</title><description>&lt;p&gt;&lt;a href="http://blog.gfader.com/2011/10/code-smell-linq-to-sql-datacontext_21.html"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-X3Lw20cPpPE/TqFLcNoPirI/AAAAAAAAHa8/a9kJTjIIqRY/image%25255B11%25255D.png?imgmax=800" width="601" height="177" /&gt;&lt;/a&gt;     &lt;br /&gt;Following up the &lt;a href="http://blog.gfader.com/2011/10/code-smell-linq-to-sql-datacontext_08.html" target="_blank"&gt;blog post about some major issues in the usage of the datacontext&lt;/a&gt; I dig into more details here.     &lt;br /&gt;Here is the &lt;a href="http://blog.gfader.com/2011/10/code-smell-linq-to-sql-datacontext.html" target="_blank"&gt;initial blog post with an intro and the whole code&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Lets start to look at the methods itself, starting with: &amp;quot;UpdateEmployeePositionHistory&amp;quot;. &lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;The name suggests that we are updating something with the values from the method.    &lt;br /&gt;Probably we are updating an entry in the database with ID:&amp;quot;EmployeeAssignmentID&amp;quot; and update that with the values: &amp;quot;EmployeeTypeID&amp;quot; and a new &amp;quot;startDate&amp;quot;&lt;/p&gt;  &lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; UpdateEmployeePositionHistory(Guid EmployeeAssignmentID, Guid EmployeeTypeID, DateTime startDate)
        {
            var _positionAssignment = GetCurrentAssignment(EmployeeAssignmentID);
            var assignmentBefore = &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetAssignStartDateBeforeEmployeePositionAssigment(_positionAssignment.EmployeeID, _positionAssignment.DateBegin);
            var assignmentAfter = &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetAssignStartDateAfterEmployeePositionAssigment(_positionAssignment.EmployeeID, _positionAssignment.DateBegin);
&lt;font style="background-color: #ffff00"&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (_positionAssignment != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
&lt;/font&gt;            {
                _positionAssignment.EmployeeTypeID = EmployeeTypeID;
                _positionAssignment.DateBegin = startDate;
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentBefore != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    assignmentBefore.DateEnd = startDate.AddDays(-1);
                }
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentAfter == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    _positionAssignment.DateEnd = defaultMaxDate;
                }
                &lt;span class="kwrd"&gt;else&lt;/span&gt;
                {
                    _positionAssignment.DateEnd = assignmentAfter.DateBegin.AddDays(-1);
                }
            }
            db.SubmitChanges();
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.ApplyPositionChangesToEmployee(_positionAssignment.EmployeeID);
            RuleManager.MarkEmployeeShiftAsDirty(_positionAssignment.EmployeeID, _positionAssignment.DateBegin, (DateTime)_positionAssignment.DateEnd);
        }&lt;/pre&gt;
&lt;style type="text/css"&gt;















.csharpcode, .csharpcode pre
{
	font-size: x-small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;That is the case, but we are updating a previous entry as well. &lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image44" border="0" alt="image44" src="http://lh4.ggpht.com/-2fWg1Jg2src/TqHur9ijUpI/AAAAAAAAHbE/26cI5Nu6FOA/image44%25255B4%25255D.png?imgmax=800" width="50" height="40" /&gt; The method name didn't suggest that.&lt;/p&gt;

&lt;p&gt;The first major problem that I see is the &lt;font style="background-color: #ffff00"&gt;yellow&lt;/font&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Warning Problem ahead" border="0" alt="Warning Problem ahead" src="http://lh6.ggpht.com/-wHX3bg_OjdA/TqFKr1WdLJI/AAAAAAAAHbI/UJTD0wjDgmo/image4%25255B2%25255D.png?imgmax=800" width="50" height="40" /&gt; If there is a current position (positionAssignment !=null &lt;font style="background-color: #ffff00"&gt;highlighted yellow above&lt;/font&gt;) we are updating it. 

  &lt;br /&gt;If there is NO current position we are submitting changes to the database (although there are any), apply some position changes and mark those changes as dirty, so that our RuleProcessor can process them.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;            db.SubmitChanges();
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.ApplyPositionChangesToEmployee(_positionAssignment.EmployeeID);
            RuleManager.MarkEmployeeShiftAsDirty(_positionAssignment.EmployeeID, _positionAssignment.DateBegin, (DateTime)_positionAssignment.DateEnd);&lt;/pre&gt;
&lt;style type="text/css"&gt;














.csharpcode, .csharpcode pre
{
	font-size: x-small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;This does not make sense, since no changes would not necessarily need to trigger a DB update and rule manager doesn't need to mark some entries as dirty.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Next problem:&lt;/p&gt;

&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image4" border="0" alt="image4" src="http://lh5.ggpht.com/-IFkPOmQFT5Y/TqFKsj_Fq4I/AAAAAAAAHbM/2Sr1446DKBU/image42%25255B1%25255D.png?imgmax=800" width="50" height="40" /&gt; We have 2 method calls in that method that have not a very good name I think:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;   var assignmentBefore = &lt;span class="kwrd"&gt;this&lt;/span&gt;.&lt;font style="background-color: #ffff00"&gt;GetAssignStartDateBeforeEmployeePositionAssigment&lt;/font&gt;(_positionAssignment.EmployeeID, _positionAssignment.DateBegin);
   var assignmentAfter = &lt;span class="kwrd"&gt;this&lt;/span&gt;.&lt;font style="background-color: #ffff00"&gt;GetAssignStartDateAfterEmployeePositionAssigment&lt;/font&gt;(_positionAssignment.EmployeeID, _positionAssignment.DateBegin);&lt;/pre&gt;
&lt;style type="text/css"&gt;












.csharpcode, .csharpcode pre
{
	font-size: x-small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;I will probably rename them to&lt;/p&gt;

&lt;pre class="csharpcode"&gt;   var assignmentBefore = &lt;span class="kwrd"&gt;this&lt;/span&gt;.&lt;font style="background-color: #ffff00"&gt;GetAssignmentBeforeDate&lt;/font&gt;(_positionAssignment.EmployeeID, _positionAssignment.DateBegin);
   var assignmentAfter = &lt;span class="kwrd"&gt;this&lt;/span&gt;.&lt;font style="background-color: #ffff00"&gt;GetAssignmentAfterDate&lt;/font&gt;(_positionAssignment.EmployeeID, _positionAssignment.DateBegin);&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Long story short, I refactor this method without any tests around it. &lt;em&gt;I know I shouldn't do that. We had tests that use a test database, but since my last time on this project all these tests are ignored and the test database is gone. Probably someone else couldn't be bothered. 
    &lt;br /&gt;This is just 1 of the pains with tests that use the database (Note: &lt;a href="http://blog.gfader.com/2010/08/how-to-unit-test-wcf-service.html" target="_blank"&gt;these are *not* unit tests&lt;/a&gt;). 

    &lt;br /&gt;What I could have done is mock the datacontext by following this blog post from Andrew Tokeley &lt;/em&gt;&lt;a title="http://andrewtokeley.net/archive/2008/07/06/mocking-linq-to-sql-datacontext.aspx" href="http://andrewtokeley.net/archive/2008/07/06/mocking-linq-to-sql-datacontext.aspx"&gt;http://andrewtokeley.net/archive/2008/07/06/mocking-linq-to-sql-datacontext.aspx&lt;/a&gt; 

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Finally I changed the method from&lt;/p&gt;

&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; UpdateEmployeePositionHistory(Guid EmployeeAssignmentID, Guid EmployeeTypeID, DateTime startDate)
        {
            var _positionAssignment = GetCurrentAssignment(EmployeeAssignmentID);
            var assignmentBefore = &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetAssignStartDateBeforeEmployeePositionAssigment(_positionAssignment.EmployeeID, _positionAssignment.DateBegin);
            var assignmentAfter = &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetAssignStartDateAfterEmployeePositionAssigment(_positionAssignment.EmployeeID, _positionAssignment.DateBegin);
&lt;font style="background-color: #ffff00"&gt;&lt;/font&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (_positionAssignment != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
&lt;font style="background-color: #ffff00"&gt;&lt;/font&gt;            {
                _positionAssignment.EmployeeTypeID = EmployeeTypeID;
                _positionAssignment.DateBegin = startDate;
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentBefore != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    assignmentBefore.DateEnd = startDate.AddDays(-1);
                }
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentAfter == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    _positionAssignment.DateEnd = defaultMaxDate;
                }
                &lt;span class="kwrd"&gt;else&lt;/span&gt;
                {
                    _positionAssignment.DateEnd = assignmentAfter.DateBegin.AddDays(-1);
                }
            }
            db.SubmitChanges();
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.ApplyPositionChangesToEmployee(_positionAssignment.EmployeeID);
            RuleManager.MarkEmployeeShiftAsDirty(_positionAssignment.EmployeeID, _positionAssignment.DateBegin, (DateTime)_positionAssignment.DateEnd);
        }&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;to&lt;/p&gt;

&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; UpdateEmployeePositionHistory(Guid employeeAssignmentID, Guid employeeTypeID, DateTime startDate)
        {
            var assignment = UpdateAssignment(employeeAssignmentID, employeeTypeID, startDate);

            &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignment != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                FixUpdatedAssignment(assignment);
            }
        }&lt;/pre&gt;
&lt;style type="text/css"&gt;












.csharpcode, .csharpcode pre
{
	font-size: x-small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;I don't like the null check in this method, but I live with it for now…&lt;/p&gt;

&lt;p&gt;I extracted some code to &amp;quot;FixUpdatedAssignment&amp;quot;, being the 3 method calls that we did before all the time.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; FixUpdatedAssignment(EmployeePositionHistoryAssignment assignment)
        {
            ApplyPositionChangesToEmployee(assignment.EmployeeID);
            DateTime endTime = assignment.DateEnd.HasValue ? assignment.DateEnd.Value : DefaultMaxDate;
            RuleManager.MarkEmployeeShiftAsDirty(assignment.EmployeeID, assignment.DateBegin, endTime);
        }&lt;/pre&gt;
&lt;style type="text/css"&gt;












.csharpcode, .csharpcode pre
{
	font-size: x-small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;The other piece of code I fixed and extracted to &amp;quot;UpdateAssignment&amp;quot;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; EmployeePositionHistoryAssignment UpdateAssignment(Guid employeeAssignmentID, Guid employeeTypeID, DateTime startDate)
{
    &lt;span class="kwrd"&gt;using&lt;/span&gt; (NorthwindDataContext db = &lt;span class="kwrd"&gt;new&lt;/span&gt; NorthwindDataContext())
    {
        EmployeePositionHistoryAssignment assignment = GetAssignment(employeeAssignmentID);
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignment != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        {
&lt;font style="background-color: #ffff00"&gt;                    &lt;span class="rem"&gt;//Since we are updating the assignment before we have to get it from the current datacontext&lt;/span&gt;
&lt;/font&gt;                    var assignmentBefore = (from assignmentFromDB &lt;span class="kwrd"&gt;in&lt;/span&gt; db.EmployeePositionHistoryAssignments
                                    &lt;span class="kwrd"&gt;where&lt;/span&gt;
                                        assignmentFromDB.EmployeeID == assignment.EmployeeID &amp;amp;&amp;amp;
                                        assignmentFromDB.DateBegin &amp;lt; assignment.DateBegin
                                    orderby assignmentFromDB.DateBegin descending
                                    select assignmentFromDB).FirstOrDefault();
            
            var assignmentAfter = GetAssignmentAfterDate(assignment.EmployeeID,
                                                         assignment.DateBegin);
            assignment.EmployeeTypeID = employeeTypeID;
            assignment.DateBegin = startDate;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentBefore != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                assignmentBefore.DateEnd = startDate.AddDays(-1);
            }
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentAfter == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                assignment.DateEnd = DefaultMaxDate;
            }
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
            {
                assignment.DateEnd = assignmentAfter.DateBegin.AddDays(-1);
            }
        }
        db.SubmitChanges();
        &lt;span class="kwrd"&gt;return&lt;/span&gt; assignment;
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;












.csharpcode, .csharpcode pre
{
	font-size: x-small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;#1 The yellow above is *very* important. We have to get the &amp;quot;assignmentBefore&amp;quot; from the same datacontext. Otherwise the SubmitChanges wont update the &amp;quot;assignmentbefore&amp;quot;. That was the reason we had a global datacontext object before &lt;a href="http://blog.gfader.com/2011/10/code-smell-linq-to-sql-datacontext_08.html" target="_blank"&gt;as we figured out&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;#2 I removed the &lt;font style="background-color: #ffff00"&gt;class-wide datacontext below &lt;/font&gt;&lt;font style="background-color: #ffffff"&gt;and need to fix all other methods in this class&lt;/font&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; EmployeePositionAssignment
    {
&lt;font style="background-color: #ffff00"&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; NorthWindDataContext db = &lt;span class="kwrd"&gt;new&lt;/span&gt; NorthWindDataContext();
&lt;/font&gt;       &lt;span class="rem"&gt;// -- snip snip snip --&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now I am up to fix all the other methods that use the &amp;quot;global&amp;quot; datacontext… More fun coming….&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-930241070361644623?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/59oYdrNfpNw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/59oYdrNfpNw/code-smell-linq-to-sql-datacontext_21.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-X3Lw20cPpPE/TqFLcNoPirI/AAAAAAAAHa8/a9kJTjIIqRY/s72-c/image%25255B11%25255D.png?imgmax=800" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://blog.gfader.com/2011/10/code-smell-linq-to-sql-datacontext_21.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-4977660725108493459</guid><pubDate>Sat, 08 Oct 2011 08:44:00 +0000</pubDate><atom:updated>2011-10-08T10:44:50.816+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">readibility</category><category domain="http://www.blogger.com/atom/ns#">coding</category><title>Code smell - LINQ to SQL Datacontext usage and more… - Look from a bird's eye view</title><description>&lt;p&gt;Alright! Lets have a look at &lt;a href="http://blog.gfader.com/2011/10/code-smell-linq-to-sql-datacontext.html" target="_blank"&gt;this nice piece of code&lt;/a&gt; that I posted before.     &lt;br /&gt;&lt;a href="http://blog.gfader.com/2011/10/code-smell-linq-to-sql-datacontext_08.html"&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="bad code - work in progress" border="0" alt="bad code - work in progress" src="http://lh6.ggpht.com/-6s_FSDuLIbc/TpANV-bqLII/AAAAAAAAHV0/qGfU5lNQ0d4/image%25255B7%25255D.png?imgmax=800" width="736" height="196" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;&lt;em&gt;As we follow the &amp;quot;&lt;/em&gt;&lt;a href="http://blog.gfader.com/2011/02/room-rule.html" target="_blank"&gt;&lt;em&gt;Boy Scout rule&lt;/em&gt;&lt;/a&gt;&lt;em&gt;&amp;quot; we try to improve this code every now and then. That means we get to a point where we are happy today but we need to accept that &lt;strong&gt;we are not getting it perfect today&lt;/strong&gt;…&lt;/em&gt;&lt;/p&gt; &lt;!-- more --&gt;  &lt;p&gt;   &lt;br /&gt;First of all, let us try to understand the responsibility of this class and the intention behind it. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The name is &amp;quot;EmployeePositionAssignment&amp;quot; and it uses a data context and has 2 constants. That is not too bad, but doesn't really tell us what the intention is. &lt;/li&gt;    &lt;li&gt;The class-wide defined datacontext suggest that we are reusing that datacontext multiple times which is a little worry so far, since MSDN is suggesting us to avoid this. From &lt;a title="http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.aspx" href="http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.aspx"&gt;http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.aspx&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;The DataContext is the source of all entities mapped over a database connection. It tracks changes that you made to all retrieved entities and maintains an &amp;quot;identity cache&amp;quot; that guarantees that entities retrieved more than one time are represented by using the same object instance.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;In general, a DataContext instance is designed to last for one &amp;quot;unit of work&amp;quot; however your application defines that term. A DataContext is lightweight and is not expensive to create. A typical LINQ to SQL application creates DataContext &lt;font style="background-color: #ffff00"&gt;instances at method scope&lt;/font&gt; or as a &lt;font style="background-color: #ffff00"&gt;member of short-lived classes&lt;/font&gt; that represent a logical set of related database operations.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; EmployeePositionAssignment
    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; NorthWindDataContext &lt;font style="background-color: #ffff00"&gt;db = &lt;span class="kwrd"&gt;new&lt;/span&gt; NorthWindDataContext&lt;/font&gt;();
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; TimeSpan defaultTimeSpan = &lt;span class="kwrd"&gt;new&lt;/span&gt; TimeSpan(1, 0, 0, 0);
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; DateTime defaultMaxDate = &lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(2100, 1, 1);
      // -- snip snip snip --&lt;/pre&gt;
&lt;style type="text/css"&gt;












.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Warning - Bad Code ahead" border="0" alt="Warning - Bad Code ahead" src="http://lh3.ggpht.com/-A-lepK2JhDo/TpANW2ADjXI/AAAAAAAAHVs/M_mY5-kt-QY/image4.png?imgmax=800" width="50" height="40" /&gt; The 1st bit of worrying code is the constructor that opens a database connection, although we are using LINQ2SQL as an ORM mapper here. &lt;/p&gt;

&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; EmployeePositionAssignment()
        {
            db.Connection.Open();
        }&lt;/pre&gt;

&lt;p&gt;Since we are using an ORM framework we shouldn't need to do this and let the framework manage the connection for us. 
  &lt;br /&gt;That raises a question: When are we going to close the connection?&lt;/p&gt;
&lt;style type="text/css"&gt;












.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The next few lines show us the answer to the previous question. &lt;/p&gt;

&lt;pre class="csharpcode"&gt;        &lt;span class="rem"&gt;//~EmployeePositionAssignment()&lt;/span&gt;
        &lt;span class="rem"&gt;//{&lt;/span&gt;
        &lt;span class="rem"&gt;//    if (db.Connection.State == ConnectionState.Open)&lt;/span&gt;
        &lt;span class="rem"&gt;//    {&lt;/span&gt;
        &lt;span class="rem"&gt;//        db.Connection.Close();&lt;/span&gt;
        &lt;span class="rem"&gt;//    }&lt;/span&gt;
        &lt;span class="rem"&gt;//    db.Dispose();&lt;/span&gt;
        &lt;span class="rem"&gt;//}&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Someone tried to close the database connection in the finalizer of the class. 
  &lt;br /&gt;&lt;em&gt;I am not saying &amp;quot;destructor&amp;quot; here, since we C# developers should think about this method as a finalizer and not destructor in a C++ sense. More on this topic and the differences can be found on &lt;a href="http://msdn.microsoft.com/en-us/library/ms177197(v=vs.80).aspx" target="_blank"&gt;MSDN&lt;/a&gt; and on &lt;a href="http://weblogs.thinktecture.com/cnagel/2006/04/ccli-finalize-and-dispose.html" target="_blank"&gt;Christian Nagel's blog entry about C++/CLI, Finalize and Dispose&lt;/a&gt;&lt;/em&gt; 

  &lt;br /&gt;There are a couple of problems with this finalizer:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Finalizers should *only* be used to clean up &lt;strong&gt;unmanaged resources&lt;/strong&gt;. 

    &lt;br /&gt;&lt;em&gt;We should very rarely need a finalizer these days actually&lt;/em&gt; &lt;/li&gt;

  &lt;li&gt;It would be better to implement &amp;quot;IDisposable&amp;quot; and let the allow users of the class when the connection is not needed anymore &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Heaps of more great information and guidelines can be found as part of the &lt;a href="http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx" target="_blank"&gt;Framework Design Guidelines&lt;/a&gt;. There are some nice patterns on how to &lt;a href="http://msdn.microsoft.com/en-us/library/system.idisposable.aspx" target="_blank"&gt;implement IDisposable&lt;/a&gt; too.&lt;/p&gt;

&lt;p&gt;Back to the initial question: Where is connection closed then? Probably as part of the GC removing up the type &amp;quot;NorthWindDataContext&amp;quot;, LINQ2SQL will close the connection, but not before. Which means multiple instances of this class can use up all connections to the database and we are presented with a &lt;a href="http://blog.gfader.com/2009/11/aspnet-how-to-show-all-roles-of-current.html" target="_blank"&gt;YSOD&lt;/a&gt;, pretty soon &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-sadsmile" alt="Sad smile" src="http://lh6.ggpht.com/-C21DtvHQ5VM/TpANXVTc68I/AAAAAAAAHVw/-tqgxCrCfmk/wlEmoticon-sadsmile2.png?imgmax=800" /&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The next piece of evil code in this is the following method: &amp;quot;ApplyDepotChangesToShifts&amp;quot;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Warning - Bad Code ahead" border="0" alt="Warning - Bad Code ahead" src="http://lh3.ggpht.com/-A-lepK2JhDo/TpANW2ADjXI/AAAAAAAAHVs/M_mY5-kt-QY/image4.png?imgmax=800" width="50" height="40" /&gt; We are passing the whole &amp;quot;NorthWindDataContext&amp;quot; to the method, which is clearly violating the &amp;quot;&lt;a href="http://pragprog.com/articles/tell-dont-ask" target="_blank"&gt;Tell don't ask&lt;/a&gt;&amp;quot; principle 

    &lt;br /&gt;This comes close to: &lt;em&gt;&amp;quot;Hey I give you everything and you just take what you need --&amp;gt; Out of control&amp;quot;&lt;/em&gt; 

    &lt;br /&gt;&lt;/li&gt;

  &lt;li&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Warning - Bad Code ahead" border="0" alt="Warning - Bad Code ahead" src="http://lh3.ggpht.com/-A-lepK2JhDo/TpANW2ADjXI/AAAAAAAAHVs/M_mY5-kt-QY/image4.png?imgmax=800" width="50" height="40" /&gt; We have a parameter &amp;quot;bool isDelete&amp;quot; which suggests us that this method is doing 2 things. We should &lt;a href="http://blog.gfader.com/2010/06/avoid-boolean-parameters-in-method.html" target="_blank"&gt;avoid boolean parameters and have 2 separate methods instead&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; ApplyDepotChangesToShifts(
                           &lt;font style="background-color: #ffff00"&gt;NorthWindDataContext dataContext,&lt;/font&gt; 
                           EmployeeDepotHistoryAssignment assignment, 
                           &lt;font style="background-color: #ffff00"&gt;&lt;span class="kwrd"&gt;bool&lt;/span&gt; isDelete,&lt;/font&gt; 
                           DateTime originalDateBegin)
        {&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Warning - Bad Code ahead" border="0" alt="Warning - Bad Code ahead" src="http://lh3.ggpht.com/-A-lepK2JhDo/TpANW2ADjXI/AAAAAAAAHVs/M_mY5-kt-QY/image4.png?imgmax=800" width="50" height="40" /&gt; The next worrying discovery (with the help of &lt;a href="http://www.jetbrains.com/resharper/" target="_blank"&gt;Resharper&lt;/a&gt;) is that all methods are &amp;quot;public&amp;quot; although some could be &amp;quot;private&amp;quot;. By making some methods &amp;quot;private&amp;quot; in this 400 line helper class we could help the next reader to understand the intention of the class and help applying some refactorings to separate responsibilities.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion &lt;/strong&gt;(so far)&lt;/p&gt;

&lt;p&gt;Just by having a bird's eye view on this class we spotted already a couple of issues we need to fix. 
  &lt;br /&gt;First of we should probably start by removing the class-wide DataContext and making sure that every method uses its own datacontext properly.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How did we get here?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I am trying to understand the current situation and how we got into this mess. This might help me avoid this situation in the future… 
    &lt;br /&gt;&lt;/em&gt;#1 There were no Code Reviews in place, otherwise another developer would have pointed out: &amp;quot;Hey, I don't get this bit here&amp;quot; or maybe just yelling out: &amp;quot;WTF&amp;quot; as illustrated in this nice comic: &amp;quot;&lt;a href="http://www.osnews.com/story/19266/WTFs_m" target="_blank"&gt;The only valid measurement of code quality&lt;/a&gt;&amp;quot;&lt;/p&gt;

&lt;p&gt;#2 Automated tools could help here as well: NDepend, StyleCop, VS2010 Code Analysis or FxCop (&lt;a href="http://blog.gfader.com/2010/08/what-is-difference-between-vs-code.html" target="_blank"&gt;What is the difference?&lt;/a&gt;) could definitely help to tell us the most worrying code in this solution&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problems ahead&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before we touch any code, we should ensure that all tests are green around this specific piece of code. 
  &lt;br /&gt;2 problems here:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;There are no tests around this code &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-sadsmile" alt="Sad smile" src="http://lh6.ggpht.com/-C21DtvHQ5VM/TpANXVTc68I/AAAAAAAAHVw/-tqgxCrCfmk/wlEmoticon-sadsmile2.png?imgmax=800" /&gt;, which means &lt;strong&gt;I am on my own &lt;/strong&gt;when I am changing something. 

    &lt;br /&gt;There is no way for me to find out if I broke something or not, unless manual testing through the UI. As &lt;a href="http://blog.gfader.com/2010/10/why-are-automated-tests-so-important.html" target="_blank"&gt;we know manual testing is cumbersome, costs time and is NOT FUN&lt;/a&gt;. &lt;/li&gt;

  &lt;li&gt;This class uses a the &amp;quot;NorthWindDataContext&amp;quot; type which is instantiated as a field in the class itself. There is no Dependency injection in place where I could inject my own mock of that class, which leads me to write some Integration tests for this class &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-sadsmile" alt="Sad smile" src="http://lh6.ggpht.com/-C21DtvHQ5VM/TpANXVTc68I/AAAAAAAAHVw/-tqgxCrCfmk/wlEmoticon-sadsmile2.png?imgmax=800" /&gt;&amp;#160; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now I am off to actually refactor this piece of code with my favorite tools: Visual Studio 2010 and ReSharper. I spotted more improvements on the method level. Stay tuned!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-4977660725108493459?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/XE0TnGB0ybY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/XE0TnGB0ybY/code-smell-linq-to-sql-datacontext_08.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-6s_FSDuLIbc/TpANV-bqLII/AAAAAAAAHV0/qGfU5lNQ0d4/s72-c/image%25255B7%25255D.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.gfader.com/2011/10/code-smell-linq-to-sql-datacontext_08.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-6734666212338866085</guid><pubDate>Mon, 03 Oct 2011 10:18:00 +0000</pubDate><atom:updated>2011-10-03T12:19:31.488+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">readibility</category><category domain="http://www.blogger.com/atom/ns#">coding</category><title>Code smell - LINQ to SQL Datacontext usage and more…</title><description>&lt;p&gt;I just came across some code where I needed to fix a couple of issues in. Since I am a strong proponent of &lt;a href="http://www.linkedin.com/in/petergfader" target="_blank"&gt;continuous improvement&lt;/a&gt; and &lt;a href="http://blog.gfader.com/2011/02/room-rule.html" target="_blank"&gt;refactoring&lt;/a&gt; I thought I blog about this good example.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-DK6vha9iIKU/TomL8Z0NSbI/AAAAAAAAHVc/j7UMXZUZRto/s1600-h/image%25255B4%25255D.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="image" border="0" alt="image" src="http://lh6.ggpht.com/-Go9UvNbF3Gg/TomL_lC6rwI/AAAAAAAAHVg/yBTTBpsFpJk/image_thumb%25255B2%25255D.png?imgmax=800" width="623" height="572" /&gt;&lt;/a&gt;    &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Webform that allows management of employee type history: &amp;quot;Assign&amp;quot; (Add), &amp;quot;Edit&amp;quot; (Modify) and &amp;quot;Delete&amp;quot;&lt;/p&gt;  &lt;p&gt;The purpose of this class &amp;quot;EmployeePositionAssignment&amp;quot; is: helper functions for a webpage that lets you manage the depot history of an employee&lt;/p&gt;  &lt;p&gt;Read this and find the code smell!   &lt;br /&gt;Keep in mind:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Single Responsibility Principle&lt;/li&gt;    &lt;li&gt;Functions should be small and express intent&lt;/li&gt;    &lt;li&gt;Purpose of commented code&lt;/li&gt;    &lt;li&gt;Parameter of functions&lt;/li&gt; &lt;/ul&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;
&lt;span class="kwrd"&gt;using&lt;/span&gt; NorthWind.FOMS.Domain;
&lt;span class="kwrd"&gt;using&lt;/span&gt; NorthWind.FOMS.Domain.Rules;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; NorthWind.FOMS.WebUI.DynamicData.CustomPages.EmployeePositionHistoryAssignments
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; EmployeePositionAssignment
    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; NorthWindDataContext db = &lt;span class="kwrd"&gt;new&lt;/span&gt; NorthWindDataContext();
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; TimeSpan defaultTimeSpan = &lt;span class="kwrd"&gt;new&lt;/span&gt; TimeSpan(1, 0, 0, 0);
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; DateTime defaultMaxDate = &lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(2100, 1, 1);

        &lt;span class="kwrd"&gt;public&lt;/span&gt; EmployeePositionAssignment()
        {
            db.Connection.Open();
        }

        &lt;span class="rem"&gt;//~EmployeePositionAssignment()&lt;/span&gt;
        &lt;span class="rem"&gt;//{&lt;/span&gt;
        &lt;span class="rem"&gt;//    if (db.Connection.State == ConnectionState.Open)&lt;/span&gt;
        &lt;span class="rem"&gt;//    {&lt;/span&gt;
        &lt;span class="rem"&gt;//        db.Connection.Close();&lt;/span&gt;
        &lt;span class="rem"&gt;//    }&lt;/span&gt;
        &lt;span class="rem"&gt;//    db.Dispose();&lt;/span&gt;
        &lt;span class="rem"&gt;//}&lt;/span&gt;

      
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; UpdateEmployeePositionHistory(Guid EmployeeAssignmentID, Guid EmployeeTypeID, DateTime startDate)
        {
            var _positionAssignment = GetCurrentAssignment(EmployeeAssignmentID);
            var assignmentBefore = &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetAssignStartDateBeforeEmployeePositionAssigment(_positionAssignment.EmployeeID, _positionAssignment.DateBegin);
            var assignmentAfter = &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetAssignStartDateAfterEmployeePositionAssigment(_positionAssignment.EmployeeID, _positionAssignment.DateBegin);
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (_positionAssignment != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                _positionAssignment.EmployeeTypeID = EmployeeTypeID;
                _positionAssignment.DateBegin = startDate;
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentBefore != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    assignmentBefore.DateEnd = startDate.AddDays(-1);
                }
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentAfter == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    _positionAssignment.DateEnd = defaultMaxDate;
                }
                &lt;span class="kwrd"&gt;else&lt;/span&gt;
                {
                    _positionAssignment.DateEnd = assignmentAfter.DateBegin.AddDays(-1);
                }
            }
            db.SubmitChanges();
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.ApplyPositionChangesToEmployee(_positionAssignment.EmployeeID);
            RuleManager.MarkEmployeeShiftAsDirty(_positionAssignment.EmployeeID, _positionAssignment.DateBegin, (DateTime)_positionAssignment.DateEnd);
        }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DeleteEmployeePositionHistory(Guid EmployeeAssignmentID)
        {
            var employeePositionAssignment = GetCurrentAssignment(EmployeeAssignmentID);
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (employeePositionAssignment != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                Guid EmployeeID = employeePositionAssignment.EmployeeID;

                var assignmentAfter = &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetAssignStartDateAfterEmployeePositionAssigment(employeePositionAssignment.EmployeeID, employeePositionAssignment.DateBegin);
                var assignmentBefore = &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetAssignStartDateBeforeEmployeePositionAssigment(employeePositionAssignment.EmployeeID, employeePositionAssignment.DateBegin);
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentBefore != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    assignmentBefore.DateEnd = employeePositionAssignment.DateEnd;
                }

                &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentBefore != &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; assignmentAfter != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentAfter.EmployeeTypeID == assignmentBefore.EmployeeTypeID)
                    {
                        assignmentBefore.DateEnd = assignmentAfter.DateEnd;
                        db.EmployeePositionHistoryAssignments.DeleteOnSubmit(assignmentAfter);
                    }
                }
                db.EmployeePositionHistoryAssignments.DeleteOnSubmit(employeePositionAssignment);
                db.SubmitChanges();
                &lt;span class="kwrd"&gt;this&lt;/span&gt;.ApplyPositionChangesToEmployee(EmployeeID);
                RuleManager.MarkEmployeeShiftAsDirty(EmployeeID, employeePositionAssignment.DateBegin, (employeePositionAssignment.DateEnd.HasValue ? employeePositionAssignment.DateEnd.Value : defaultMaxDate));
            }
        }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; AssignEmployeePositionHistory(Guid EmployeeID, Guid EmployeeTypeID, DateTime startDate)
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (!IsExistedEmployeePositionAssignment(EmployeeID, startDate))
            {
                var assignmentAfter = GetAssignStartDateAfterEmployeePositionAssigment(EmployeeID, startDate);
                var assignmentBefore = GetAssignStartDateBeforeEmployeePositionAssigment(EmployeeID, startDate);

                EmployeePositionHistoryAssignment epha = &lt;span class="kwrd"&gt;new&lt;/span&gt; EmployeePositionHistoryAssignment();
                epha.EmployeePositionHistoryAssignmentID = Guid.NewGuid();
                epha.EmployeeTypeID = EmployeeTypeID;
                epha.EmployeeID = EmployeeID;
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentAfter != &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; assignmentBefore != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    assignmentBefore.DateEnd = startDate.Subtract(defaultTimeSpan);
                    epha.DateBegin = assignmentBefore.DateEnd.Value.Add(defaultTimeSpan);
                    epha.DateEnd = assignmentAfter.DateBegin.Subtract(defaultTimeSpan);
                }
                &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentAfter != &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; assignmentBefore == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    epha.DateEnd = assignmentAfter.DateBegin.Subtract(defaultTimeSpan);
                    epha.DateBegin = startDate;
                }
                &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentBefore != &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp; assignmentAfter == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    epha.DateBegin = startDate;
                    assignmentBefore.DateEnd = (DateTime?)startDate.Subtract(defaultTimeSpan);
                    epha.DateEnd = defaultMaxDate;
                }
                db.EmployeePositionHistoryAssignments.InsertOnSubmit(epha);
                db.SubmitChanges();
                ApplyPositionChangesToEmployee(EmployeeID);
                RuleManager.MarkEmployeeShiftAsDirty(EmployeeID, (DateTime)epha.DateBegin, (DateTime)epha.DateEnd);
            }

        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ApplyPositionChangesToEmployee(Guid EmployeeID)
        {
            var positionChange = (from positionAssignment &lt;span class="kwrd"&gt;in&lt;/span&gt; db.EmployeePositionHistoryAssignments
                                  &lt;span class="kwrd"&gt;where&lt;/span&gt; positionAssignment.EmployeeID == EmployeeID &amp;amp;&amp;amp;
                                        positionAssignment.DateBegin &amp;lt;= DateTime.Today &amp;amp;&amp;amp; positionAssignment.DateEnd &amp;gt;= DateTime.Today
                                  select positionAssignment).FirstOrDefault();
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (positionChange != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                positionChange.Employee.EmployeeTypeID = positionChange.EmployeeTypeID;
                db.SubmitChanges();
            }
        }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsExistedEmployeePositionAssignment(Guid EmployeeID, DateTime startDate)
        {
            var positionAssignment = (from assignment &lt;span class="kwrd"&gt;in&lt;/span&gt; db.EmployeePositionHistoryAssignments
                                      &lt;span class="kwrd"&gt;where&lt;/span&gt; assignment.DateBegin == startDate
                                      &amp;amp;&amp;amp; assignment.EmployeeID == EmployeeID
                                      select assignment).FirstOrDefault();

            &lt;span class="kwrd"&gt;return&lt;/span&gt; positionAssignment == &lt;span class="kwrd"&gt;null&lt;/span&gt; ? &lt;span class="kwrd"&gt;false&lt;/span&gt; : &lt;span class="kwrd"&gt;true&lt;/span&gt;;
        }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; ValidateStartDate(Guid EmployeeID, DateTime startDate)
        {
            &lt;span class="rem"&gt;//Dev1: Fixed. don't allow crossover date&lt;/span&gt;
            var assignmentAfter = GetAssignStartDateAfterEmployeePositionAssigment(EmployeeID, startDate);
            var assignmentBefore = GetAssignStartDateBeforeEmployeePositionAssigment(EmployeeID, startDate);
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentAfter != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentAfter.DateBegin &amp;lt;= startDate)
                {
                    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
                }
            }

            &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentBefore != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignmentBefore.DateBegin &amp;gt;= startDate)
                {
                    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
                }
            }
            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;
        }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; ValidateEmployeeType(Guid EmployeeID, Guid EmployeeTypeID, DateTime startDate)
        {
            var assignmentAfter = GetAssignStartDateAfterEmployeePositionAssigment(EmployeeID, startDate);
            var assignmentBefore = GetAssignStartDateBeforeEmployeePositionAssigment(EmployeeID, startDate);
            &lt;span class="kwrd"&gt;if&lt;/span&gt; ((assignmentAfter != &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; assignmentAfter.EmployeeTypeID == EmployeeTypeID) || (assignmentBefore != &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; assignmentBefore.EmployeeTypeID == EmployeeTypeID))
            {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            }
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
            {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            }
        }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; ValidationOnDeletedAssignment(Guid EmployeeID)
        {
            &lt;span class="rem"&gt;//Dev2: Fixed. Don't allow to delete the last record.&lt;/span&gt;
            &lt;span class="kwrd"&gt;int&lt;/span&gt; count = (from assignment &lt;span class="kwrd"&gt;in&lt;/span&gt; db.EmployeePositionHistoryAssignments
                         &lt;span class="kwrd"&gt;where&lt;/span&gt; assignment.EmployeeID == EmployeeID
                         select assignment).Count();
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (count &amp;gt; 1)
            {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            }
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
            {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            }

        }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; VidationDateBeginOnUpdatedAssingment(Guid employeeAssingmentID, DateTime startDate)
        {
            &lt;span class="rem"&gt;//Dev1: the begin date of the first record should always be in the past&lt;/span&gt;
            var positionAssignment = (from assignment &lt;span class="kwrd"&gt;in&lt;/span&gt; db.EmployeePositionHistoryAssignments
                                      &lt;span class="kwrd"&gt;where&lt;/span&gt; assignment.EmployeePositionHistoryAssignmentID == employeeAssingmentID
                                      select assignment).FirstOrDefault();
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (positionAssignment != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                var firstAssignment = &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetFirstPositionHistoryAssignment(positionAssignment.EmployeeID);
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (firstAssignment.EmployeePositionHistoryAssignmentID == positionAssignment.EmployeePositionHistoryAssignmentID)
                {
                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (startDate &amp;gt; DateTime.Today)
                    {
                        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
                    }
                }
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            }
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
            {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            }
        }


        &lt;span class="rem"&gt;// ---  SNIP SNIP SNIP  more of code godness&lt;/span&gt;


        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; ApplyDepotChangesToShifts(NorthWindDataContext dataContext, EmployeeDepotHistoryAssignment assignment, &lt;span class="kwrd"&gt;bool&lt;/span&gt; isDelete, DateTime originalDateBegin)
        {

            var existingSameBeforeOne = dataContext.EmployeeDepotHistoryAssignments.Where(h =&amp;gt; h.DateBegin &amp;lt; assignment.DateBegin
                                                                                            &amp;amp;&amp;amp; h.EmployeeID == assignment.EmployeeID).OrderByDescending(h =&amp;gt; h.DateBegin).FirstOrDefault();
            Guid depotid = assignment.DepotID;
            DateTime dateBegin = assignment.DateBegin;
            DateTime dateEnd = assignment.DateEnd.HasValue ? assignment.DateEnd.Value.AddDays(1) : DateTime.MaxValue;
            Guid employeeID = assignment.EmployeeID;
            Guid previouseDepotID = existingSameBeforeOne == &lt;span class="kwrd"&gt;null&lt;/span&gt; ? Guid.Empty : existingSameBeforeOne.DepotID;
            DateTime previouseDateEnd = existingSameBeforeOne == &lt;span class="kwrd"&gt;null&lt;/span&gt; ? originalDateBegin : (existingSameBeforeOne.DateEnd.HasValue ? existingSameBeforeOne.DateEnd.Value.AddDays(1) : DateTime.MaxValue);

            &lt;span class="kwrd"&gt;int&lt;/span&gt; affectedShifts = 0;
            &lt;span class="rem"&gt;//dataContext.MoveShifts(assignment.DepotID, previouseDepotID, dateBegin, dateEnd, employeeID);&lt;/span&gt;

            &lt;span class="kwrd"&gt;if&lt;/span&gt; (isDelete)
            {
                affectedShifts = MoveShifts(dataContext, assignment.DepotID, previouseDepotID, dateBegin, dateEnd, employeeID);

                &lt;span class="kwrd"&gt;if&lt;/span&gt; (existingSameBeforeOne != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    existingSameBeforeOne.DateEnd = assignment.DateEnd;
                }
                dataContext.EmployeeDepotHistoryAssignments.DeleteOnSubmit(assignment);

                dataContext.SubmitChanges();

                RuleManager.MarkEmployeeShiftAsDirty(employeeID, dateBegin, dateEnd);
            }
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
            {
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (existingSameBeforeOne != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    existingSameBeforeOne.DateEnd = assignment.DateBegin.AddDays(-1);
                }
                dataContext.SubmitChanges();

                &lt;span class="kwrd"&gt;if&lt;/span&gt; (assignment.DateBegin &amp;lt;= previouseDateEnd)
                {
                    &lt;span class="rem"&gt;//if (assignment.DateBegin &amp;lt; DateTime.Today.AddDays(1))&lt;/span&gt;
                    &lt;span class="rem"&gt;//{&lt;/span&gt;
                    affectedShifts = MoveShifts(dataContext, previouseDepotID, assignment.DepotID,
                            assignment.DateBegin, previouseDateEnd, employeeID);
                    &lt;span class="rem"&gt;//}&lt;/span&gt;

                    &lt;span class="rem"&gt;//if (assignment.DateBegin &amp;lt; DateTime.Today.AddDays(1))&lt;/span&gt;
                    &lt;span class="rem"&gt;//{&lt;/span&gt;
                    RuleManager.MarkEmployeeShiftAsDirty(employeeID, assignment.DateBegin, previouseDateEnd);
                    &lt;span class="rem"&gt;//}&lt;/span&gt;
                }
                &lt;span class="kwrd"&gt;else&lt;/span&gt;
                {
                    &lt;span class="rem"&gt;//if (assignment.DateBegin &amp;lt; DateTime.Today.AddDays(1))&lt;/span&gt;
                    &lt;span class="rem"&gt;//{&lt;/span&gt;
                    affectedShifts = MoveShifts(dataContext, assignment.DepotID, previouseDepotID,
                        previouseDateEnd, assignment.DateBegin, employeeID);
                    &lt;span class="rem"&gt;//}                    &lt;/span&gt;

                    &lt;span class="rem"&gt;//if (assignment.DateBegin &amp;lt; DateTime.Today.AddDays(1))&lt;/span&gt;
                    &lt;span class="rem"&gt;//{&lt;/span&gt;
                    RuleManager.MarkEmployeeShiftAsDirty(employeeID, previouseDateEnd.AddDays(-1), assignment.DateBegin.AddDays(1));
                    &lt;span class="rem"&gt;//}&lt;/span&gt;
                }

            }

            &lt;span class="rem"&gt;//Update employee's deopt&lt;/span&gt;
            var currentAssignment = dataContext.EmployeeDepotHistoryAssignments.Where(h =&amp;gt; h.DateBegin &amp;lt;= DateTime.Today &amp;amp;&amp;amp; (h.DateEnd.HasValue ? h.DateEnd.Value : DateTime.MaxValue) &amp;gt; DateTime.Today
                                                                                            &amp;amp;&amp;amp; h.EmployeeID == employeeID).FirstOrDefault();
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (currentAssignment != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                Employee emp = dataContext.Employees.Where(e =&amp;gt; e.EmployeeID == employeeID).FirstOrDefault();
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (emp != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    emp.Depot = dataContext.Depots.Single(d =&amp;gt; d.DepotID == currentAssignment.DepotID);
                    &lt;span class="rem"&gt;//emp.DepotID = currentAssignment.DepotID;&lt;/span&gt;
                    dataContext.SubmitChanges();
                }
            }

            &lt;span class="kwrd"&gt;return&lt;/span&gt; affectedShifts;
        }


        &lt;span class="rem"&gt;// SNIP SNIP SNIP  -&amp;gt; I spare you the rest&lt;/span&gt;

    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;I post the refactored code file in the next days. You can and should read the book: &lt;a href="http://blog.objectmentor.com/articles/2008/04/08/clean-code-whew" target="_blank"&gt;&amp;quot;Clean Code&amp;quot;&lt;/a&gt; from Uncle Bob in the meantime &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh6.ggpht.com/-rhLOFPBytXc/TomMAOX8krI/AAAAAAAAHVk/zJDZNqFZQNI/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800" /&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-6734666212338866085?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/KwyaOTNVG4U" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/KwyaOTNVG4U/code-smell-linq-to-sql-datacontext.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-Go9UvNbF3Gg/TomL_lC6rwI/AAAAAAAAHVg/yBTTBpsFpJk/s72-c/image_thumb%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.gfader.com/2011/10/code-smell-linq-to-sql-datacontext.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-1225422706933323812</guid><pubDate>Tue, 30 Aug 2011 10:44:00 +0000</pubDate><atom:updated>2011-08-30T12:44:00.501+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">sql server</category><category domain="http://www.blogger.com/atom/ns#">databinding</category><category domain="http://www.blogger.com/atom/ns#">database</category><title>ORM: Should I go Micro?</title><description>&lt;p&gt;We had an interesting internal discussion about ORMs (&lt;a href="http://msdn.microsoft.com/en-us/library/bb425822.aspx"&gt;Linq to SQL&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx"&gt;Entity Framework&lt;/a&gt;, …) and MicroORMs (&lt;a href="http://code.google.com/p/dapper-dot-net/"&gt;Dapper&lt;/a&gt;, &lt;a href="https://github.com/robconery/massive"&gt;Massive&lt;/a&gt;, &lt;a href="http://www.toptensoftware.com/petapoco/"&gt;PetaPoco&lt;/a&gt;, …). This discussion led me to think about: When should I use a MicroORM?&lt;/p&gt;  &lt;p&gt;I would go for the approach: Use both (MicroORM and BigORM) and use them where they make sense.&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;A possible decision approach: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Start with Entity Framework (Big ORM) &lt;/li&gt;    &lt;li&gt;Measure performance (as you should do anyway, see my posts &lt;u&gt;&lt;a href="http://blog.gfader.com/2011/07/website-check-list-part-1-aspnet-4.html"&gt;http://blog.gfader.com/2011/07/website-check-list-part-1-aspnet-4.html&lt;/a&gt; &lt;/u&gt;) &lt;/li&gt;    &lt;li&gt;Find bottlenecks &lt;/li&gt;    &lt;li&gt;Entity Framework is your bottleneck? --&amp;gt; replace with a MicroORM      &lt;br /&gt;&lt;i&gt;I can almost guarantee you that EF is *&lt;b&gt;not&lt;/b&gt;* your bottleneck&lt;/i&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;This is how &lt;a href="http://samsaffron.com/"&gt;Sam Saffron&lt;/a&gt; came to the conclusion to write Dapper in the first place, as per his blog post: &lt;a href="http://samsaffron.com/archive/2011/03/30/How+I+learned+to+stop+worrying+and+write+my+own+ORM"&gt;http://samsaffron.com/archive/2011/03/30/How+I+learned+to+stop+worrying+and+write+my+own+ORM&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;     &lt;br /&gt;Things to consider before going Micro: &lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Going to these MicroORM's we lose a lot of features that many of us loved to have, e.g.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;b&gt;Compile time evaluation of queries&lt;/b&gt;       &lt;br /&gt;      &lt;br /&gt;&amp;#160; var post = connection.ExecuteQuery&amp;lt;Post&amp;gt;(&lt;font style="background-color: #ffff00"&gt;&amp;quot;select * from Posts where Id = @Id&amp;quot;&lt;/font&gt;, new {Id = 1}).First();       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;b&gt;Intellisense &lt;/b&gt;that comes with LINQ       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&amp;quot;&lt;b&gt;Unit of Work&lt;/b&gt;&amp;quot; pattern (Tracking of entities) - Relevant for state full applications (WPF and Windows Forms)       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;No &amp;quot;&lt;b&gt;Map of Identities&lt;/b&gt;&amp;quot; - Knowing about object identities       &lt;br /&gt;Ensures that each object gets loaded only once by keeping every loaded object in a map. Looks up objects using the map when referring to them &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;If you don't care about the above features and you want &lt;strong&gt;easy deployment&lt;/strong&gt; (1 file drop)&lt;strong&gt; &lt;/strong&gt;and &lt;strong&gt;best performance &lt;/strong&gt;out of database-access go Micro!&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-1225422706933323812?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/tXmAMZrP7O8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/tXmAMZrP7O8/orm-should-i-go-micro.html</link><author>noreply@blogger.com (Peter Gfader)</author><thr:total>1</thr:total><feedburner:origLink>http://blog.gfader.com/2011/08/orm-should-i-go-micro.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-8914865138841428911</guid><pubDate>Sat, 27 Aug 2011 09:44:00 +0000</pubDate><atom:updated>2011-11-14T22:13:21.891+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">deployment</category><category domain="http://www.blogger.com/atom/ns#">TFS</category><category domain="http://www.blogger.com/atom/ns#">vs2010</category><title>It's official: Manual deployments are BAD, Automated Deployments are a WIN!</title><description>&lt;p&gt;&lt;span class="red"&gt;*Updated*&lt;/span&gt; 14 November 2011: Video is not on &lt;a href="http://vimeo.com/27963161"&gt;vimeo&lt;/a&gt; anymore but on &lt;a href="http://tv.ssw.com/245/peter-gfader-deployment-continuous-delivery-with-tfs"&gt;tv.ssw.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The video video recording of my talk &lt;a href="http://blog.gfader.com/2011/07/continuous-delivery-with-tfs-msbuild.html" target="_blank"&gt;&amp;quot;Continuous Delivery with TFS, msbuild and msdeploy&amp;quot;&lt;/a&gt; is finally online.     &lt;br /&gt;&lt;em&gt;     &lt;br /&gt;Please say &lt;/em&gt;&lt;a href="mailto:RajDhatt*ssw.com.au?Subject=THANKS%20for%20the%20recording%20of%20Peter%20Gfader%20Continuous%20Delivery" target="_blank"&gt;&lt;em&gt;&amp;quot;Thanx&amp;quot; to Raj&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.      &lt;br /&gt;&lt;/em&gt;&lt;em&gt;Thanks to Adam Cogan for introducing me so nicely, he almost got my last name right this time &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh5.ggpht.com/-AGTm1NNzw-g/Tli8dm9u06I/AAAAAAAAHVM/eDJPAlzumPw/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800" /&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;The video is on &lt;a href="http://tv.ssw.com/245/peter-gfader-deployment-continuous-delivery-with-tfs"&gt;tv.ssw.com&lt;/a&gt; -&amp;gt; which just launched BTW and is a great learning resource)&amp;#160;&amp;#160; &lt;br /&gt;and embedded here     &lt;br /&gt;&lt;/p&gt;  &lt;div id="wistia_537216_social_226"&gt;&lt;object width="770" height="430" id="wistia_537216" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"&gt;&lt;param name="movie" value="http://embed.wistia.com/flash/embed_player_v1.2.swf" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="wmode" value="opaque" /&gt;&lt;param name="flashvars" value="videoUrl=http://embed.wistia.com/deliveries/1277381966eb6ccec76e2c18a7150ac2cd9ea6e8.bin&amp;amp;stillUrl=http://embed.wistia.com/deliveries/b522631eac65a8142082deba72874f2a943b61d7.bin&amp;amp;unbufferedSeek=true&amp;amp;controlsVisibleOnLoad=false&amp;amp;autoPlay=false&amp;amp;endVideoBehavior=default&amp;amp;playButtonVisible=true&amp;amp;embedServiceURL=http://distillery.wistia.com/x&amp;amp;accountKey=wistia-production_8394&amp;amp;mediaID=wistia-production_537216&amp;amp;mediaDuration=4055.6&amp;amp;hdUrl=http://embed.wistia.com/deliveries/1277381966eb6ccec76e2c18a7150ac2cd9ea6e8.bin" /&gt;&lt;embed src="http://embed.wistia.com/flash/embed_player_v1.2.swf" width="770" height="430" name="wistia_537216" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" wmode="opaque" flashvars="videoUrl=http://embed.wistia.com/deliveries/1277381966eb6ccec76e2c18a7150ac2cd9ea6e8.bin&amp;stillUrl=http://embed.wistia.com/deliveries/b522631eac65a8142082deba72874f2a943b61d7.bin&amp;unbufferedSeek=true&amp;controlsVisibleOnLoad=false&amp;autoPlay=false&amp;endVideoBehavior=default&amp;playButtonVisible=true&amp;embedServiceURL=http://distillery.wistia.com/x&amp;accountKey=wistia-production_8394&amp;mediaID=wistia-production_537216&amp;mediaDuration=4055.6&amp;hdUrl=http://embed.wistia.com/deliveries/1277381966eb6ccec76e2c18a7150ac2cd9ea6e8.bin"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;script src="http://embed.wistia.com/embeds/v.js" charset="ISO-8859-1"&gt;&lt;/script&gt;&lt;script&gt;if(!navigator.mimeTypes['application/x-shockwave-flash'] || navigator.userAgent.match(/Android/i)!==null)Wistia.VideoEmbed('wistia_537216',1280,720,{videoUrl:'http://embed.wistia.com/deliveries/bca30659438772f335f3e72a6c1dcc7f80c3dd88.bin',stillUrl:'http://embed.wistia.com/deliveries/b522631eac65a8142082deba72874f2a943b61d7.bin',distilleryUrl:'http://distillery.wistia.com/x',accountKey:'wistia-production_8394',mediaId:'wistia-production_537216',mediaDuration:4055.6})&lt;/script&gt;&lt;/div&gt; &lt;script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"&gt;&lt;/script&gt;&lt;script type="text/javascript" src="http://static.wistia.com/javascripts/jquery/jquery.injectCss.min.js"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;var socialJQuery = jQuery.noConflict(true);&lt;/script&gt;&lt;script type="text/javascript" src="http://static.wistia.com/socialbar/socialbar.js"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;new SocialBar("wistia_537216_social_226", {buttons:["twitter","facebook","embed","googleplusone"], badgeUrl:"http://wistia.com", embedCode:"%3Cobject%20width%3D%221280%22%20height%3D%22720%22%20id%3D%22wistia_537216%22%20classid%3D%22clsid%3AD27CDB6E-AE6D-11cf-96B8-444553540000%22%3E%3Cparam%20name%3D%22movie%22%20value%3D%22http%3A//embed.wistia.com/flash/embed_player_v1.2.swf%22/%3E%3Cparam%20name%3D%22allowfullscreen%22%20value%3D%22true%22/%3E%3Cparam%20name%3D%22allowscriptaccess%22%20value%3D%22always%22/%3E%3Cparam%20name%3D%22wmode%22%20value%3D%22opaque%22/%3E%3Cparam%20name%3D%22flashvars%22%20value%3D%22videoUrl%3Dhttp%3A//embed.wistia.com/deliveries/1277381966eb6ccec76e2c18a7150ac2cd9ea6e8.bin%26stillUrl%3Dhttp%3A//embed.wistia.com/deliveries/b522631eac65a8142082deba72874f2a943b61d7.bin%26unbufferedSeek%3Dtrue%26controlsVisibleOnLoad%3Dfalse%26autoPlay%3Dfalse%26endVideoBehavior%3Ddefault%26playButtonVisible%3Dtrue%26embedServiceURL%3Dhttp%3A//distillery.wistia.com/x%26accountKey%3Dwistia-production_8394%26mediaID%3Dwistia-production_537216%26mediaDuration%3D4055.6%26hdUrl%3Dhttp%3A//embed.wistia.com/deliveries/1277381966eb6ccec76e2c18a7150ac2cd9ea6e8.bin%22/%3E%3Cembed%20src%3D%22http%3A//embed.wistia.com/flash/embed_player_v1.2.swf%22%20width%3D%221280%22%20height%3D%22720%22%20name%3D%22wistia_537216%22%20type%3D%22application/x-shockwave-flash%22%20allowfullscreen%3D%22true%22%20allowscriptaccess%3D%22always%22%20wmode%3D%22opaque%22%20flashvars%3D%22videoUrl%3Dhttp%3A//embed.wistia.com/deliveries/1277381966eb6ccec76e2c18a7150ac2cd9ea6e8.bin%26stillUrl%3Dhttp%3A//embed.wistia.com/deliveries/b522631eac65a8142082deba72874f2a943b61d7.bin%26unbufferedSeek%3Dtrue%26controlsVisibleOnLoad%3Dfalse%26autoPlay%3Dfalse%26endVideoBehavior%3Ddefault%26playButtonVisible%3Dtrue%26embedServiceURL%3Dhttp%3A//distillery.wistia.com/x%26accountKey%3Dwistia-production_8394%26mediaID%3Dwistia-production_537216%26mediaDuration%3D4055.6%26hdUrl%3Dhttp%3A//embed.wistia.com/deliveries/1277381966eb6ccec76e2c18a7150ac2cd9ea6e8.bin%22%3E%3C/embed%3E%3C/object%3E%3Cscript%20src%3D%22http%3A//embed.wistia.com/embeds/v.js%22%20charset%3D%22ISO-8859-1%22%3E%3C/script%3E%3Cscript%3Eif%28%21navigator.mimeTypes%5B%27application/x-shockwave-flash%27%5D%20%7C%7C%20navigator.userAgent.match%28/Android/i%29%21%3D%3Dnull%29Wistia.VideoEmbed%28%27wistia_537216%27%2C1280%2C720%2C%7BvideoUrl%3A%27http%3A//embed.wistia.com/deliveries/bca30659438772f335f3e72a6c1dcc7f80c3dd88.bin%27%2CstillUrl%3A%27http%3A//embed.wistia.com/deliveries/b522631eac65a8142082deba72874f2a943b61d7.bin%27%2CdistilleryUrl%3A%27http%3A//distillery.wistia.com/x%27%2CaccountKey%3A%27wistia-production_8394%27%2CmediaId%3A%27wistia-production_537216%27%2CmediaDuration%3A4055.6%7D%29%3C/script%3E"})&lt;/script&gt;  &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: &lt;a href="http://tv.ssw.com/245/peter-gfader-deployment-continuous-delivery-with-tfs" target="_blank"&gt;Video recording of Continuous Delivery - SSW Sydney User Group - Peter Gfader&lt;/a&gt;   &lt;br /&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Have fun and &lt;a href="mailto:peter@gfader.com" target="_blank"&gt;send me some feedback&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;My related blog posts about Continuous Delivery&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The &lt;a href="http://blog.gfader.com/2011/06/tired-of-manual-deployments.html" target="_blank"&gt;&lt;strong&gt;pain &lt;/strong&gt;with deployments can be found in this blog post&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.gfader.com/2010/12/do-you-automate-your-deployment-process.html" target="_blank"&gt;&lt;strong&gt;How to &lt;/strong&gt;and some &lt;strong&gt;tips and tricks &lt;/strong&gt;for TFS2010 regarding deployment&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The &lt;a href="http://www.slideshare.net/PeterGfader/continuous-delivery-with-tfs-msbuild-msdeploy" target="_blank"&gt;slides are on SlideShare&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-8914865138841428911?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/RiDTBRzRZFk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/RiDTBRzRZFk/it-official-manual-deployments-are-bad.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-AGTm1NNzw-g/Tli8dm9u06I/AAAAAAAAHVM/eDJPAlzumPw/s72-c/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://blog.gfader.com/2011/08/it-official-manual-deployments-are-bad.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-417962794423268681</guid><pubDate>Wed, 10 Aug 2011 16:38:00 +0000</pubDate><atom:updated>2011-12-11T15:08:03.969+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">asp.net</category><title>Part 3 ASP.NET - 9 User Experience tips before going live</title><description>&lt;strong&gt;Index of series    &lt;br /&gt;&lt;/strong&gt;&lt;a href="http://blog.gfader.com/2011/07/website-check-list-part-1-aspnet-4.html"&gt;Part 1 ASP.NET - 4 essential steps before going live &lt;/a&gt;  &lt;br /&gt;&lt;a href="http://blog.gfader.com/2011/07/website-check-list-part-2-aspnet-8.html"&gt;Part 2 ASP.NET - 8 performance tips before going live&lt;/a&gt;   &lt;br /&gt;&lt;a href="http://blog.gfader.com/2011/08/part-3-aspnet-8-user-experience-tips.html" target="_blank"&gt;Part 3 ASP.NET - 9 User Experience tips before going live (*this post*)&lt;/a&gt;   &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The last part of this series focuses on User Experience (UX). From &lt;a href="http://en.wikipedia.org/wiki/User_experience" target="_blank"&gt;Wikipedia&lt;/a&gt; we learn that User Experience stands on 3 pillars: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Look &lt;/li&gt;    &lt;li&gt;Usability &lt;/li&gt;    &lt;li&gt;Feel &lt;/li&gt; &lt;/ol&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;Our web application has to look good, be usable and feel alright in order to give a good user experience. &lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Looks" border="0" alt="Looks" src="http://lh5.ggpht.com/-9CO37arhyLw/TkKz5c5dp5I/AAAAAAAAHPk/gbaOx-SVav8/image%25255B13%25255D.png?imgmax=800" width="100" height="124" /&gt;     &lt;br /&gt;#1 The first point about &amp;quot;looking good&amp;quot; is very subjective so I wont comment on that one, especially because &amp;quot;Beauty is in the eye of the beholder&amp;quot;&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Usability" border="0" alt="Usability" src="http://lh5.ggpht.com/--CtQ4gvVygA/TkKz500LXrI/AAAAAAAAHPo/tUNg7FmkrTQ/image%25255B8%25255D.png?imgmax=800" width="100" height="131" /&gt;     &lt;br /&gt;#2 &amp;quot;&lt;a href="http://en.wikipedia.org/wiki/Usability" target="_blank"&gt;Usability&lt;/a&gt;&amp;quot; is about how easy people can achieve a particular goal on your website. E.g. &amp;quot;Sign up to the newsletter&amp;quot;, or &amp;quot;Find contact information (phone nr) about your company&amp;quot;&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Feel" border="0" alt="Feel" src="http://lh5.ggpht.com/-69Zl9VcnOvQ/TkKz6btdbNI/AAAAAAAAHPs/ce74QHfop5o/image%25255B18%25255D.png?imgmax=800" width="151" height="100" /&gt;     &lt;br /&gt;#3 The &amp;quot;Feel&amp;quot; of a site refers to making the site feel alive, responsive and react fast.     &lt;br /&gt;Make your website interact with the user, give instant feedback and make sure it is a joy to use.&lt;/p&gt;  &lt;p&gt;These 3 aspects are hard to measure and improve, but a good start is to just ask different people on their opinions. Ask people on the hallway:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Do you like my website? &lt;/li&gt;    &lt;li&gt;What is good? What is bad? What could be improved? &lt;/li&gt;    &lt;li&gt;Can you find the newsletter on the site? How do you sign up? &lt;/li&gt;    &lt;li&gt;Does the site respond fast enough? &lt;/li&gt;    &lt;li&gt;Do you understand the warning or error message? &lt;/li&gt;    &lt;li&gt;Do we actually need an error message? &lt;/li&gt;    &lt;li&gt;… &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Here some tips on how to improve User experience&lt;/p&gt;  &lt;h4&gt;#1 Run browsershots on your start page and make sure that the screens look similar&lt;/h4&gt;  &lt;p&gt;Go to &lt;a title="http://browsershots.org/" href="http://browsershots.org/" target="_blank"&gt;http://browsershots.org/&lt;/a&gt; and knock in your homepage URL. Wait a couple of minutes until you get some results back and compare the different screens. Make sure they look at least similar on different browsers.     &lt;br /&gt;Note: If you use any JavaScript or plugins (e.g. Silverlight or Flash), Browsershots won't help you much, because it is not executing client side stuff.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-2BBf1l-qfeM/TkKz9aP55WI/AAAAAAAAHPw/j3avLPZ7mNo/s1600-h/image%25255B23%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Sample page on browsershots" border="0" alt="Sample page on browsershots" src="http://lh6.ggpht.com/-onlyKRUiKDY/TkKz-Ix75EI/AAAAAAAAHP0/EFDghoY5X-4/image_thumb%25255B9%25255D.png?imgmax=800" width="225" height="244" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Screenshots of sample page on different browsers and operating system combinations from browsershots&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;#2 Install and test your site on at least the top 4 browsers (more if you have time)&lt;/h4&gt;  &lt;p&gt;Look at Google Analytics (that you have added on your site since you have followed &lt;a href="http://blog.gfader.com/2011/07/website-check-list-part-2-aspnet-8.html" target="_blank"&gt;these performance tips&lt;/a&gt;) and make sure to test your site with the major browsers&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/-4uVUjdWwgzM/TkKz-yIxneI/AAAAAAAAHP4/FXs2o-j9_lw/s1600-h/image%25255B29%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Google Analytics: Go to &amp;quot;Visitors&amp;quot; | &amp;quot;Browser Capabilities&amp;quot; | &amp;quot;Browsers&amp;quot; to find out your users browsers" border="0" alt="Google Analytics: Go to &amp;quot;Visitors&amp;quot; | &amp;quot;Browser Capabilities&amp;quot; | &amp;quot;Browsers&amp;quot; to find out your users browsers" src="http://lh4.ggpht.com/-3iIdtg_JjkA/TkKz_tmXDWI/AAAAAAAAHP8/yE194mtQlbY/image_thumb%25255B13%25255D.png?imgmax=800" width="640" height="163" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Google Analytics: Go to &amp;quot;Visitors&amp;quot; | &amp;quot;Browser Capabilities&amp;quot; | &amp;quot;Browsers&amp;quot; to find out your users browsers&lt;/p&gt;  &lt;p&gt;Test at least with &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Internet Explorer (&lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyId=21EABB90-958F-4B64-B5F1-73D0A413C8EF&amp;amp;displaylang=en"&gt;Microsoft provides some Virtual PC VHDs for testing different versions of IE&lt;/a&gt;) &lt;/li&gt;    &lt;li&gt;Firefox &lt;/li&gt;    &lt;li&gt;Chrome &lt;/li&gt;    &lt;li&gt;Safari &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;#3 Check your content: HTML page titles&lt;/h4&gt;  &lt;p&gt;You should really care about content and Search Engine Optimization (SEO) these days, so make sure to have nice page titles&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;#4 Check your content: HTML description&lt;/h4&gt;  &lt;p&gt;The description tag content is the one that shows up in the search results in the major search engines.&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-7kpIRy6kcx8/TkK0AH1CSGI/AAAAAAAAHQA/ajN7VYIgkdA/image%25255B35%25255D.png?imgmax=800" width="785" height="220" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Google shows the HTML meta description in the search result&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;meta&lt;/span&gt; &lt;span class="attr"&gt;content&lt;/span&gt;&lt;span class="kwrd"&gt;='My blog with my daily problems and solutions about .NET, C#, Visual Studio, Clean Code Development, Testing and Performance.'&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;='description'&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Meta tag for my blog&lt;/p&gt;

&lt;p&gt;Make sure to include a nice meta description for all your pages!&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;#5 Have a nice &amp;quot;About Us&amp;quot; and &amp;quot;Contact Us&amp;quot; page&lt;/h4&gt;

&lt;p&gt;Make sure to include all info about you and make sure that these pages are easy to find. We want people easily get in contact with us. We have nothing to hide! 
  &lt;br /&gt;This is a good candidate for some &lt;a href="http://www.joelonsoftware.com/articles/fog0000000043.html" target="_blank"&gt;usability hallway testing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;#6 Have a usable error page&lt;/h4&gt;

&lt;p&gt;It's important for users to recover quickly when things doesn't turn out the way we intend to. It's also a good way to show that you care about your product and service. When exception occurs, pick them up, explain what just happened and offer some direction. This can be your homepage, an index, or a starting point of a critical path. &lt;/p&gt;

&lt;p&gt;Some developers/designers may want to get creative. Showing the human side of your product and/or service is a nice relieve and a great palate-cleanser. However, it is important that the design fit the purpose and not used as a playground.&lt;/p&gt;

&lt;p&gt;These links discuss 404-page but the principle is applicable for any type of error page: 
  &lt;br /&gt;&lt;a href="http://www.uxbooth.com/blog/5-tips-to-make-your-404-page-more-usable/"&gt;http://www.uxbooth.com/blog/5-tips-to-make-your-404-page-more-usable/&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://www.alistapart.com/articles/perfect404/"&gt;http://www.alistapart.com/articles/perfect404/&lt;/a&gt; 

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You still have more time before you go live?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;#7 Is your HTML and CSS valid?&lt;/h4&gt;

&lt;p&gt;Validate and check your HTML and CSS with W3C validator. 
  &lt;br /&gt;&lt;a href="http://validator.w3.org/"&gt;http://validator.w3.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even better, you should write a test that does this automatically on each check in, by following Damian Edwards blog post about &lt;a href="http://damianedwards.wordpress.com/2008/10/06/adding-html-validity-checking-to-your-aspnet-web-site-via-unit-tests/" target="_blank"&gt;&amp;quot;Adding HTML validity checking to your ASP.NET web site via unit tests&amp;quot;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;#8 ASP.NET MVC only: Do you know the internals of your MVC app?&lt;/h4&gt;

&lt;p&gt;Check what your site is doing with &amp;quot;Glimpse&amp;quot; and &amp;quot;MVC Mini Profiler&amp;quot;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://getglimpse.com/"&gt;http://getglimpse.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://code.google.com/p/mvc-mini-profiler/"&gt;http://code.google.com/p/mvc-mini-profiler/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;#9 Have drinks ready for your launch day!&lt;/h4&gt;

&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Prosecco" border="0" alt="Prosecco" src="http://lh4.ggpht.com/-AyI87ikZGFM/TkK0Cn4fwiI/AAAAAAAAHQE/rtK6xW20YkM/image%25255B41%25255D.png?imgmax=800" width="610" height="259" /&gt; 

  &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Cool drinks make your team happy!&lt;/p&gt;

&lt;p&gt;All the best for your website launch! 
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;More tips before going live &lt;/p&gt;

&lt;p&gt;&lt;a title="http://www.smashingmagazine.com/2009/04/07/15-essential-checks-before-launching-your-website/" href="http://www.smashingmagazine.com/2009/04/07/15-essential-checks-before-launching-your-website/"&gt;http://www.smashingmagazine.com/2009/04/07/15-essential-checks-before-launching-your-website/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.webdistortion.com/2008/03/20/a-website-checklist-20-things-to-check-before-going-live/" target="_blank"&gt;http://blog.webdistortion.com/2008/03/20/a-website-checklist-20-things-to-check-before-going-live/&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a title="http://www.egov.vic.gov.au/victorian-government-resources/website-practice-victoria/search-engines-victoria/seo-checklist-for-a-new-victorian-government-website-to-go-live.html&amp;#13;&amp;#10;" href="http://www.egov.vic.gov.au/victorian-government-resources/website-practice-victoria/search-engines-victoria/seo-checklist-for-a-new-victorian-government-website-to-go-live.html"&gt;http://www.egov.vic.gov.au/victorian-government-resources/website-practice-victoria/search-engines-victoria/seo-checklist-for-a-new-victorian-government-website-to-go-live.html&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Coming up: Estimate and simulate load on your website to be ready for the launch day!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-417962794423268681?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/G-I9EW15dv0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/G-I9EW15dv0/part-3-aspnet-8-user-experience-tips.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-9CO37arhyLw/TkKz5c5dp5I/AAAAAAAAHPk/gbaOx-SVav8/s72-c/image%25255B13%25255D.png?imgmax=800" height="72" width="72" /><thr:total>5</thr:total><feedburner:origLink>http://blog.gfader.com/2011/08/part-3-aspnet-8-user-experience-tips.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-4162192846267279067</guid><pubDate>Fri, 05 Aug 2011 13:49:00 +0000</pubDate><atom:updated>2011-08-10T08:31:03.031+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">testing</category><category domain="http://www.blogger.com/atom/ns#">debugging</category><title>Avoid the debugger like the pest</title><description>&lt;p&gt;&lt;em&gt;In this post I want to explain why I don't like debugging, and prefer instead to use unit testing where I work in tiny sections.      &lt;br /&gt;&lt;/em&gt;&lt;em&gt;To put this post in context, can first I encourage you to read: &lt;/em&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;em&gt;My previous post about &lt;/em&gt;&lt;a href="http://blog.gfader.com/2011/08/vs2010-debugging-not-working.html" target="_blank"&gt;&lt;em&gt;&amp;quot;Debugging not working&amp;quot;&lt;/em&gt;&lt;/a&gt;&lt;em&gt; where I explain a debugging problem with Visual Studio 2010, and&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://simpleprogrammer.com/2011/06/17/the-debugger-mindset/" target="_blank"&gt;&lt;em&gt;John about the debugger mind set&lt;/em&gt;&lt;/a&gt;&lt;em&gt; where he talks about a common developer mindset on using the debugger too often&lt;/em&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;em&gt;I wait here in the meantime &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh6.ggpht.com/-drLIChOMG8A/Tjv0fSLV6MI/AAAAAAAAHN8/WnObBV3bccA/wlEmoticon-winkingsmile2.png?imgmax=800" /&gt; &lt;/em&gt;&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;As I said in the other &lt;a href="http://blog.gfader.com/2011/08/vs2010-debugging-not-working.html" target="_blank"&gt;blog post about the debugger not working&lt;/a&gt;: The only reason that I see in using the debugger is: &lt;strong&gt;inspecting state&lt;/strong&gt;. Before we look into &amp;quot;inspecting state&amp;quot; we start looking into why and when developers use the debugger.&lt;/p&gt;  &lt;h4&gt;Bad scenarios for the debugger&lt;/h4&gt;  &lt;p&gt;&lt;img alt="image" src="http://lh6.ggpht.com/-kr3fDt-9x4c/Tfg0tqA3LvI/AAAAAAAAG8Q/RgpNH079Mm8/image%25255B11%25255D.png?imgmax=800" /&gt;#1 &lt;strong&gt;Reading code&lt;/strong&gt; by stepping through code&lt;/p&gt;  &lt;p&gt;&lt;img alt="image" src="http://lh6.ggpht.com/-kr3fDt-9x4c/Tfg0tqA3LvI/AAAAAAAAG8Q/RgpNH079Mm8/image%25255B11%25255D.png?imgmax=800" /&gt;#2 &lt;strong&gt;Finding a bug&lt;/strong&gt; by stepping through code &lt;/p&gt;  &lt;p&gt;&lt;img alt="image" src="http://lh6.ggpht.com/-kr3fDt-9x4c/Tfg0tqA3LvI/AAAAAAAAG8Q/RgpNH079Mm8/image%25255B11%25255D.png?imgmax=800" /&gt;#3 &lt;strong&gt;Understanding the flow &lt;/strong&gt;(what happens when and what should happen)&lt;/p&gt;  &lt;p&gt;&lt;img alt="image" src="http://lh6.ggpht.com/-kr3fDt-9x4c/Tfg0tqA3LvI/AAAAAAAAG8Q/RgpNH079Mm8/image%25255B11%25255D.png?imgmax=800" /&gt;#4 Discover API &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;#1    &lt;br /&gt;You don't need a debugger to read code! The more readable your code is the even less you are tempted to use the debugger to step through it.     &lt;br /&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="No surprises" border="0" alt="No surprises" src="http://lh3.ggpht.com/-vJBVlIKD8IA/Tjz6iCIav2I/AAAAAAAAHOs/gsZ6WhciYqI/image%25255B5%25255D.png?imgmax=800" width="173" height="240" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Nice clean code leads to: &amp;quot;&lt;strong&gt;No surprises&lt;/strong&gt;&amp;quot;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;#2    &lt;br /&gt;You could step through your whole application which might take a couple of hours, or you spend the time in writing a test that verifies your expectation. What is easier? What gives you more advantages for the future, e.g. &lt;a href="http://blog.gfader.com/2010/10/why-are-automated-tests-so-important.html" target="_blank"&gt;safety net for future changes&lt;/a&gt;?&lt;/p&gt;  &lt;p&gt;#3    &lt;br /&gt;To understand the flow of your application the debugger might be the 1st option that comes to mind. It might help you understand the flow of your application today, but what about in a weeks time? You probably forgot already about the execution flow of your app.     &lt;br /&gt;What about having some tests that describe the execution flow of your application? Maybe a nice combination of unit and integration tests.&lt;/p&gt;  &lt;p&gt;#4 Discovering an API with the debugger might be handy. I would MUCH more prefer to have some tests around the API that I could look at, in order to discover the API.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Good scenarios for the debugger&lt;/h4&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-yv_QZ9gteqo/Tjv0lKGhJGI/AAAAAAAAHOE/jMWw5pKMh0Q/s1600-h/check_thumb12.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="check_thumb[1]" border="0" alt="check_thumb[1]" src="http://lh4.ggpht.com/-AriYJaN3aJM/Tjv0o-r5qiI/AAAAAAAAHOI/cpwVefnbAh8/check_thumb1_thumb.png?imgmax=800" width="16" height="16" /&gt;&lt;/a&gt; Set a breakpoint, run there and &lt;strong&gt;inspect the state&lt;/strong&gt; of your application at that point.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-_UxP2BVp1qU/Tjv0sCde9OI/AAAAAAAAHOM/pHi1zclw_UM/s1600-h/check_thumb22.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="check_thumb[2]" border="0" alt="check_thumb[2]" src="http://lh3.ggpht.com/-D60t4DHTDNc/Tjv0uujhtaI/AAAAAAAAHOQ/kjY026gyXdo/check_thumb2_thumb.png?imgmax=800" width="16" height="16" /&gt;&lt;/a&gt;&amp;#160;&lt;strong&gt;On Exception&lt;/strong&gt;, attach the debugger and &lt;strong&gt;see the state&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-e7D9vhYtRB0/Tjv0xAl1xSI/AAAAAAAAHOU/pM_Fdsn_HFY/s1600-h/check_thumb32.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="check_thumb[3]" border="0" alt="check_thumb[3]" src="http://lh5.ggpht.com/-0KJVjZ0ZhD8/Tjv00OsxB_I/AAAAAAAAHOY/DsKrrqjUDgI/check_thumb3_thumb.png?imgmax=800" width="16" height="16" /&gt;&lt;/a&gt;&amp;#160;&lt;strong&gt;Attach the debugger&lt;/strong&gt; to any running application and inspect the state&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Interesting to mention is that even the latter &lt;strong&gt;state inspections &lt;/strong&gt;could be written as tests (maybe even &lt;a href="http://blog.gfader.com/2010/10/why-are-automated-tests-so-important.html" target="_blank"&gt;automated for regression&lt;/a&gt;).     &lt;br /&gt;&lt;em&gt;You are expecting your application variables to be in a certain state, which means Asserts on your variables &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh6.ggpht.com/-drLIChOMG8A/Tjv0fSLV6MI/AAAAAAAAHN8/WnObBV3bccA/wlEmoticon-winkingsmile2.png?imgmax=800" /&gt;       &lt;br /&gt;It's just too much work to write a test for a quick state inspection and that is probably the reason why we don't write tests for those…&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&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="Stepping through thousands of lines of code to find why the UI is not showing the right number" border="0" alt="Using the Debugger" src="http://lh6.ggpht.com/-PZTvYznTnaI/TkIlpTZGuEI/AAAAAAAAHPQ/UaoOkFHcWe4/image%25255B24%25255D.png?imgmax=800" width="689" height="534" /&gt;&amp;#160; &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: &lt;img alt="image" src="http://lh6.ggpht.com/-kr3fDt-9x4c/Tfg0tqA3LvI/AAAAAAAAG8Q/RgpNH079Mm8/image%25255B11%25255D.png?imgmax=800" /&gt; Bad: Stepping through thousands of lines of code to find why the UI is not showing the right number. (In this case the price in an auction) &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&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="Write a test for your expectations on state" border="0" alt="Write a test for your expectations on state" src="http://lh3.ggpht.com/-48nmOBzhwWw/TkIj6bYPFjI/AAAAAAAAHPM/ibIwNyvWf0U/image%25255B18%25255D.png?imgmax=800" width="705" height="293" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: &lt;img alt="check_thumb[1]" src="http://lh4.ggpht.com/-AriYJaN3aJM/Tjv0o-r5qiI/AAAAAAAAHOI/cpwVefnbAh8/check_thumb1_thumb.png?imgmax=800" /&gt; Good: Write a test for your expectations on state. Here we expect Anna to be the highest bidder with a price of $91&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;Rules of thumb     &lt;br /&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-3VQZ7Zk9SWE/Tjv0292X9LI/AAAAAAAAHOc/KzmQhcLL2e8/image11.png?imgmax=800" width="80" height="52" /&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Write better code (readable and understandable)! &lt;/li&gt;    &lt;li&gt;Have a tight test harness around your code! &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;These 2 rules help the reader to understand your code and the flow of your application.    &lt;br /&gt;&lt;em&gt;How can we achieve this? Do regular code reviews in your team.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Conclusion&lt;/h4&gt;  &lt;p&gt;Use the debugger, but think about better investments of your time. Maybe you can write a test for the current scenario that you are trying to debug.&lt;/p&gt;  &lt;p&gt;My experience: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Debugging leads to patching until the problem is fixed, but not to understanding the root causes of the problem and fixing it correctly &lt;/li&gt;    &lt;li&gt;Debuggers are used to see: Is this line of code actually hit by my code (Manual Code Coverage ;-) )      &lt;br /&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;What do you use the Debugger for?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-4162192846267279067?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/g2F8_F_-7_A" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/g2F8_F_-7_A/avoid-debugger-like-pest.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-drLIChOMG8A/Tjv0fSLV6MI/AAAAAAAAHN8/WnObBV3bccA/s72-c/wlEmoticon-winkingsmile2.png?imgmax=800" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://blog.gfader.com/2011/08/avoid-debugger-like-pest.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-7135765839115815002</guid><pubDate>Thu, 04 Aug 2011 14:36:00 +0000</pubDate><atom:updated>2011-08-06T15:26:48.755+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">debugging</category><category domain="http://www.blogger.com/atom/ns#">vs2010</category><title>VS2010 - Debugging not working</title><description>&lt;p&gt;We just faced an interesting problem on one of our dev's computers.    &lt;br /&gt;He is not able to debug any VS2010 solution: Windows Forms, WPF, Web Forms… There is no chance to debug anything on his 64bit machine.&lt;/p&gt;  &lt;h4&gt;Problem:&lt;/h4&gt;  &lt;ol&gt;   &lt;li&gt;Add breakpoint &lt;/li&gt;    &lt;li&gt;Hit F5 on your project &lt;/li&gt;    &lt;li&gt;Break point doesn't get hit &lt;/li&gt; &lt;/ol&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;In Debug | Windows | Breakpoints you see&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="The breakpoint will not currently be hit. No symbols have been loaded for this document." border="0" alt="The breakpoint will not currently be hit. No symbols have been loaded for this document." src="http://lh6.ggpht.com/-F79C265DQis/TjquRarm-NI/AAAAAAAAHNQ/BxWYqVe11kw/clip_image0027.jpg?imgmax=800" width="598" height="184" /&gt;     &lt;br /&gt;&lt;b&gt;Figure&lt;/b&gt;: The breakpoint will not currently be hit. No symbols have been loaded for this document.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Our fix&lt;/h4&gt;  &lt;p&gt;Check the solution configuration to be &amp;quot;Any CPU&amp;quot; (which means x64)&lt;/p&gt;  &lt;p&gt;Change &lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://lh3.ggpht.com/-3rHbuPdeeqY/TjquTFwQhjI/AAAAAAAAHOg/DtCoL3uiUw4/clip_image004%25255B1%25255D.jpg?imgmax=800" width="727" height="460" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Solution configuration that can be found by doing a right click on your Visual Studio 2010 solution&lt;/p&gt;  &lt;p&gt;to&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image006" border="0" alt="clip_image006" src="http://lh3.ggpht.com/-fRtUn81axJA/TjquU4H5nAI/AAAAAAAAHOk/2sYcniytUyY/clip_image006%25255B1%25255D.jpg?imgmax=800" width="783" height="499" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Change it to be &amp;quot;Any&amp;quot; platform, If there is no &amp;quot;Any CPU&amp;quot; in the list, you have to add a new entry&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;We couldn't figure out yet &lt;strong&gt;why &lt;/strong&gt;on each &amp;quot;File -&amp;gt; New Project&amp;quot; this is the default &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-sadsmile" alt="Sad smile" src="http://lh6.ggpht.com/-pCnd6ymmp9U/TjquVx2Aw0I/AAAAAAAAHNk/ksrPwlh917g/wlEmoticon-sadsmile2.png?imgmax=800" /&gt;&amp;#160; &lt;br /&gt;I update this once we know…&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-OTghB0hK-i8/TjquXLzirZI/AAAAAAAAHOo/2e44jNgbzis/image%25255B1%25255D.png?imgmax=800" width="261" height="116" /&gt;     &lt;br /&gt;BTW: I am big opponent of debugging as you may know. I try to &lt;a href="http://blog.gfader.com/2010/10/developer-blog-banter-how-do-you-test.html"&gt;write as much tests as possible&lt;/a&gt; in order to &lt;a href="http://blog.gfader.com/2010/10/why-are-automated-tests-so-important.html"&gt;avoid time wasted in the debugger&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The only reason that I see in using the debugger is: &lt;strong&gt;inspecting state&lt;/strong&gt;.     &lt;br /&gt;More on this in my blog post: &lt;a href="http://blog.gfader.com/2011/08/avoid-debugger-like-pest.html" target="_blank"&gt;Avoid the debugger like the pest&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-7135765839115815002?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/77x0GXgFQn8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/77x0GXgFQn8/vs2010-debugging-not-working.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-F79C265DQis/TjquRarm-NI/AAAAAAAAHNQ/BxWYqVe11kw/s72-c/clip_image0027.jpg?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.gfader.com/2011/08/vs2010-debugging-not-working.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-5556506609737422567</guid><pubDate>Sat, 23 Jul 2011 02:43:00 +0000</pubDate><atom:updated>2011-08-27T12:21:12.863+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">deployment</category><category domain="http://www.blogger.com/atom/ns#">TFS</category><category domain="http://www.blogger.com/atom/ns#">vs2010</category><title>Continuous Delivery with TFS, msbuild and msdeploy</title><description>&lt;p&gt;We had a great crowd last Wednesday night at the Sydney .NET UG. Thanks everyone! &lt;/p&gt;  &lt;p&gt;&lt;strike&gt;For everyone who couldn't make it, &lt;/strike&gt;&lt;a href="mailto:RajDhatt*ssw.com.au?Subject=Where%20Is%20The%20recording%20of%20Peter%20Gfader%20Continuous%20Delivery"&gt;&lt;strike&gt;ping Raj&lt;/strike&gt;&lt;/a&gt;&lt;strike&gt; (our video guy) and tell him to get the recording up and running &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh4.ggpht.com/-_x4ee-XjQQ8/TiyfIl3JrrI/AAAAAAAAHNM/KTLdDSLA938/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800" /&gt;      &lt;br /&gt;&lt;/strike&gt;&lt;a href="http://blog.gfader.com/2011/08/it-official-manual-deployments-are-bad.html"&gt;The video is online: Continuous Delivery with TFS, msbuild and msdeploy!&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;Agenda of the talk&lt;/strong&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Pain &lt;/li&gt;    &lt;li&gt;Goals &lt;/li&gt;    &lt;li&gt;How To      &lt;ol&gt;       &lt;li&gt;Start from scratch &lt;/li&gt;        &lt;li&gt;Existing System &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt;    &lt;li&gt;Best Practices &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;&lt;strong&gt;Pain&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Deployment pain can be found on my previous entry about &lt;a href="http://blog.gfader.com/2011/06/tired-of-manual-deployments.html" target="_blank"&gt;Tired of manual deployments?&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Goals&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;#1 Deliver business value faster    &lt;br /&gt;&lt;em&gt;You spent an hour on a bug fix, but customers will not see it for months&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;#2 Fail fast and early in the development process    &lt;br /&gt;&lt;em&gt;On the &amp;quot;Go Live Day&amp;quot; you realize: Production hardware is missing an important feature&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;#3 Release small increments    &lt;br /&gt;&lt;em&gt;Deploying often, less number of defects      &lt;br /&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;How To&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;See the slides for all details and the recording&lt;strike&gt; (that should be up soon, &lt;/strike&gt;&lt;a href="mailto:RajDhatt*ssw.com.au?Subject=Where%20Is%20The%20recording%20of%20Peter%20Gfader%20Continuous%20Delivery"&gt;&lt;strike&gt;Raj&lt;/strike&gt;&lt;/a&gt;&lt;strike&gt;)&lt;/strike&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;#1 Deploy early    &lt;br /&gt;&lt;em&gt;Deployment is never easy, so try to deploy as soon as possible to remove all roadblocks&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;#2 Have a rollback plan    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;#3 Have a Dashboard    &lt;br /&gt;&lt;em&gt;Latest Build? Environment which version? Everything healthy?&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;#4 Have a guinea pig    &lt;br /&gt;&lt;em&gt;AB testing&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;#5 Have a clone of your production environment &lt;/p&gt;  &lt;p&gt;#6 Have everything under source control&lt;/p&gt;  &lt;p&gt;#7 Log failed and successful deployments    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Thanks everyone for the great feedback!!    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Slides are on SlideShare&lt;/p&gt;  &lt;div style="width: 425px" id="__ss_8668024"&gt;&lt;strong style="margin: 12px 0px 4px; display: block"&gt;&lt;a title="Continuous Delivery with TFS msbuild msdeploy" href="http://www.slideshare.net/PeterGfader/continuous-delivery-with-tfs-msbuild-msdeploy" target="_blank"&gt;Continuous Delivery with TFS msbuild msdeploy&lt;/a&gt;&lt;/strong&gt; &lt;iframe height="355" marginheight="0" src="http://www.slideshare.net/slideshow/embed_code/8668024" frameborder="0" width="425" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;    &lt;div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px"&gt;View more &lt;a href="http://www.slideshare.net/" target="_blank"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/PeterGfader" target="_blank"&gt;Peter Gfader&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;More infos can be found on my blog post about &lt;a href="http://blog.gfader.com/2010/12/do-you-automate-your-deployment-process.html" target="_blank"&gt;Do you automate your deployment process? (aka Continuous Deployment)&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-5556506609737422567?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/OwCz0izZRNo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/OwCz0izZRNo/continuous-delivery-with-tfs-msbuild.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-_x4ee-XjQQ8/TiyfIl3JrrI/AAAAAAAAHNM/KTLdDSLA938/s72-c/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.gfader.com/2011/07/continuous-delivery-with-tfs-msbuild.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-5996284747389325394</guid><pubDate>Thu, 14 Jul 2011 02:30:00 +0000</pubDate><atom:updated>2011-12-11T15:08:03.969+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">asp.net</category><title>Website check list - Part 2 ASP.NET - 8 performance tips before going live</title><description>&lt;strong&gt;Index of series    &lt;br /&gt;&lt;/strong&gt;&lt;a href="http://blog.gfader.com/2011/07/website-check-list-part-1-aspnet-4.html"&gt;Part 1 ASP.NET - 4 essential steps before going live&lt;/a&gt;   &lt;br /&gt;&lt;a href="http://blog.gfader.com/2011/07/website-check-list-part-2-aspnet-8.html"&gt;Part 2 ASP.NET - 8 performance tips before going live (*this post*)&lt;/a&gt;   &lt;br /&gt;&lt;a href="http://blog.gfader.com/2011/08/part-3-aspnet-8-user-experience-tips.html" target="_blank"&gt;Part 3 ASP.NET - 9 User Experience tips before going live&lt;/a&gt;   &lt;br /&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Part 1 of this series had a little &lt;a href="http://blog.gfader.com/2011/07/website-check-list-part-1-aspnet-4.html" target="_blank"&gt;checklist before going live&lt;/a&gt; to ensure that we are ready from a security perspective and our site is healthy and remains healthy. &lt;/p&gt;  &lt;p&gt;This part will cover more performance specific tips that I collected over the years.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;&lt;em&gt;The web builds on top of HTTP, HTML, CSS, JS, …      &lt;br /&gt;Web performance is about &lt;/em&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;em&gt;Minimizing the data that you send over the wire&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;Minimizing the time spent on each pageview        &lt;br /&gt;&lt;/em&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;em&gt;That means:&lt;/em&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;em&gt;Deliver as little as possible on each page view&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;&lt;em&gt;Do as little as possible on each page view (on the server and the client)&lt;/em&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;#1 Tune your web.config for performance&lt;/h4&gt; Mads Kristensen has written some awesome tips and tricks to get more out of IIS and ASP.NET.   &lt;br /&gt;Check this 2 links   &lt;br /&gt;  &lt;p&gt;&lt;a href="http://madskristensen.net/post/Performance-tuning-tricks-for-ASPNET-and-IIS-7-part-1.aspx"&gt;http://madskristensen.net/post/Performance-tuning-tricks-for-ASPNET-and-IIS-7-part-1.aspx&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://madskristensen.net/post/Performance-tuning-tricks-for-ASPNET-and-IIS-7-e28093-part-2.aspx"&gt;http://madskristensen.net/post/Performance-tuning-tricks-for-ASPNET-and-IIS-7-e28093-part-2.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;#2 Have an automated test tool that monitors the uptime of your site&lt;/h4&gt;  &lt;p&gt;Obviously you want to know if your site is down for whatever reason (DNS, database, configuration error, …)    &lt;br /&gt;Use one of these services on the following page to ping your site every second, minute, hour, whatever your server can handle.     &lt;br /&gt;&lt;a href="http://sixrevisions.com/tools/12-excellent-free-tools-for-monitoring-your-sites-uptime/"&gt;http://sixrevisions.com/tools/12-excellent-free-tools-for-monitoring-your-sites-uptime/&lt;/a&gt;     &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://lh5.ggpht.com/-EHbjOcM1wIw/Th5Usm3UCcI/AAAAAAAAHMU/2zAMYk-IugM/s1600-h/image%25255B13%25255D.png"&gt;&lt;em&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-FquN-ycGRuI/Th5Ut-NGLMI/AAAAAAAAHMY/XyQzWgRUuoY/image_thumb%25255B7%25255D.png?imgmax=800" width="640" height="325" /&gt;&lt;/em&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: What about monitoring your zsValidate page? &lt;em&gt;Ping the page every 5 minutes and check for #AllGood…&lt;/em&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;#3 Have Google Analytics (or a similar tool) on every page&lt;/h4&gt;  &lt;p&gt;Track your users going through the site, to know what they are looking for and optimize your site regarding your users needs.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;The next 2 tips are about creating a performance baseline, that you are going to use for future reference.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;#4 Check your website in YSlow and establish a baseline &amp;quot;Grade&amp;quot; that you expect to be the minimum over time&lt;/h4&gt;  &lt;p&gt;YSlow gives you a rating of your page performance. &lt;a href="http://developer.yahoo.com/yslow/"&gt;http://developer.yahoo.com/yslow/&lt;/a&gt;     &lt;br /&gt;Talk to your team and establish a baseline that you want to keep over time     &lt;br /&gt;(Implementing new features normally degrades your performance, so you have to work hard to keep performance to this baseline)     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-AkIsZT-9zzU/Th5UuhwM5hI/AAAAAAAAHMc/fQeflEa1zKg/s1600-h/image%25255B7%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Grade B in YSlow is OK, but we want to get better over time" border="0" alt="Grade B in YSlow is OK, but we want to get better over time" src="http://lh6.ggpht.com/-MGy-xUKOJgw/Th5UvSASiyI/AAAAAAAAHMg/rZr1Z67mwcQ/image_thumb%25255B3%25255D.png?imgmax=800" width="644" height="290" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Grade B in YSlow is OK, but we want to get better over time&lt;/p&gt; &lt;em&gt;The earlier in the development process you establish a baseline, the better you are prepared for the future.    &lt;br /&gt;&lt;/em&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;#5 Check website in PageSpeed and establish baseline Grade that you expect to be the minimum&lt;/h4&gt;  &lt;p&gt;Same story as per YSPow, PageSpeed is just another nice tool in your web developer toolbox.    &lt;br /&gt;&lt;a href="http://code.google.com/speed/page-speed/"&gt;http://code.google.com/speed/page-speed/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;a href="http://lh4.ggpht.com/-stHhJUJJ504/Th5UwIypkJI/AAAAAAAAHMk/e11nWbwOHrI/s1600-h/image%25255B8%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-afSd8cwrFx8/Th5UxHGZL6I/AAAAAAAAHMo/R96pib35K50/image_thumb%25255B4%25255D.png?imgmax=800" width="644" height="312" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: PageSpeed score 80 out of 100 is a nice starting point. But you can do better!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;If you have more time to spend on performance then go on…      &lt;br /&gt;The following tips are about minimizing the data over the wire…&lt;/em&gt;&lt;/p&gt;  &lt;h4&gt;#6 Do you minimize your HTML, CSS and JavaScript?&lt;/h4&gt;  &lt;p&gt;See tip #1 for how to do this with ASP.NET automagically or do it manually for CSS and JavaScript.    &lt;br /&gt;If you do it manually, make sure to keep the original version for later changes…     &lt;br /&gt;E.g.     &lt;br /&gt;myStyle.&lt;font style="background-color: #ffff00"&gt;min&lt;/font&gt;.css     &lt;br /&gt;MyStyle.&lt;font style="background-color: #ffff00"&gt;original&lt;/font&gt;.css (This is the original that you use for future changes)&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;#7 Do you bundle your single data files (CSS, JS, …) into 1 download?&lt;/h4&gt;  &lt;p&gt;Nice solution for bundling multiple CSS or JavaScript files into 1 download can be found on &lt;a href="http://madskristensen.net/post/Performance-tuning-tricks-for-ASPNET-and-IIS-7-e28093-part-2.aspx" target="_blank"&gt;Mads blog post about performance tuning tricks&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;#8 Do you use Image Sprites to improve performance?&lt;/h4&gt;  &lt;p&gt;Using Image Sprites can dramatically improve performance on sites with a lot of small images.&lt;/p&gt;  &lt;p&gt;There are a lot of tools to help compile your images into sprites, see here &lt;a href="http://stackoverflow.com/questions/527336/tools-to-make-css-sprites"&gt;http://stackoverflow.com/questions/527336/tools-to-make-css-sprites&lt;/a&gt; and here &lt;a href="http://www.spritecow.com/"&gt;http://www.spritecow.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Do you know more??      &lt;br /&gt;Drop me &lt;a href="mailto://peter@gfader.com" target="_blank"&gt;an email&lt;/a&gt; if you have to share more tips!&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The next and last post will look at basic tips for User Experience (UX) and User Interface (UI)&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-5996284747389325394?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/cr_iaIutU0s" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/cr_iaIutU0s/website-check-list-part-2-aspnet-8.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-FquN-ycGRuI/Th5Ut-NGLMI/AAAAAAAAHMY/XyQzWgRUuoY/s72-c/image_thumb%25255B7%25255D.png?imgmax=800" height="72" width="72" /><thr:total>6</thr:total><feedburner:origLink>http://blog.gfader.com/2011/07/website-check-list-part-2-aspnet-8.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-1422273560574022572</guid><pubDate>Fri, 01 Jul 2011 06:50:00 +0000</pubDate><atom:updated>2011-12-11T15:08:18.455+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">asp.net</category><title>Website check list - Part 1 ASP.NET - 4 essential steps before going live</title><description>&lt;p&gt;&lt;strong&gt;Index of series      &lt;br /&gt;&lt;/strong&gt;&lt;a href="http://blog.gfader.com/2011/07/website-check-list-part-1-aspnet-4.html"&gt;Part 1 ASP.NET - 4 essential steps before going live (*this post*)&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://blog.gfader.com/2011/07/website-check-list-part-2-aspnet-8.html"&gt;Part 2 ASP.NET - 8 performance tips before going live&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://blog.gfader.com/2011/08/part-3-aspnet-8-user-experience-tips.html" target="_blank"&gt;Part 3 ASP.NET - 9 User Experience tips before going live&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;span class="red"&gt;*Updated*&lt;/span&gt; 14 July 2011: Explanation about the the &amp;quot;zsValidate page&amp;quot; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Its not easy to launch a website.    &lt;br /&gt;As per &lt;a href="http://twitter.com/#!/secretGeek" target="_blank"&gt;secretGeek&lt;/a&gt; you gotta know:     &lt;br /&gt;&amp;quot;HTML, CSS, JavaScript, C#, razor, SQL, DDL, and regex. Oh, plus people skills.&amp;quot;&amp;#160; &lt;br /&gt;    &lt;br /&gt;from &lt;a title="http://twitter.com/#!/secretGeek/status/83297694449287168" href="http://twitter.com/#!/secretGeek/status/83297694449287168" target="_blank"&gt;http://twitter.com/#!/secretGeek/status/83297694449287168&lt;/a&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;This is a quick check list for an ASP.NET site before going live.&lt;em&gt; There are heaps of those on the web, but this one is customized to ASP.NET and my personal top 4.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Leave a comment if you want to add something      &lt;br /&gt;Thx to &lt;a href="http://blog.damianbrady.com.au/" target="_blank"&gt;Damian&lt;/a&gt; and &lt;a href="https://plus.google.com/100611814604676429490/posts" target="_blank"&gt;Tristan&lt;/a&gt; for some additional tips&lt;/em&gt;&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;hr /&gt;  &lt;h4&gt;#1 Check your web.config for security and performance issues&lt;/h4&gt;  &lt;p&gt;Submit your web.config to &lt;a href="http://www.wcanalyzer.com/" target="_blank"&gt;http://www.wcanalyzer.com/&lt;/a&gt;     &lt;br /&gt;&lt;em&gt;Attention: Before submitting to wcanalyzer.com make sure to get rid of all clear text passwords and server/ database names &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh5.ggpht.com/-hg3JIxpUSfU/Tg1uPBsLkNI/AAAAAAAAHK8/jmvHGHwhobU/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800" /&gt;&amp;#160;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-4dXWdjPLI_g/Tg1uPwIM3YI/AAAAAAAAHLA/30pbZQUvHlc/s1600-h/image3.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-NQanKzI59NE/Tg1uRC5kslI/AAAAAAAAHLE/mSz2WG0rxQo/image_thumb1.png?imgmax=800" width="436" height="484" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Fix all security issues from wcanalyzer&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;     &lt;br /&gt;Use web transforms to get rid of all &amp;quot;Debug&amp;quot; configuration settings and security relevant bits     &lt;br /&gt;&lt;a href="http://blogs.msdn.com/b/webdevtools/archive/2009/05/04/web-deployment-web-config-transformation.aspx" target="_blank"&gt;http://blogs.msdn.com/b/webdevtools/archive/2009/05/04/web-deployment-web-config-transformation.aspx&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Tip      &lt;br /&gt;&lt;/strong&gt;There is a nice little tool called the &amp;quot;Web.config Transformation Tester tool&amp;quot; to test whether your transforms work as expected.     &lt;br /&gt;Check it out if you struggle with web transformation here &lt;a href="http://webconfigtransformationtester.apphb.com/" target="_blank"&gt;http://webconfigtransformationtester.apphb.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Some other quick things that you should check your web.config for    &lt;br /&gt;&lt;em&gt;Not 100% sure but I hope this analyser covers those&lt;/em&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&amp;lt;compilation debug=&amp;quot;false&amp;quot;&amp;gt;      &lt;br /&gt;Increases performance and caching and less overhead       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&amp;lt;customErrors mode=&amp;quot;on&amp;quot; or &amp;quot;remoteOnly&amp;quot;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Disable or at least limit tracing info      &lt;br /&gt;&amp;lt;trace mostRecent=&amp;quot;true&amp;quot; enabled=&amp;quot;true&amp;quot; requestLimit=&amp;quot;1000&amp;quot; pageOutput=&amp;quot;false&amp;quot; localOnly=&amp;quot;true&amp;quot;/&amp;gt;       &lt;br /&gt;      &lt;br /&gt;Tracing works only in debug mode anyway… So this shouldn't be necessary       &lt;br /&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;Tip      &lt;br /&gt;&lt;/strong&gt;&amp;quot;Superhero Sys Admins&amp;quot; put all those in the machine config to enforce this machine wide&lt;/p&gt;  &lt;hr /&gt;  &lt;h4&gt;#2 Deploy &amp;quot;Release&amp;quot; build&lt;/h4&gt;  &lt;p&gt;Because you have setup Continuous Delivery as per &lt;a href="http://blog.gfader.com/2010/12/do-you-automate-your-deployment-process.html"&gt;http://blog.gfader.com/2010/12/do-you-automate-your-deployment-process.html&lt;/a&gt;     &lt;br /&gt;just check that you really deploy the &amp;quot;Release&amp;quot; version.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/-Y6fWeVoAdB8/Tg1uSHzBvDI/AAAAAAAAHLI/QP_ym6jQ7mw/s1600-h/image%25255B4%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-kLOhh1yXA4I/Tg1uTDs4n6I/AAAAAAAAHLM/EjFZjzXcVO4/image_thumb%25255B1%25255D.png?imgmax=800" width="644" height="147" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Set your TFS Build configuration to be &amp;quot;Release&amp;quot;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Tip      &lt;br /&gt;&lt;/strong&gt;Change your Build configuration to &amp;quot;Release&amp;quot; will reduce your build time to half. Per default this is set to: &amp;quot;Any CPU|Debug, Any CPU|Release&amp;quot; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;hr /&gt;  &lt;h4&gt;#3 Install elmah and have &amp;quot;no error emails&amp;quot; for 1 week&lt;/h4&gt;  &lt;p&gt;1. &amp;quot;nuget elmah&amp;quot; on your website project&lt;/p&gt;  &lt;p&gt;2. Configure error email&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;elmah&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;errorMail&lt;/span&gt; &lt;span class="attr"&gt;from&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;devs@northwind.com.au&amp;quot;&lt;/span&gt;
           &lt;span class="attr"&gt;to&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot; devs@northwind.com.au&amp;quot;&lt;/span&gt;
           &lt;span class="attr"&gt;subject&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;LOCALHOST - Elmah - Error in Website&amp;quot;&lt;/span&gt;  // &lt;span class="attr"&gt;Servername&lt;/span&gt; &lt;span class="attr"&gt;gets&lt;/span&gt; &lt;span class="attr"&gt;injected&lt;/span&gt; &lt;span class="attr"&gt;via&lt;/span&gt; &lt;span class="attr"&gt;web&lt;/span&gt;.&lt;span class="attr"&gt;transform&lt;/span&gt;
           &lt;span class="attr"&gt;async&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;
           &lt;span class="attr"&gt;priority&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;High&amp;quot;&lt;/span&gt;
           &lt;span class="attr"&gt;smtpPort&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;25&amp;quot;&lt;/span&gt;
           &lt;span class="attr"&gt;smtpServer&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;mail.northwind.com.au&amp;quot;&lt;/span&gt;
           &lt;span class="attr"&gt;noYsod&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;elmah&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;






.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;3. Wait 1 week and check that you have 0 error emails&lt;/p&gt;

&lt;p&gt;No Go-Live if you can't get that. 
  &lt;br /&gt;Your site shouldn't throw errors, even not missing files 404 or 500. 

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;hr /&gt;

&lt;h4&gt;#4 Have a zsValidate page and get all green ticks&lt;/h4&gt;

&lt;p&gt;
  &lt;br /&gt;Follow this rule &lt;a href="http://www.ssw.com.au/ssw/Standards/Rules/RulesToBetterWebsitesTuningAndMaintenance.aspx#zsValidate"&gt;http://www.ssw.com.au/ssw/Standards/Rules/RulesToBetterWebsitesTuningAndMaintenance.aspx#zsValidate&lt;/a&gt; 

  &lt;br /&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-4Wn2NQiYO_4/Tg1uULzLG3I/AAAAAAAAHLQ/kC0ni9Dt6Ak/image%25255B11%25255D.png?imgmax=800" width="416" height="441" /&gt; 

  &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Green apples are healthy &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh5.ggpht.com/-hg3JIxpUSfU/Tg1uPBsLkNI/AAAAAAAAHK8/jmvHGHwhobU/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800" /&gt;&lt;/p&gt;

&lt;p&gt;Update: The zsValidate page checks that all your external dependencies are up and running. This might include the databases, web services, other servers, etc… Everything that is outside the web application process and everything that could cause the website from functioning.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is part 1 out of 3 or maybe 4. Not sure yet… it is not easy to build websites these days&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;PS: Needless to say that before you consider this list, you should fulfill all your customer requirements, proof-read every single webpage, know what traffic to expect and have automated unit/integration/stress/performance/black and white tests &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh5.ggpht.com/-hg3JIxpUSfU/Tg1uPBsLkNI/AAAAAAAAHK8/jmvHGHwhobU/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800" /&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-1422273560574022572?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/bJxp-AUopzI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/bJxp-AUopzI/website-check-list-part-1-aspnet-4.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-hg3JIxpUSfU/Tg1uPBsLkNI/AAAAAAAAHK8/jmvHGHwhobU/s72-c/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>8</thr:total><feedburner:origLink>http://blog.gfader.com/2011/07/website-check-list-part-1-aspnet-4.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-8474244387959802214</guid><pubDate>Wed, 29 Jun 2011 01:18:00 +0000</pubDate><atom:updated>2011-06-29T06:39:43.591+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">testing</category><category domain="http://www.blogger.com/atom/ns#">vs2010</category><title>"Continuously" testing with Visual Studio 2010</title><description>&lt;p&gt;&lt;em&gt;I used the following notes as guide line for my talk &lt;a href="http://sydney.ozalt.net/" target="_blank"&gt;Sydney ALT.NET&lt;/a&gt;, and just post them here for future reference…       &lt;br /&gt;Had a great night @ the user group and interesting insights into stackoverflow from &lt;a href="http://samsaffron.com/" target="_blank"&gt;Sam Saffron&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;An important aspect of Agile is the feedback loop or in other words: &lt;strong&gt;We want short feedback cycles&lt;/strong&gt;.     &lt;br /&gt;Check out Scott Ambler post for why those feedback loops are so important in Agile &lt;a href="http://www.ambysoft.com/essays/whyAgileWorksFeedback.html" target="_blank"&gt;http://www.ambysoft.com/essays/whyAgileWorksFeedback.html&lt;/a&gt;     &lt;br /&gt;&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;We want &lt;font color="#ff0000"&gt;quick&lt;/font&gt; feedback&lt;/p&gt;    &lt;ol&gt;     &lt;li&gt;2 weekly reviews &lt;/li&gt;      &lt;li&gt;weekly deploys &lt;/li&gt;      &lt;li&gt;daily stand ups &lt;/li&gt;      &lt;li&gt;pair programming &lt;/li&gt;      &lt;li&gt;code reviews &lt;/li&gt;      &lt;li&gt;automated tests &lt;/li&gt;      &lt;li&gt;… &lt;/li&gt;   &lt;/ol&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;------------------&lt;/p&gt;    &lt;p&gt;The pain with VS2010 … &lt;em&gt;if &lt;/em&gt;&lt;a href="http://blog.gfader.com/2010/10/why-are-automated-tests-so-important.html" target="_blank"&gt;&lt;em&gt;you write tests, and yes you should…&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;    &lt;ol&gt;     &lt;li&gt;Write test &lt;/li&gt;      &lt;li&gt;Stop coding &lt;/li&gt;      &lt;li&gt;Run tests &lt;/li&gt;      &lt;li&gt;Write code &lt;/li&gt;      &lt;li&gt;Stop coding &lt;/li&gt;      &lt;li&gt;Run tests &lt;/li&gt;      &lt;li&gt;Refactor code &lt;/li&gt;      &lt;li&gt;Run tests &lt;/li&gt;   &lt;/ol&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;------------------&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Running tests with vanilla Visual Studio is slow&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;------------------&lt;/p&gt;    &lt;p&gt;Better with Resharper&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;------------------&lt;/p&gt;    &lt;p&gt;Better with TestDriven.NET and shortcut Ctrl+R, T&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;------------------&lt;/p&gt;    &lt;p&gt;Even better with Giles &lt;a href="http://codereflection.github.com/Giles/" target="_blank"&gt;http://codereflection.github.com/Giles/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Giles&lt;/strong&gt;       &lt;br /&gt;On File save, Auto build &amp;amp; test in the background&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;------------------&lt;/p&gt;    &lt;p&gt;We can go 1 step further with &lt;strong&gt;nCrunch        &lt;br /&gt;&lt;/strong&gt;&lt;a title="http://www.ncrunch.net/" href="http://www.ncrunch.net/" target="_blank"&gt;http://www.ncrunch.net/&lt;/a&gt;&amp;#160; &lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;------------------&lt;/p&gt;    &lt;ol&gt;     &lt;li&gt;Write test &lt;/li&gt;      &lt;li&gt;Write code &lt;/li&gt;      &lt;li&gt;Refactor code &lt;/li&gt;   &lt;/ol&gt;    &lt;p&gt;nCrunch takes care of running the tests!&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;------------------&lt;/p&gt;    &lt;p&gt;What else you get?&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;No need to save files &lt;/li&gt;      &lt;li&gt;Code coverage        &lt;br /&gt;* Black         &lt;br /&gt;* Green - Which test covers this line         &lt;br /&gt;* Red &lt;/li&gt;      &lt;li&gt;Parallel execution &lt;/li&gt;      &lt;li&gt;Intelligent Execution&amp;#160; &lt;br /&gt;* Slow tests not affecting the fast ones &lt;/li&gt;   &lt;/ul&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;-------------------&lt;/p&gt;    &lt;p&gt;What is missing?&amp;#160;&amp;#160;&amp;#160; &lt;em&gt;As per today end of July 2011 &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh6.ggpht.com/-aYY67tm8m-w/Tgp9ZN5XYjI/AAAAAAAAHKg/0oNAswKogPg/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800" /&gt;&lt;/em&gt;&lt;/p&gt;    &lt;ol&gt;     &lt;li&gt;Why #fail? &lt;/li&gt;      &lt;li&gt;How to find the failing test? &lt;/li&gt;      &lt;li&gt;How to spot the broken code? &lt;/li&gt;      &lt;li&gt;Test impact analysis? &lt;/li&gt;   &lt;/ol&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;p&gt;------------------&lt;/p&gt;    &lt;p&gt;Now you&lt;/p&gt;    &lt;p&gt;1. Download Giles      &lt;br /&gt;&lt;a href="http://codereflection.github.com/Giles/"&gt;http://codereflection.github.com/Giles/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;2. Download nCrunch      &lt;br /&gt;&lt;a href="http://www.ncrunch.net/"&gt;http://www.ncrunch.net/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;3. Have fun and let me know what you think&lt;/p&gt;    &lt;p&gt;------------------&lt;/p&gt;&lt;/blockquote&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-8474244387959802214?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/Qwt84ABOBfY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/Qwt84ABOBfY/continuous-testing-with-visual-studio.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-aYY67tm8m-w/Tgp9ZN5XYjI/AAAAAAAAHKg/0oNAswKogPg/s72-c/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.gfader.com/2011/06/continuous-testing-with-visual-studio.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-5841163591974518898</guid><pubDate>Wed, 22 Jun 2011 07:03:00 +0000</pubDate><atom:updated>2011-06-22T09:06:33.993+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">deployment</category><category domain="http://www.blogger.com/atom/ns#">TFS</category><title>Tired of manual deployments?</title><description>&lt;p&gt;&lt;em&gt;Have you ever come across this?&lt;/em&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;quot;Only Bob knows how to deploy... And &lt;font color="#ff0000"&gt;he is on holidays&lt;/font&gt;...&amp;quot;       &lt;br /&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Or maybe this…&lt;/em&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;You spent an hour on a bug fix,      &lt;br /&gt;&amp;#160;&amp;#160; but customers will not see it &lt;font color="#ff0000"&gt;for months&lt;/font&gt;       &lt;br /&gt;&lt;/p&gt; &lt;/blockquote&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Or you need to do this…&lt;/em&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;quot;We deploy on Saturday, because on Saturday there is no one in the office and &lt;font color="#ff0000"&gt;we can't be offline&lt;/font&gt; during the week&amp;quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Or you are a bit late and …&lt;/em&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Deployment happens 1 day before Go-Live and you are &lt;font color="#ff0000"&gt;freaking out&lt;/font&gt;       &lt;br /&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Borat freaking out" border="0" alt="Borat freaking out" src="http://lh3.ggpht.com/-6B1pwu2biv0/TgGTvHldfJI/AAAAAAAAHJ0/c8NF5KVbgRI/image3.png?imgmax=800" width="216" height="244" /&gt;       &lt;br /&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;   &lt;br /&gt;&lt;em&gt;And you say …&lt;/em&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;quot;&lt;font color="#ff0000"&gt;Deployment is so hard&lt;/font&gt;.&amp;quot;       &lt;br /&gt;&amp;quot;We have to configure the environment, update databases, take care of existing data, start and stop external services, check for external dependencies and more things on my list that I can't even remember&amp;quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;em&gt;Most important …&lt;/em&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font size="5"&gt;Manual deployment != fun&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Quitting your job is not an option…&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-csWG0di6Jrg/TgGTwddtWGI/AAAAAAAAHJ4/pMQ6RzIQrow/image10.png?imgmax=800" width="644" height="259" /&gt;     &lt;br /&gt;From: &lt;a title="http://twitter.com/#!/DEVOPS_BORAT/status/62745218931359744&amp;#13;&amp;#10;" href="http://twitter.com/#!/DEVOPS_BORAT/status/62745218931359744"&gt;http://twitter.com/#!/DEVOPS_BORAT/status/62745218931359744 &lt;/a&gt;&lt;a title="http://twitter.com/#!/DEVOPS_BORAT/status/62745218931359744&amp;#13;&amp;#10;" href="http://twitter.com/#!/DEVOPS_BORAT/status/62745218931359744"&gt;     &lt;br /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;How to tackle these problems with TFS?    &lt;br /&gt;How to &lt;a href="http://blog.gfader.com/2010/12/do-you-automate-your-deployment-process.html" target="_blank"&gt;automate your deployment with msbuild and msdeploy&lt;/a&gt;?&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;Check out my talk at the &lt;a href="http://www.ssw.com.au/ssw/NETUG/Sydney.aspx" target="_blank"&gt;SSW user group&lt;/a&gt; on the 20. July in Neutral Bay &lt;strong&gt;Not the Microsoft office in Ryde.&lt;/strong&gt;     &lt;br /&gt;The user group has *moved* from Microsoft to &lt;a href="http://www.ssw.com.au/ssw/Company/ContactUs.aspx#Sydney" target="_blank"&gt;SSW in Neutral Bay (How to get there)&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Watch this space for the slides and notes after the 20. July      &lt;br /&gt;You might even &lt;/em&gt;&lt;a href="http://feedburner.google.com/fb/a/mailverify?uri=PeterGfader" target="_blank"&gt;&lt;em&gt;subscribe via email&lt;/em&gt;&lt;/a&gt;&lt;em&gt; in the meantime &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh3.ggpht.com/-dEmq877ykPA/TgGTxmIzmgI/AAAAAAAAHJ8/7eZLDmhWWwo/wlEmoticon-winkingsmile2.png?imgmax=800" /&gt;&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-5841163591974518898?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/OMpwbNbW3ck" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/OMpwbNbW3ck/tired-of-manual-deployments.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-6B1pwu2biv0/TgGTvHldfJI/AAAAAAAAHJ0/c8NF5KVbgRI/s72-c/image3.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.gfader.com/2011/06/tired-of-manual-deployments.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-2114065680657323532</guid><pubDate>Wed, 15 Jun 2011 04:28:00 +0000</pubDate><atom:updated>2011-06-15T23:34:59.391+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">deployment</category><category domain="http://www.blogger.com/atom/ns#">TFS</category><category domain="http://www.blogger.com/atom/ns#">vs2010</category><title>TFS 2010 Build - Lesson learned --&gt; Treat warnings as errors</title><description>&lt;p&gt;We came across a weird issue with our TFS 2010 build server. We have an MVC3 web application where we added a new Silverlight application. Since we added that Silverlight application our build fails. We get error messages like these:&lt;/p&gt;  &lt;p&gt;#1    &lt;br /&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-kr3fDt-9x4c/Tfg0tqA3LvI/AAAAAAAAG8Q/RgpNH079Mm8/image%25255B11%25255D.png?imgmax=800" width="16" height="16" /&gt; C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets (1852): Copying file ClientBin\BuildAuction.xap to obj\Release\Package\PackageTmp\ClientBin\BuildAuction.xap failed. &lt;strong&gt;Could not find file&lt;/strong&gt; 'ClientBin\BuildAuction.&lt;strong&gt;xap'&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;#2    &lt;br /&gt;&lt;a href="http://lh6.ggpht.com/-7hV7E3kC6a4/Tfg0u_IqMBI/AAAAAAAAG8U/RUUW1hQkRsk/s1600-h/image%25255B15%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-0Q_m9QMivrU/Tfg0wLGQ4PI/AAAAAAAAG8Y/aNhn6BV6Rj0/image_thumb%25255B6%25255D.png?imgmax=800" width="16" height="16" /&gt;&lt;/a&gt; Copying file C:\Builds\4\WoolTradePlus\WooltradePlus - Build and Test on Checkin\Binaries\BuildAuction.xap failed. &lt;strong&gt;Access to the path&lt;/strong&gt; 'C:\Builds\4\WoolTradePlus\WooltradePlus - Build and Test on Checkin\Sources\trunk\WoolTradePlus\MvcApplicationXXX\ClientBin\BuildAuction.xap' is denied.&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-eRtnA0A6rPE/Tfg0yTfTkaI/AAAAAAAAG9Q/GhKoke5IoWs/image%25255B68%25255D.png?imgmax=800" width="324" height="286" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Spiderman and Batman to the rescue&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;em&gt;Here is my journey to fix this problem&lt;/em&gt;&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;#1    &lt;br /&gt;I changed the logging verbosity on our Build definition to &amp;quot;Diagnostic&amp;quot;.     &lt;br /&gt;&lt;em&gt;Same as you do in VS2010 under Tools Options. Explained as a &lt;/em&gt;&lt;a href="http://blog.gfader.com/2011/04/silverlight-5-easy-steps-to-obfuscate.html" target="_blank"&gt;&lt;em&gt;tip in this post about Silverlight obfuscation&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-xC5uyfURzNk/Tfkj7a6y48I/AAAAAAAAG-o/wuAhPFumr60/s1600-h/image16%25255B4%25255D.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="Logging verbosity on a Build definition in TFS 2010" border="0" alt="Logging verbosity on a Build definition" src="http://lh6.ggpht.com/-7LjdPxX_lfU/Tfg01KHxnKI/AAAAAAAAG-s/JhFdtNWdpWU/image16_thumb%25255B3%25255D.png?imgmax=800" width="784" height="220" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Change Logging verbosity to &amp;quot;Detailed&amp;quot;&lt;/p&gt;  &lt;p&gt;With that I was hoping to find some issue in the msbuild output.    &lt;br /&gt;No anomalies found… &lt;/p&gt;  &lt;p&gt;#2    &lt;br /&gt;I tried to &amp;quot;exclude&amp;quot; and &amp;quot;re-include&amp;quot; the XAP file, in order to re-trigger some VS2010 magic that happens behind the scenes.     &lt;br /&gt;&lt;a href="http://lh4.ggpht.com/-BUkx_u3-s-c/Tfg02kSJNdI/AAAAAAAAG8o/Sy3nsut6igs/s1600-h/image%25255B23%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Exclude XAP from Project" border="0" alt="Exclude XAP from Project" src="http://lh3.ggpht.com/-rmmeOfOBrIU/Tfg033BD4KI/AAAAAAAAG8s/7TXDbFaNmzI/image_thumb%25255B10%25255D.png?imgmax=800" width="519" height="638" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Exclude XAP from Project&lt;/p&gt;  &lt;p&gt;Now the build is fine!! But obviously the XAP file is then not in /ClientBin anymore… which is what we are after &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://lh3.ggpht.com/-j24IePvcMOk/Tfg05GEq0sI/AAAAAAAAG8w/8c-9RwpL4kA/wlEmoticon-winkingsmile%25255B2%25255D.png?imgmax=800" /&gt;.     &lt;br /&gt;When we deploy this project we need the XAP file in /ClientBin     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;#3    &lt;br /&gt;I deleted the XAP from source control and rebuild.     &lt;br /&gt;Good try, no change.     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;#4    &lt;br /&gt;I deleted the XAP and re added the Silverlight application through the web application properties dialog     &lt;br /&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="Re-Add Silverlight Application to the hosting web project" border="0" alt="Re-Add Silverlight Application to the hosting web project" src="http://lh3.ggpht.com/-xdBUx8Emc-k/Tfg06qaUrSI/AAAAAAAAG-w/vJU5sTN2V4E/image29%25255B4%25255D.png?imgmax=800" width="784" height="536" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Re-Add Silverlight Application to the hosting web project&lt;/p&gt;  &lt;p&gt;No luck with that one…&lt;/p&gt;  &lt;p&gt;#5    &lt;br /&gt;I changed the XAP &amp;quot;Build action&amp;quot; and &amp;quot;Copy to Output Directory&amp;quot;     &lt;br /&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Changing &amp;quot;Build Action&amp;quot; and &amp;quot;Copy to Output Directory&amp;quot;" border="0" alt="Changing &amp;quot;Build Action&amp;quot; and &amp;quot;Copy to Output Directory&amp;quot;" src="http://lh4.ggpht.com/-mtJsDrgI_Dg/Tfg07pv9auI/AAAAAAAAG84/9PQMqQD6kE4/image%25255B40%25255D.png?imgmax=800" width="727" height="315" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Changing &amp;quot;Build Action&amp;quot; and &amp;quot;Copy to Output Directory&amp;quot;&lt;/p&gt;  &lt;p&gt;Setting &amp;quot;Build Action&amp;quot; to &amp;quot;None&amp;quot; will fix the build, but not include the XAP as part of the web deployment package…    &lt;br /&gt;Not a solution     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;#6    &lt;br /&gt;I tried to reproduce this problem with a &lt;strong&gt;new solution&lt;/strong&gt; and had no luck with that. I did a &amp;quot;File New MVC3 app&amp;quot; and &amp;quot;File New Silverlight App&amp;quot; and Check In to source control.     &lt;br /&gt;Build server is happy and web deployment package holds the XAP file.     &lt;br /&gt;No repro!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;#7    &lt;br /&gt;I tried to reproduce this on the &lt;strong&gt;existing solution&lt;/strong&gt;. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;I added a new Silverlight application and hosting in the same MVC web application. FAIL! &lt;/li&gt;    &lt;li&gt;I added a new MVC3 web application and used that to host the Silverlight application. SUCCESS! &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;That told me that it is something with my existing MVC3 web application.&lt;/p&gt;  &lt;p&gt;I did a &amp;quot;Compare&amp;quot; of the &lt;strong&gt;non-working &lt;/strong&gt;.csproj file with the &lt;strong&gt;working&lt;/strong&gt; new one. &lt;/p&gt;  &lt;p&gt;The first difference that I found was&lt;/p&gt;  &lt;p&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="&amp;quot;Folder Include&amp;quot; missing on the existing web app" border="0" alt="&amp;quot;Folder Include&amp;quot; missing on the existing web app" src="http://lh3.ggpht.com/-xaTz90WCxkE/Tfg08o0ArOI/AAAAAAAAG-0/EhtMwHcKuuE/image41%25255B4%25255D.png?imgmax=800" width="784" height="58" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: &amp;quot;Folder Include&amp;quot; missing on the existing web app&lt;/p&gt;  &lt;p&gt;I added the &amp;quot;Folder include&amp;quot;, but didn't fix the build on TFS&lt;/p&gt;  &lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Folder&lt;/span&gt; &lt;span class="attr"&gt;Include&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;App_Data\&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
&lt;font style="background-color: #ffff00"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Folder&lt;/span&gt; &lt;span class="attr"&gt;Include&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ClientBin\&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
&lt;/font&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Folder&lt;/span&gt; &lt;span class="attr"&gt;Include&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Areas\Admin\Views\Shared\&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;#8 
  &lt;br /&gt;The next difference in the 2 csproj files was 

  &lt;br /&gt;&lt;a href="http://lh6.ggpht.com/-Rqyooa4ykhQ/Tfkk71YJEAI/AAAAAAAAG-4/oZA8S08R43M/s1600-h/image47%25255B4%25255D.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="The existing &amp;quot;broken&amp;quot; hosting web app was importing &amp;quot;Microsoft.Web.Publishing.targets&amp;quot; " border="0" alt="The existing &amp;quot;broken&amp;quot; hosting web app was importing &amp;quot;Microsoft.Web.Publishing.targets&amp;quot; " src="http://lh6.ggpht.com/-akka2M8l7Yk/Tfg0_IUp0kI/AAAAAAAAG-8/s9Z6Nq7OwR8/image47_thumb%25255B3%25255D.png?imgmax=800" width="784" height="143" /&gt;&lt;/a&gt; 

  &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: The existing &amp;quot;broken&amp;quot; hosting web app was importing &amp;quot;Microsoft.Web.Publishing.targets&amp;quot; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I saw a warning with this &amp;quot;msbuild target&amp;quot; as part of the build before, but I never worried about that warning before.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&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="image" border="0" alt="image" src="http://lh5.ggpht.com/-iuyzzHoBVNc/Tfg1AeWfsNI/AAAAAAAAG_A/1E_0F8n9mFs/image%25255B4%25255D.png?imgmax=800" width="784" height="412" /&gt;&lt;strong&gt; 
    &lt;br /&gt;Figure&lt;/strong&gt;: Error on TFS Build: Copying file ClientBin\BuildAuction.xap to obj\Release\Package\PackageTmp\ClientBin\BuildAuction.xap failed. Could not find file 'ClientBin\BuildAuction.xap'.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;This warning comes from importing the &amp;quot;Microsoft.Web.Publishing.targets&amp;quot; in the .csproj file.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;As part of my journey I fixed that warning by removing that Import. 
  &lt;br /&gt;Suddenly the build is green and our web deployment package holds the XAP file. 

  &lt;br /&gt;WOOOT! 

  &lt;br /&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-oKu_Umo9bQI/Tfg1B-F_b3I/AAAAAAAAG9M/-P9NcgvGVuE/image%25255B64%25255D.png?imgmax=800" width="131" height="190" /&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I never thought a msbuild warning could break the build. But it did in this case… 
    &lt;br /&gt;The issue here is [2] in the screen above. The 2nd import of these build targets causes the build process to fail and that fails the whole build. Arrgghhh!!! So…. what should be an &amp;quot;Error&amp;quot; is a &amp;quot;Warning&amp;quot; here…&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-2114065680657323532?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/Je1d-6Fw6pE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/Je1d-6Fw6pE/tfs-2010-build-lesson-learned-treat.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-kr3fDt-9x4c/Tfg0tqA3LvI/AAAAAAAAG8Q/RgpNH079Mm8/s72-c/image%25255B11%25255D.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.gfader.com/2011/06/tfs-2010-build-lesson-learned-treat.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-4385293517806838646</guid><pubDate>Thu, 09 Jun 2011 02:53:00 +0000</pubDate><atom:updated>2011-06-09T05:05:06.492+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">deployment</category><category domain="http://www.blogger.com/atom/ns#">TFS</category><title>Running NUnit Tests in TFS 2010 Continuous Build Environment</title><description>&lt;p&gt;&lt;em&gt;I tried different ways to run nunit on our build server.      &lt;br /&gt;From &lt;/em&gt;&lt;a href="http://nunit4teambuild.codeplex.com/" target="_blank"&gt;&lt;em&gt;&amp;quot;NUnit for Team Build&amp;quot;&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, to &lt;/em&gt;&lt;a href="http://stackoverflow.com/questions/2478603/how-to-integrate-nunit-tests-into-a-tfs-2010-build/2498185#2498185" target="_blank"&gt;&lt;em&gt;&amp;quot;executing nunit-console on cmd&amp;quot;&lt;/em&gt;&lt;/a&gt;&lt;em&gt; and eventually customizing our project files…      &lt;br /&gt;None of those methods made me happy.       &lt;br /&gt;&lt;/em&gt;&lt;a href="http://lh4.ggpht.com/-QW9WTDT2m8Y/TfA4W93gPOI/AAAAAAAAG70/0jfP0l4n8iY/s1600-h/image%25255B3%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-YRxYguHHTxo/TfA4YPkjgjI/AAAAAAAAG74/XL2cZcB-rZw/image_thumb%25255B1%25255D.png?imgmax=800" width="240" height="180" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Sad - Broken builds and mucking around with XML make dev's unhappy&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt; &lt;p&gt;   &lt;br /&gt;The best way (and most important *working* way) is by customizing the build template.&lt;/p&gt;  &lt;p&gt;By using the customization from Shawn Wallace I was able to run nunit tests on the build server and get a nice output if a test fails.    &lt;br /&gt;&lt;a title="http://blog.shawnewallace.com/2011/02/running-nunit-tests-in-tfs-2010.html" href="http://blog.shawnewallace.com/2011/02/running-nunit-tests-in-tfs-2010.html" target="_blank"&gt;http://blog.shawnewallace.com/2011/02/running-nunit-tests-in-tfs-2010.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I am writing this up, because I have 3 comments on his build template change&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;I removed all '&lt;font face="Courier New"&gt;&lt;em&gt;sap:&lt;/em&gt;&lt;/font&gt;' attributes from his XML in order to get it working on our TFS 2010 &lt;/li&gt;    &lt;li&gt;Make sure to &lt;font style="background-color: #ffff00"&gt;customize the path&lt;/font&gt; of the nunit-console runner       &lt;br /&gt;&amp;#160; Search for nunit-console in the template and replace the path &lt;/li&gt;    &lt;li&gt;Add the below XML before the 1st occurrence of '&lt;font face="Courier New"&gt;&lt;em&gt;&amp;lt;If Condition=&amp;quot;[Not DisableTests]&amp;quot;&lt;/em&gt;&lt;/font&gt;' &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;The resulting template looks like this&lt;/p&gt;  &lt;pre class="csharpcode"&gt;                  
                          &lt;span class="rem"&gt;&amp;lt;!-- *********** START:  Unit Testing *********** --&amp;gt;&lt;/span&gt;
                        
                        
                          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;If&lt;/span&gt; &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[Not DisableTests]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;If Not DisableTests&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;If.Then&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                              &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Run Tests&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sequence.Variables&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Variable&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;scg:IEnumerable(x:String)&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;testAssemblies&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Variable&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;mtbwa:TestAssemblySpec&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;testAssembly&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Variable&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;mtbwa:TestAssemblySpec&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;testAssemblySpec&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sequence.Variables&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                
                                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ForEach&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;mtbwa:TestSpec&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;ForEach&amp;amp;lt;TestSpec&amp;amp;gt;&amp;quot;&lt;/span&gt;  &lt;span class="attr"&gt;Values&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[TestSpecs]&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ActivityAction&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;mtbwa:TestSpec&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ActivityAction.Argument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DelegateInArgument&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;mtbwa:TestSpec&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;testSpec&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ActivityAction.Argument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sequence.Variables&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Variable&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;testAssemblyMatchPattern&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sequence.Variables&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:WriteBuildMessage&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Write outputDirectory&amp;quot;&lt;/span&gt;  &lt;span class="attr"&gt;Importance&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Message&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[&amp;amp;quot;outputDirectory is: &amp;amp;quot; + outputDirectory]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;mva:VisualBasic&lt;/span&gt;.&lt;span class="attr"&gt;Settings&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Assembly references and imported namespaces serialized as XML namespaces&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Cast&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;mtbwa:TestSpec, mtbwa:TestAssemblySpec&amp;quot;&lt;/span&gt;  &lt;span class="attr"&gt;Operand&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[testSpec]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Result&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[testAssemblySpec]&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:WriteBuildMessage&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Write testAssemblySpec.AssemblyFileSpec&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Importance&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Message&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[&amp;amp;quot;testAssemblySpec.AssemblyFileSpec is: &amp;amp;quot; + testAssemblySpec.AssemblyFileSpec]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;mva:VisualBasic&lt;/span&gt;.&lt;span class="attr"&gt;Settings&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Assembly references and imported namespaces serialized as XML namespaces&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign.To&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;OutArgument&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;[testAssemblyMatchPattern]&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;OutArgument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign.To&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign.Value&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;InArgument&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;[String.Format(&amp;quot;{0}\{1}&amp;quot;, outputDirectory, testAssemblySpec.AssemblyFileSpec)]&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;InArgument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign.Value&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:WriteBuildMessage&lt;/span&gt;  &lt;span class="attr"&gt;Importance&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Message&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[&amp;amp;quot;testAssemblyMatchPattern: &amp;amp;quot; + testAssemblyMatchPattern]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;mva:VisualBasic&lt;/span&gt;.&lt;span class="attr"&gt;Settings&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Assembly references and imported namespaces serialized as XML namespaces&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:FindMatchingFiles&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Find Test Assemblies --&amp;amp;gt; testAssemblies&amp;quot;&lt;/span&gt;  &lt;span class="attr"&gt;MatchPattern&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[testAssemblyMatchPattern]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Result&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[testAssemblies]&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                      
                                      &lt;span class="rem"&gt;&amp;lt;!-- Assign value to treatTestFailureAsBuildFailure --&amp;gt;&lt;/span&gt;
                                      
                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign.To&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;OutArgument&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:Boolean&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;[treatTestFailureAsBuildFailure]&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;OutArgument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign.To&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign.Value&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;InArgument&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:Boolean&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;[testSpec.FailBuildOnFailure]&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;InArgument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign.Value&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;If&lt;/span&gt; &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[testAssemblies.Count() &amp;amp;gt; 0]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;If Test Assemblies Found&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;If.Then&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Run NUnit&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ForEach&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Loop through all Test Assemblies&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Values&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[testAssemblies]&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                              &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ActivityAction&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ActivityAction.Argument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DelegateInArgument&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;item&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                                &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ActivityAction.Argument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sequence.Variables&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Variable&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;assemblyName&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Variable&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;testResultXmlPath&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Variable&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;variable1&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                                  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sequence.Variables&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Get Assembly Name&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign.To&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;OutArgument&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;[assemblyName]&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;OutArgument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign.To&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign.Value&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;InArgument&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;[item.Substring(item.LastIndexOf(&amp;quot;\&amp;quot;) + 1)]&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;InArgument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign.Value&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Get Test Result Path&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign.To&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;OutArgument&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;[testResultXmlPath]&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;OutArgument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign.To&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign.Value&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;InArgument&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;[String.Format(&amp;quot;{0}\{1}.ResultXml.xml&amp;quot;, logFileDropLocation, assemblyName)]&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;InArgument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign.Value&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:WriteBuildMessage&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Write testResultXmlPath&amp;quot;&lt;/span&gt;  &lt;span class="attr"&gt;Importance&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Message&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[&amp;amp;quot;testResultXmlPath: &amp;amp;quot; + testResultXmlPath]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;mva:VisualBasic&lt;/span&gt;.&lt;span class="attr"&gt;Settings&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Assembly references and imported namespaces serialized as XML namespaces&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                                  
                                                 &lt;span class="rem"&gt;&amp;lt;!-- Execute NUnit tests --&amp;gt;&lt;/span&gt;
                                                  
                                                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:InvokeProcess&lt;/span&gt; &lt;span class="attr"&gt;Arguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[String.Format(&amp;amp;quot;&amp;amp;quot;&amp;amp;quot;{0}&amp;amp;quot;&amp;amp;quot; /xml:&amp;amp;quot;&amp;amp;quot;{1}&amp;amp;quot;&amp;amp;quot; /nologo /nodots&amp;amp;quot;, item, testResultXmlPath)]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Execute NUnit&amp;quot;&lt;/span&gt; &lt;font style="background-color: #ffff00"&gt;&lt;span class="attr"&gt;FileName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;c:\Program Files (x86)\NUnit 2.5.10\bin\net-2.0\nunit-console.exe&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;/font&gt;                                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:InvokeProcess.ErrorDataReceived&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ActivityAction&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ActivityAction.Argument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DelegateInArgument&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;errOutput&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                                        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ActivityAction.Argument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:WriteBuildError&lt;/span&gt;  &lt;span class="attr"&gt;Message&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[errOutput]&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                                      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ActivityAction&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;mtbwa:InvokeProcess.ErrorDataReceived&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:InvokeProcess.OutputDataReceived&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ActivityAction&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ActivityAction.Argument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;DelegateInArgument&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;stdOutput&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                                        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ActivityAction.Argument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                          
                                                          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:WriteBuildMessage&lt;/span&gt;  &lt;span class="attr"&gt;Importance&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Message&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[&amp;amp;#x9;  stdOutput]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;mva:VisualBasic&lt;/span&gt;.&lt;span class="attr"&gt;Settings&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Assembly references and imported namespaces serialized as XML namespaces&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                                          
                                                          &lt;span class="rem"&gt;&amp;lt;!-- if test output contains errors or failures --&amp;gt;&lt;/span&gt;
                                                          
                                                          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;If&lt;/span&gt; &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[(Not stdOutput.Contains(&amp;amp;quot;Failures: 0&amp;amp;quot;) And stdOutput.Contains(&amp;amp;quot;Failures:&amp;amp;quot;)) Or&amp;amp;#xA;(Not stdOutput.Contains(&amp;amp;quot;Errors: 0&amp;amp;quot;) And stdOutput.Contains(&amp;amp;quot;Errors:&amp;amp;quot;))]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;If there were failed tests&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;If.Then&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                              &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                
                                                                &lt;span class="rem"&gt;&amp;lt;!-- put build test status in failed state --&amp;gt;&lt;/span&gt;
                                                                
                                                                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign.To&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;OutArgument&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;mtbc:BuildPhaseStatus&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;[BuildDetail.TestStatus]&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;OutArgument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign.To&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign.Value&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;InArgument&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;mtbc:BuildPhaseStatus&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed]&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;InArgument&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign.Value&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Assign&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                
                                                                &lt;span class="rem"&gt;&amp;lt;!-- if treatTestFailureAsBuildFailure create build error, else create build warning --&amp;gt;&lt;/span&gt;
                                                                
                                                                &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;If&lt;/span&gt; &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[treatTestFailureAsBuildFailure]&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;If.Then&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:WriteBuildError&lt;/span&gt;  &lt;span class="attr"&gt;Message&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[assemblyName &amp;amp;amp; &amp;amp;quot; -&amp;amp;gt; &amp;amp;quot; &amp;amp;amp; stdOutput]&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                                                  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;If.Then&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;If.Else&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:WriteBuildWarning&lt;/span&gt;  &lt;span class="attr"&gt;Message&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[assemblyName &amp;amp;amp; &amp;amp;quot; -&amp;amp;gt; &amp;amp;quot; &amp;amp;amp; stdOutput]&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
                                                                  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;If.Else&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                                &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;If&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                              &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;If.Then&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                          &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;If&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ActivityAction&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;mtbwa:InvokeProcess.OutputDataReceived&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;mtbwa:InvokeProcess&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                                  
                                                  &lt;span class="rem"&gt;&amp;lt;!-- end EXECUTE NUnit tests --&amp;gt;&lt;/span&gt;
                                                  
                                                &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                              &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ActivityAction&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ForEach&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                          &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;If.Then&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;If&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ActivityAction&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                                &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ForEach&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                              &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;If.Then&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                          &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;If&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                        
                        
                          &lt;span class="rem"&gt;&amp;lt;!-- *********** END:  Unit Testing *********** --&amp;gt;&lt;/span&gt;
                        &lt;/pre&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Thanks &lt;a href="http://twitter.com/shawnwallace" target="_blank"&gt;Shawn&lt;/a&gt;!!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-4385293517806838646?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/HqFVWn8b-zw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/HqFVWn8b-zw/running-nunit-tests-in-tfs-2010.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-YRxYguHHTxo/TfA4YPkjgjI/AAAAAAAAG74/XL2cZcB-rZw/s72-c/image_thumb%25255B1%25255D.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.gfader.com/2011/06/running-nunit-tests-in-tfs-2010.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-263787514437345552</guid><pubDate>Fri, 20 May 2011 00:52:00 +0000</pubDate><atom:updated>2011-05-20T02:52:26.086+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">silverlight</category><title>A better EBay in Silverlight</title><description>&lt;p&gt;Thanks everyone for 2 great user group nights.    &lt;br /&gt;Here are my slides and my most important slide, based on &lt;a href="http://www.paulstovell.com/presentation-technologies" target="_blank"&gt;Paul Stovell's blog post&lt;/a&gt; &lt;a name='more'&gt;&lt;/a&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;If you are facing a technology decision, consider&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Existing Team knowledge &lt;/li&gt;    &lt;li&gt;Your target audience (User, OS, browser, devices, …) &lt;/li&gt;    &lt;li&gt;Technology limitations &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Ask yourself: What gets you there faster?&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="Use Silverlight plugin" src="http://lh5.ggpht.com/_7U9eu-U3X-8/TdW7OO87v9I/AAAAAAAAG7U/atFdW9NgKdk/image%5B7%5D.png?imgmax=800" width="618" height="480" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: My workflow on deciding on a technology, based on &lt;a href="http://www.paulstovell.com/presentation-technologies" target="_blank"&gt;Paul Stovell's workflow&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Here the slides&lt;/p&gt;  &lt;div style="width: 425px" id="__ss_8033461"&gt;&lt;strong style="margin: 12px 0px 4px; display: block"&gt;&lt;a title="Silverlight vs HTML5 - Lessons learned from the real world..." href="http://www.slideshare.net/PeterGfader/silverlight-vs-html5-lessons-learned-from-the-real-world"&gt;Silverlight vs HTML5 - Lessons learned from the real world...&lt;/a&gt;&lt;/strong&gt; &lt;iframe height="355" marginheight="0" src="http://www.slideshare.net/slideshow/embed_code/8033461" frameborder="0" width="425" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;    &lt;div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/PeterGfader"&gt;Peter Gfader&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;BTW: Our software is going to be on Australian TV. Stay tuned!!&lt;/p&gt;  &lt;p&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="image" border="0" alt="image" src="http://lh6.ggpht.com/_7U9eu-U3X-8/TdW7R5nt-RI/AAAAAAAAG7Y/K_sQSCx8Waw/image%5B14%5D.png?imgmax=800" width="931" height="1007" /&gt;    &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: On the screen in the middle you can see our main screen done in Silverlight    &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-263787514437345552?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/3wvgdBj0G5o" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/3wvgdBj0G5o/better-ebay-in-silverlight.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_7U9eu-U3X-8/TdW7OO87v9I/AAAAAAAAG7U/atFdW9NgKdk/s72-c/image%5B7%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.gfader.com/2011/05/better-ebay-in-silverlight.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-7128137252766235402</guid><pubDate>Mon, 09 May 2011 12:06:00 +0000</pubDate><atom:updated>2011-12-11T15:08:18.456+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Vs2008</category><category domain="http://www.blogger.com/atom/ns#">how to</category><category domain="http://www.blogger.com/atom/ns#">vs2010</category><category domain="http://www.blogger.com/atom/ns#">coding</category><title>3 keyboard productivity tips for VS2010 - "Look Ma no mouse"</title><description>&lt;p&gt;I am a big fan of little check-ins as often as possible during the day, instead of 1 big check-in at the end of the day.&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;Split tasks into smaller pieces and check-in every small change. Advantages of doing so:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Your focus is much higher because your code changes are smaller &lt;/li&gt;    &lt;li&gt;Less risk of merges and conflicts&lt;/li&gt;    &lt;li&gt;Every check-in is a kind of a &amp;quot;Done&amp;quot; (Isolate features!) &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;BTW: In order that everyone on your team can follow the life of your code base, you should setup email alerts on source control. So everyone can follow what's going on… &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Back to checkins!   &lt;br /&gt;A check-in has to be quick. That is the reason why I don't like Gated-Checkins. I don't want to wait for a Gated-Checkin to be finished.     &lt;br /&gt;It has to be quick!!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Now …&amp;#160; 3 quick keyboard tips for Visual Studio 2010&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;If you are coding along and you are done with the current task/feature/test/coding&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;#1 Do a Checkin!&lt;/strong&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&amp;lt;Ctrl&amp;gt;+&amp;lt;Alt&amp;gt;+&amp;lt;L&amp;gt;&amp;#160;&amp;#160; : Focus Solution Explorer &lt;/li&gt;    &lt;li&gt;WinRight&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : Open Contextmenu &lt;/li&gt;    &lt;li&gt;&amp;lt;I&amp;gt;,&amp;lt;I&amp;gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : Go to menu point &amp;quot;Check In&amp;quot; &lt;/li&gt;    &lt;li&gt;&amp;lt;Enter&amp;gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : Select &amp;quot;Check In&amp;quot; &lt;/li&gt;    &lt;li&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : Type comment &lt;/li&gt;    &lt;li&gt;&amp;lt;Alt&amp;gt; + &amp;lt;C&amp;gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; : Do the check in &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Done!   &lt;br /&gt;&lt;em&gt;Your build server will tell you if you did a good job, because &lt;/em&gt;&lt;a href="http://blog.gfader.com/2010/10/why-are-automated-tests-so-important.html" target="_blank"&gt;&lt;em&gt;you have a lot of automated tests&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;How to get back to the code window?&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;#2 Focus Code Editor&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Hit a couple of times &amp;lt;Esc&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;How can you close &amp;quot;Solution Explorer&amp;quot;, &amp;quot;Team Explorer&amp;quot; or other tool windows with the keyboard?&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;#3 Close tool window with current focus &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;Shift&amp;gt;+&amp;lt;Esc&amp;gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_7U9eu-U3X-8/TcfY1kE5wqI/AAAAAAAAG6E/KlBmNuWGQlU/image%5B4%5D.png?imgmax=800" width="408" height="301" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&amp;quot;Look Ma, no mouse&amp;quot;&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-7128137252766235402?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/Gds3_qhJvTk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/Gds3_qhJvTk/3-keyboard-productivity-tips-for-vs2010.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_7U9eu-U3X-8/TcfY1kE5wqI/AAAAAAAAG6E/KlBmNuWGQlU/s72-c/image%5B4%5D.png?imgmax=800" height="72" width="72" /><thr:total>8</thr:total><feedburner:origLink>http://blog.gfader.com/2011/05/3-keyboard-productivity-tips-for-vs2010.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-1401787989998621617</guid><pubDate>Fri, 06 May 2011 01:25:00 +0000</pubDate><atom:updated>2011-05-10T08:22:45.204+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mvc</category><category domain="http://www.blogger.com/atom/ns#">asp.net</category><category domain="http://www.blogger.com/atom/ns#">vs2010</category><title>Microsoft ASP.NET - Too many options</title><description>&lt;p&gt;&lt;strong&gt;&lt;span class="red"&gt;*Updated*&lt;/span&gt;&amp;#160;&lt;/strong&gt;10 May 2011: From Tarn's feedback: I made it more clear that the target audience &amp;quot;Beginners with ASP.NET&amp;quot; get confused.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;TL;DR&lt;/b&gt; &lt;/p&gt;  &lt;p&gt;I think Microsoft's message for beginners on ASP.NET is wrong, by suggesting we have 3 players for doing web development with MS tooling, as per &lt;a href="http://www.asp.net/get-started" target="_blank"&gt;http://www.asp.net/get-started&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;i&gt;Me thinks: There is &amp;quot;Web Pages&amp;quot;, &amp;quot;MVC&amp;quot; and &amp;quot;Webforms&amp;quot;, and tools: &amp;quot;WebMatrix&amp;quot; and &amp;quot;VS2010&amp;quot;.      &lt;br /&gt;But should we really suggest all of them?&lt;/i&gt;&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;-------------    &lt;br /&gt;Next week I am talking about &lt;a title="ASP.NET MVC at UTS" href="http://www.ssw.com.au/ssw/Training/VisualStudio.aspx" target="_blank"&gt;ASP.NET MVC at UTS&lt;/a&gt; because that's a bright future in my eyes.     &lt;br /&gt;&lt;i&gt;WebForms is still handy for some things (usercontrols, legacy,...), and obviously you can mix both together as much as you like…&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;I got a question regarding reference applications for ASP.NET from an UTS student and went to &lt;a title="asp.net get-started" href="http://www.asp.net/get-started" target="_blank"&gt;http://www.asp.net/get-started&lt;/a&gt; because this website should be our main entry point for MS web development. &lt;/p&gt;  &lt;p&gt;I was shocked!    &lt;br /&gt;Now we have a new player!&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ASP.NET portal" border="0" alt="ASP.NET getstartet portal" src="http://lh5.ggpht.com/_7U9eu-U3X-8/TcNN9E3JwJI/AAAAAAAAG5k/Q061IUwl3rg/clip_image001%5B6%5D.jpg?imgmax=800" width="630" height="364" /&gt;     &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: ASP.NET Get started shows &lt;strong&gt;3 options&lt;/strong&gt; for doing web development &lt;/p&gt;  &lt;p&gt;So…. Instead of 2 options: &amp;quot;WebForms&amp;quot; and &amp;quot;MVC&amp;quot;, we have another option here &amp;quot;Web Pages&amp;quot;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;I speak to so many dev's that struggle already with the options provided and are overwhelmed by all the different choices that we have: WebForms, MVC, Silverlight, HTML5, jQuery, WTF, … Confusing them with &amp;quot;Web Pages&amp;quot; is not a good idea &lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I think MS should make clear: &lt;/p&gt;  &lt;p&gt;As a Starter on ASP.NET use &amp;quot;WebMatrix&amp;quot; and &amp;quot;Web Pages&amp;quot;.    &lt;br /&gt;If you want to go Pro, get &amp;quot;VS2010&amp;quot; and use &amp;quot;MVC&amp;quot;. For legacy reasons or fancy user controls use &amp;quot;Web Forms&amp;quot;.&lt;/p&gt;  &lt;p&gt;&lt;strike&gt;We have 2 UI technologies: #1 Webforms and #2 MVC      &lt;br /&gt;We have 2 tools: #1 WebMatrix and #2 VS2010&lt;/strike&gt;&lt;/p&gt;  &lt;p&gt;What do you think?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-1401787989998621617?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/bbmGRZBQIMo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/bbmGRZBQIMo/microsoft-aspnet-too-many-options.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_7U9eu-U3X-8/TcNN9E3JwJI/AAAAAAAAG5k/Q061IUwl3rg/s72-c/clip_image001%5B6%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>9</thr:total><feedburner:origLink>http://blog.gfader.com/2011/05/microsoft-aspnet-too-many-options.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6538953.post-8310050367762655822</guid><pubDate>Thu, 28 Apr 2011 23:08:00 +0000</pubDate><atom:updated>2011-04-29T07:13:17.492+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">deployment</category><category domain="http://www.blogger.com/atom/ns#">TFS</category><title>TFS - Fail a build when the warning count increases</title><description>&lt;p&gt;I am a big fan of &amp;quot;measuring&amp;quot;, because &lt;strong&gt;what you don't measure you can't improve&lt;/strong&gt;.     &lt;br /&gt;Measuring over time allows us to establish a trend and the trend is often more interesting that the hard numbers. &lt;/p&gt;  &lt;p&gt;Trends that might be interesting are:&lt;/p&gt; &lt;a name='more'&gt;&lt;/a&gt;  &lt;ol&gt;   &lt;li&gt;Code Coverage: I don't care about 55.3%, 65.7% or even 85% Code Coverage.      &lt;br /&gt;I am more interested in the trend over time: How did Code Coverage change since last week? Since last month?       &lt;br /&gt;If it changes too much, maybe we have problem…       &lt;br /&gt;&lt;em&gt;BTW: If you have &amp;gt; 95% Code Coverage, send me an email… Keen to see your code and your tests!&lt;/em&gt;       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Max Request/second in stress test: What's the maximum number of requests that we can handle per second in our web application? Did it increase or decrease over time?      &lt;br /&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Jason Stangroome blogged about a quick XAML extension of the default build template, that &lt;a href="http://blog.codeassassin.com/2011/03/28/fail-a-build-when-the-warning-count-increases/" target="_blank"&gt;fails a build when the warning count increases&lt;/a&gt;.     &lt;br /&gt;This is great! Make sure to grab it and put it into your build.     &lt;br /&gt;And say Thanks to &lt;a href="http://twitter.com/#!/jstangroome" target="_blank"&gt;@jstangroome&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;I just added an output message to show me the current values (see the &lt;font style="background-color: #ffff00"&gt;yellow&lt;/font&gt;). Since it was not so easy to do, I include it here.&lt;/em&gt;&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;&amp;lt;!-- Insert this Sequence as one of the last children of the Sequence with DisplayName=&amp;quot;Compile and Test&amp;quot; --&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt; &lt;span class="attr"&gt;DisplayName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Fail Build if Warnings increase&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sequence.Variables&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Variable&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;mtbc:IBuildDetail&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;LastBuildDetail&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Variable&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:Int32&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;LastWarningCount&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Variable&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:Int32&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;WarningCount&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sequence.Variables&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;mtbc:IBuildDetail&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;To&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[LastBuildDetail]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[BuildDetail.BuildServer.GetBuild(BuildDetail.BuildDefinition.LastBuildUri)]&amp;quot;&lt;/span&gt;  &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:Int32&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;To&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[LastWarningCount]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[Microsoft.TeamFoundation.Build.Client.InformationNodeConverters.GetBuildWarnings(LastBuildDetail).Count]&amp;quot;&lt;/span&gt;  &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Assign&lt;/span&gt; &lt;span class="attr"&gt;x:TypeArguments&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;x:Int32&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;To&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[WarningCount]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[Microsoft.TeamFoundation.Build.Client.InformationNodeConverters.GetBuildWarnings(BuildDetail).Count]&amp;quot;&lt;/span&gt;  &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;

&lt;font style="background-color: #ffff00"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:WriteBuildMessage&lt;/span&gt; &lt;span class="attr"&gt;Importance&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Message&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[String.Format(&amp;amp;quot;LastWarningCount: {0}.  WarningCount: {1} &amp;amp;quot;, LastWarningCount, WarningCount)]&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/font&gt;

  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;If&lt;/span&gt; &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;[WarningCount &amp;amp;gt; LastWarningCount]&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;If.Then&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:WriteBuildError&lt;/span&gt; &lt;span class="attr"&gt;Message&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;This build has more warnings than the last build. Focus on fixing more build warnings than are introduced.&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;&amp;lt;!-- The follow SetBuildProperties line will mark the build as Failed instead of just Partially Successful if the warning count has increased. --&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mtbwa:SetBuildProperties&lt;/span&gt; &lt;span class="attr"&gt;PropertiesToSet&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Status&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Status&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Failed&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;If.Then&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;If&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Sequence&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Fail build, when Warning count increased since last build 

&lt;p&gt;&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&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="image" border="0" alt="image" src="http://lh4.ggpht.com/_7U9eu-U3X-8/TbpI6D-NIII/AAAAAAAAG4Q/UjBKf1WVehA/image%5B5%5D.png?imgmax=800" width="1178" height="340" /&gt;

  &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: Build failed cause too many warning&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&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="image" border="0" alt="image" src="http://lh6.ggpht.com/_7U9eu-U3X-8/TbpI62v4k9I/AAAAAAAAG4U/7Tf4D4XrO2Q/image%5B11%5D.png?imgmax=800" width="1200" height="324" /&gt;

  &lt;br /&gt;&lt;strong&gt;Figure&lt;/strong&gt;: &amp;quot;View Log&amp;quot; shows you the details: Warnings increased from 0 to 20&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Thanks Jason!!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now I am off to write some XAML for my code coverage numbers, and max req/sec… 
    &lt;br /&gt;CU later&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6538953-8310050367762655822?l=blog.gfader.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/PeterGfader/~4/rAMVWZKfQgM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/PeterGfader/~3/rAMVWZKfQgM/tfs-fail-build-when-warning-count.html</link><author>noreply@blogger.com (Peter Gfader)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_7U9eu-U3X-8/TbpI6D-NIII/AAAAAAAAG4Q/UjBKf1WVehA/s72-c/image%5B5%5D.png?imgmax=800" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://blog.gfader.com/2011/04/tfs-fail-build-when-warning-count.html</feedburner:origLink></item></channel></rss>

