﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com/blog/</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2012 (c) 2013</copyright><ttl>60</ttl><item><title>Don’t play peekaboo with support, damn it!</title><description>&lt;p&gt;One of the things that we really pride ourselves with Hibernating Rhinos is the level of support. Just to give you some idea, today &amp;amp; yesterday we had core team members on the phone with people (not customers, yes) who are having problems with RavenDB for quite some time.&lt;/p&gt; &lt;p&gt;Now, I understand that you may not always have the information to give, but what you have, give me! So I can help you.&lt;/p&gt; &lt;p&gt;From a recent exchange in the mailing list:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;var clickCount = session.Query&amp;lt;TrackerRequest&amp;gt;().Where(t =&amp;gt; t.TrackerCreated == doc.Created).Where(t =&amp;gt; t.Type == Type.Click).Count();  &lt;p&gt;This gives:  &lt;p&gt;"Non-static method requires a target"&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;To which I replied:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;What is the full error that you get? Compile time? Runtime?&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The answer I got:  &lt;blockquote&gt; &lt;p&gt;This is a document I'm trying to 'Count':  &lt;p&gt;{  &lt;p&gt;&amp;nbsp; "Created": "2012-11-15T16:12:42.1775747",  &lt;p&gt;&amp;nbsp; "IP": "127.0.0.1",  &lt;p&gt;&amp;nbsp; "TrackerCreated": "2012-11-15T14:12:16.3951000Z",  &lt;p&gt;&amp;nbsp; "Referrer": "&lt;a href="http://example.com/"&gt;http://example.com&lt;/a&gt;",  &lt;p&gt;&amp;nbsp; "Type": "Click"  &lt;p&gt;}  &lt;p&gt;Raven terminal gives:  &lt;p&gt;Request # 172: GET&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3 ms - &amp;lt;system&amp;gt;&amp;nbsp;&amp;nbsp; - 200 - /indexes/Raven/DocumentsByEntityName?query=Tag%253ATrackerRequests&amp;amp;start=0&amp;amp;pageSize=30&amp;amp;aggregation=None&amp;amp;noCache=-1129797484  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Query: Tag:TrackerRequests  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Time: 2 ms  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Index: Raven/DocumentsByEntityName  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Results: 3 returned out of 3 total.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;By the way, you might note that this ISN’T related in any way to his issue. This query (and document) were gotten from the Studio. I can tell by the URL.  &lt;p&gt;Then there was this: &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Dont-play-peekaboo-with-support-damn-it_FD5E/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 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://ayende.com/blog/Images/Windows-Live-Writer/Dont-play-peekaboo-with-support-damn-it_FD5E/image_thumb.png" width="748" height="317"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I mean, seriously, I am happy to provide support, even if you aren’t a customer yet, but don’t give me some random bit of information that has absolutely nothing to do to the problem at hand and expect me to guess what the issue is.  &lt;p&gt;Relevant information like the stack trace, what build you are on, what classes are involved, etc are expected.&lt;/p&gt;</description><link>http://ayende.com/blog/159905/dont-play-peekaboo-with-support-damn-it?key=8404e2a7-a95c-4d70-af92-920b57df2b63</link><guid>http://ayende.com/blog/159905/dont-play-peekaboo-with-support-damn-it?key=8404e2a7-a95c-4d70-af92-920b57df2b63</guid><pubDate>Tue, 20 Nov 2012 10:00:00 GMT</pubDate></item><item><title>Negative hiring decisions, Part I</title><description>&lt;p&gt;One of the things that I &lt;em&gt;really&lt;/em&gt; hate is to be reminded anew how stupid some people are. Or maybe it is how stupid they think I am.&amp;nbsp; One of the things that we are doing during interviews is to ask candidates to do some fairly simple code tasks. Usually, I give them an hour or two to complete that (using VS and a laptop), and if they don’t complete everything, they can do that at home and send me the results.&lt;/p&gt; &lt;p&gt;This is a piece of code that one such candidate has sent. To be clear, this is something that the candidate has worked on at &lt;em&gt;home&lt;/em&gt; and had as much time for as she wanted:&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; GetTaxs(&lt;span class="kwrd"&gt;int&lt;/span&gt; salary)
{
    &lt;span class="kwrd"&gt;double&lt;/span&gt;  net, tax;

    &lt;span class="kwrd"&gt;switch&lt;/span&gt; (salary)
    {
        &lt;span class="kwrd"&gt;case&lt;/span&gt; &amp;lt; 5070:
            tax = salary  * 0.1;
            net=  salary  - tax ;
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;

        &lt;span class="kwrd"&gt;case&lt;/span&gt; &amp;lt; 8660:
        &lt;span class="kwrd"&gt;case&lt;/span&gt; &amp;gt; 5071:
            tax = (salary - 5071)*0.14;
            tax+= 5070 * 0.1;
            net = salary-tax;   
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;
        &lt;span class="kwrd"&gt;case&lt;/span&gt; &amp;lt; 14070:
        &lt;span class="kwrd"&gt;case&lt;/span&gt; &amp;gt; 8661:
            tax=  (salary - 8661)*0.23;
            tax+= (8661 - 5071 )*0.14;
            tax+= 5070 *0.1;
            net=  salary - tax;
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;
        &lt;span class="kwrd"&gt;case&lt;/span&gt; &amp;lt;21240:
        &lt;span class="kwrd"&gt;case&lt;/span&gt; &amp;gt;14071:
            tax=  (salary- 14071)*0.3;
            tax+= (14070 - 8661)*0.23;
            tax+= (8661 - 5071 )*0.14;
            tax+= 5070 *0.1;
            net= salary - tax;
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;
        &lt;span class="kwrd"&gt;case&lt;/span&gt; &amp;lt;40230:
        &lt;span class="kwrd"&gt;case&lt;/span&gt; &amp;gt;21241:
            tax=  (salary- 21241)*0.33;
            tax+= (21240 - 14071)*0.3;
            tax+= (14070 - 8661)*0.23;
            tax+= (8661 - 5071 )*0.14;
            tax+= 5070 *0.1;
            net= salary - tax;
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;
        &lt;span class="kwrd"&gt;case&lt;/span&gt; &amp;gt; 40230:
            tax= (salary - 40230)*0.45;
            tax+=  (40230- 21241)*0.33;
            tax+= (21240 - 14071)*0.3;
            tax+= (14070 - 8661)*0.23;
            tax+= (8661 - 5071 )*0.14;
            tax+= 5070 *0.1;
            net= salary - tax;
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;
        &lt;span class="kwrd"&gt;default&lt;/span&gt;:
            &lt;span class="kwrd"&gt;break&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;/blockquote&gt;
&lt;p&gt;Submitting code that &lt;em&gt;doesn’t actually compiles&lt;/em&gt; is a great way to pretty much &lt;em&gt;ensures&lt;/em&gt; that I won’t hire you.&lt;/p&gt;</description><link>http://ayende.com/blog/102401/negative-hiring-decisions-part-i?key=b63a56cb-924d-409b-bcc2-fe956d1f36a4</link><guid>http://ayende.com/blog/102401/negative-hiring-decisions-part-i?key=b63a56cb-924d-409b-bcc2-fe956d1f36a4</guid><pubDate>Thu, 22 Sep 2011 09:00:00 GMT</pubDate></item><item><title>Tales from a code review gone wrong</title><description>&lt;blockquote&gt;Originally posted at 2/23/2011&lt;/blockquote&gt;&lt;p&gt;Yes, I know that the NHibernate documentation says that you should override Equals and GetHashCode, but I get the feeling that this wasn’t what the documentation authors intended:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/Tales-from-a-code-review-gone-wrong_DB95/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 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://ayende.com/Blog/images/ayende_com/Blog/Windows-Live-Writer/Tales-from-a-code-review-gone-wrong_DB95/image_thumb.png" width="244" height="66" /&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://ayende.com/blog/4772/tales-from-a-code-review-gone-wrong?key=6c477238-b6e8-4914-bea2-d2948d7b7b71</link><guid>http://ayende.com/blog/4772/tales-from-a-code-review-gone-wrong?key=6c477238-b6e8-4914-bea2-d2948d7b7b71</guid><pubDate>Thu, 24 Feb 2011 10:00:00 GMT</pubDate></item><item><title>You saved 5 cents, and your code is not readable, congrats!</title><description>&lt;p&gt;I found myself reading &lt;a href="http://blog.boxedice.com/2009/07/25/choosing-a-non-relational-database-why-we-migrated-from-mysql-to-mongodb/"&gt;this post&lt;/a&gt;, and at some point, I really wanted to cry:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;We had relatively long, descriptive names in MySQL such as timeAdded or valueCached. For a small number of rows, this extra storage only amounts to a few bytes per row, but when you have 10 million rows, each with maybe 100 bytes of field names, then you quickly eat up disk space unnecessarily. 100 * 10,000,000 = ~900MB just for field names!&lt;/p&gt;    &lt;p&gt;We cut down the names to 2-3 characters. This is a little more confusing in the code but the disk storage savings are worth it. And if you use sensible names then it isn’t that bad e.g. timeAdded -&amp;gt; tA. A reduction to about 15 bytes per row at 10,000,000 rows means ~140MB for field names – a massive saving.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Let me do the math for a second, okay?&lt;/p&gt;  &lt;p&gt;A &lt;em&gt;two terabyte hard drive &lt;/em&gt;now costs &lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16822136344"&gt;120 USD&lt;/a&gt;. By my math, that makes:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;1 TB = 60 USD&lt;/li&gt;    &lt;li&gt;1 GB = 0.058 USD&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In other words, that &lt;em&gt;massive&lt;/em&gt; saving that they are talking about? 5 cents!&lt;/p&gt;  &lt;p&gt;Let me do another math problem, oaky?&lt;/p&gt;  &lt;p&gt;Developer costs about &lt;a href="http://www.payscale.com/research/US/Job=C%2523_Developer/Salary"&gt;75,000 USD per year&lt;/a&gt;.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;(52 weeks – 2 vacation weeks) x 40 work hours = 2,000 work hours per year.&lt;/li&gt;    &lt;li&gt;75,000 / 2,000 = 37.5 $ / hr&lt;/li&gt;    &lt;li&gt;37.5 / 60 minutes = 62 cents per minutes.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In other words, assuming that this change cost a &lt;em&gt;single minute of developer time, &lt;/em&gt;the entire saving is worse than moot.&lt;/p&gt;  &lt;p&gt;And it is going to take a &lt;em&gt;lot&lt;/em&gt; more than one minute.&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Update:&lt;/b&gt; Fixed decimal placement error in the cost per minute. Fixed mute/moot issue. 
&lt;/p&gt;
&lt;p&gt;
To those of you pointing out that real server storage space is much higher. You are correct, of course. I am trying to make a &lt;i&gt;point&lt;/i&gt;. Even assuming that it costs &lt;i&gt;two orders of magnitudes&lt;/i&gt; higher than what I said, that is still only 5$. Are you going to tell me that saving the price of a single cup of coffee is actually meaningful?
&lt;/p&gt;
&lt;p&gt;To those of you pointing out that MongoDB effectively stores the entire DB in memory. The post talked about disk size, not about memory, but even so, that is still not relevant. Mostly because MongoDB only requires indexes to fit in memory, and (presumably) indexes don't really need to store the field name per each indexed entry. If they do, then there is something very wrong with the impl.
&lt;/p&gt;</description><link>http://ayende.com/blog/4669/you-saved-5-cents-and-your-code-is-not-readable-congrats?key=50f5fd63-7817-4505-82ea-f0036cb955c2</link><guid>http://ayende.com/blog/4669/you-saved-5-cents-and-your-code-is-not-readable-congrats?key=50f5fd63-7817-4505-82ea-f0036cb955c2</guid><pubDate>Fri, 22 Oct 2010 10:00:00 GMT</pubDate></item><item><title>How to pay 3 times for the same flight ticket</title><description>&lt;p&gt;My current mood is somewhere between mad, pissed off, frustrated and exhausted.&lt;/p&gt;  &lt;p&gt;All I want to do it arrive home, but dark forces has conspired against me. It works like this:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I got a ticket both ways to London, and I left to London quite happily, taking the train to the airport. At that point things started going horribly wrong. An idiot has suicided on the train trucks, leading to about 2 hours of delays, which, naturally, caused me to miss my flight. We will leave that aside and just point out that I somehow managed to get to London without being late to my course the next morning. &lt;/li&gt;    &lt;li&gt;That is when I heard that since I was a no show for the outgoing flight, the airline cancelled my flight back.  I had to order a new one, but because I was busy actually doing the course, I asked the company to order that for me.&lt;/li&gt;    &lt;li&gt;They did, and I went to the airport quite satisfied, except that on arrival, the stupid machine told me that my booking is invalid, which is the point that I discovered that the ticket was ordered on Ayende Rahien. Unfortunately, legally speaking, that guy doesn’t exists. The airline was quite insistent that they can’t put me on board with the different name. And they made me buy a new ticket.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;That was the point (&lt;em&gt;after&lt;/em&gt; I paid for the &lt;em&gt;same bloody seat for &lt;/em&gt;&lt;strong&gt;the third time&lt;/strong&gt;&lt;em&gt;) &lt;/em&gt;that they told me that they oversold the flight, and that they put me on waiting list. &lt;/p&gt;  &lt;p&gt;I tried to explain that they could use the &lt;em&gt;second&lt;/em&gt; ticket that I bought, and just give me the same seat, but they told me that they already sold that to someone else. &lt;/p&gt;  &lt;p&gt;I am currently waiting to hear whatever I’ll get to go home tonight or not. &lt;/p&gt;  &lt;p&gt;Your truly,&lt;/p&gt;  &lt;p&gt;Pissed off,&lt;/p&gt;  &lt;p&gt;Oren Eini (because being Ayende is currently dangerous, given my mood)&lt;/p&gt;</description><link>http://ayende.com/blog/4587/how-to-pay-3-times-for-the-same-flight-ticket?key=49f250e6-193d-4f73-ad9c-8e01b72106c9</link><guid>http://ayende.com/blog/4587/how-to-pay-3-times-for-the-same-flight-ticket?key=49f250e6-193d-4f73-ad9c-8e01b72106c9</guid><pubDate>Fri, 13 Aug 2010 19:39:00 GMT</pubDate></item><item><title>WTF?! Google Groups really hates me!</title><description>&lt;p&gt;There are no other owners for the group, I have no idea what is going on…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/WTFGoogleGroupsreallyhatesme_76BD/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/WTFGoogleGroupsreallyhatesme_76BD/image_thumb.png" width="679" height="357" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Looks like Google disabled my account, for reasons known only to it. I had to go through a “send me an SMS to activate it” loop, but now it is working.&lt;/p&gt;</description><link>http://ayende.com/blog/4536/wtf-google-groups-really-hates-me?key=2a278de4-5ae1-4cec-a68a-786ddbc070b7</link><guid>http://ayende.com/blog/4536/wtf-google-groups-really-hates-me?key=2a278de4-5ae1-4cec-a68a-786ddbc070b7</guid><pubDate>Fri, 04 Jun 2010 05:26:00 GMT</pubDate></item><item><title>Some code just make me queasy</title><description>&lt;p&gt;And this one hits a lot of the high notes in that regard:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/Somecodejustmakemequeasy_144C3/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/Somecodejustmakemequeasy_144C3/image_thumb.png" width="452" height="118" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;em&gt;Three properties to say the same thing?!&lt;/em&gt;&lt;/p&gt;</description><link>http://ayende.com/blog/4501/some-code-just-make-me-queasy?key=95e49f1d-c436-41f0-9de7-4ceed887b36e</link><guid>http://ayende.com/blog/4501/some-code-just-make-me-queasy?key=95e49f1d-c436-41f0-9de7-4ceed887b36e</guid><pubDate>Fri, 14 May 2010 19:41:00 GMT</pubDate></item><item><title>Help requests that make me want to cry</title><description>&lt;p&gt;This showed up on my mail box, with the following text:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;When i try to insert an item to db, VS gives a stackoverflow exception. is it because of that i am using generic classes?? &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/Helprequeststhatmakemewanttocry_311B/image_4.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="247" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/Helprequeststhatmakemewanttocry_311B/image_thumb_1.png" width="726" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I am not going to comment further, I am stepping away from the keyboard and going to have a lie down.&lt;/p&gt;</description><link>http://ayende.com/blog/4134/help-requests-that-make-me-want-to-cry?key=6886c5ba-bf41-40d0-a477-a4655c6fb148</link><guid>http://ayende.com/blog/4134/help-requests-that-make-me-want-to-cry?key=6886c5ba-bf41-40d0-a477-a4655c6fb148</guid><pubDate>Fri, 21 Aug 2009 00:27:00 GMT</pubDate></item><item><title>NHibernate – Get Thou Out Of My Database</title><description>&lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/NHibernateGetThouOutOfMyDatabase_D659/image_2.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin-left: 0px; margin-right: 0px; border-right-width: 0px" height="301" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/NHibernateGetThouOutOfMyDatabase_D659/image_thumb.png" width="166" align="right" border="0" /&gt;&lt;/a&gt; There are evil people in this world, and some of them want access to my database. Unfortunately, they are often part of that nasty integration team and they try to integrate directly into my database. I tried beating them with clubs and lobbing arguments about letting other people mess with my implementation details, but they have been persistent. That is when I reached out to a technological solution for the problem.&lt;/p&gt;  &lt;p&gt;I want to emphasize that this is the &lt;em&gt;nuclear option &lt;/em&gt;and  you want to really consider it before going that route.&lt;/p&gt;  &lt;p&gt;We are going to use NHibernate to do that, naturally. Here is how:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/NHibernateGetThouOutOfMyDatabase_D659/image_4.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="295" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/NHibernateGetThouOutOfMyDatabase_D659/image_thumb_1.png" width="816" border="0" /&gt;&lt;/a&gt; &lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which results in the following schema:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;div&gt;
    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;create&lt;/span&gt; &lt;span style="color: #0000ff"&gt;table&lt;/span&gt; [tbl_-1434067361] (
   [col_287061521] &lt;span style="color: #0000ff"&gt;INT&lt;/span&gt; &lt;span style="color: #0000ff"&gt;IDENTITY&lt;/span&gt; &lt;span style="color: #0000ff"&gt;NOT&lt;/span&gt; &lt;span style="color: #0000ff"&gt;NULL&lt;/span&gt;,
   [col_4699698] &lt;span style="color: #0000ff"&gt;INT&lt;/span&gt; &lt;span style="color: #0000ff"&gt;not&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;,
   [col_-1966747349] NVARCHAR(255) &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;,
   [col_-649855325] NVARCHAR(255) &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;,
   [col_-649855326] NVARCHAR(255) &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;,
   [col_775690683] NVARCHAR(255) &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;,
   [col_-2127361396] NVARCHAR(255) &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;,
   [col_-1334581412] NVARCHAR(255) &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;,
   &lt;span style="color: #0000ff"&gt;primary&lt;/span&gt; &lt;span style="color: #0000ff"&gt;key&lt;/span&gt; ([col_287061521])
)&lt;/pre&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;To make sure that we follow procedure, we are even using the naming convention of the organization! Lovely, isn’t it? It is obvious that this is my people table, right?&lt;/p&gt;

&lt;p&gt;All arguments against this schema can be answered using: “It is more secured”.&lt;/p&gt;

&lt;p&gt;It might be the nuclear option, but it tend to work :-)&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Nitpicker corner: No, I don’t suggest you would do this, that is why the code is an image. This is just an example of how to programmatically modify the configuration and mapping. I only used it once, during a demo to the integration people, to get them to leave my DB alone. If you push something like that for production you should probably be shot.&lt;/p&gt;&lt;/blockquote&gt;</description><link>http://ayende.com/blog/4048/nhibernate-get-thou-out-of-my-database?key=ea1c8644-0921-490d-98d2-aab012d261c5</link><guid>http://ayende.com/blog/4048/nhibernate-get-thou-out-of-my-database?key=ea1c8644-0921-490d-98d2-aab012d261c5</guid><pubDate>Sat, 06 Jun 2009 12:13:00 GMT</pubDate></item><item><title>PayPal: It may be your account, but you aren’t going to use it</title><description>&lt;p&gt;In general, I have been very happy with PayPal over the years. Recently, however, I have become quite frustrated with it. I am using it quite often to send and accept money to people I am working with, and for a while now, I have been unable to do so.&lt;/p&gt;  &lt;p&gt;Apparently, my actions has been caught by some automated security systems and they decided to ban any transactions on my account. That is actually acceptable from my point of view. I feel better knowing that there are active attempts to protect me from fraud or theft. &lt;/p&gt;  &lt;p&gt;What I &lt;strong&gt;&lt;em&gt;don’t&lt;/em&gt;&lt;/strong&gt; find acceptable is that when I called PayPal to try to resolve that, the response that I got was: It is an act of God, nothing we mere mortals can do about it.&lt;/p&gt;  &lt;p&gt;I understand all about false positives, and aside from the annoyance factor, they are acceptable if they aren’t happening very often. What I am not able to comprehend is responses such as: No one in PayPal can help you. And that is after I already escalated to a supervisor!&lt;/p&gt;  &lt;p&gt;I recorded my conversation with PayPal, you can download it &lt;a href="http://ayende-backup.s3.amazonaws.com/paypal-support-is-useless.mp3"&gt;here&lt;/a&gt; or just listen:&lt;/p&gt; &lt;object type="application/x-shockwave-flash" data="http://ayende.com/blog/audio/player.swf" id="audioplayer1" height="24" width="290"&gt; &lt;param name="movie" value="http://ayende.com/blog/audio/player.swf" /&gt; &lt;param name="FlashVars" value="playerID=1&amp;amp;soundFile=http://ayende-backup.s3.amazonaws.com/paypal-support-is-useless.mp3" /&gt; &lt;param name="quality" value="high" /&gt; &lt;param name="menu" value="false" /&gt; &lt;param name="wmode" value="transparent" /&gt; &lt;/object&gt;  &lt;p&gt;I find the whole thing utterly infuriating, and totally unacceptable.&lt;/p&gt;</description><link>http://ayende.com/blog/4015/paypal-it-may-be-your-account-but-you-arent-going-to-use-it?key=445f24cd-efcf-41d0-95dc-934a71def3b0</link><guid>http://ayende.com/blog/4015/paypal-it-may-be-your-account-but-you-arent-going-to-use-it?key=445f24cd-efcf-41d0-95dc-934a71def3b0</guid><pubDate>Fri, 15 May 2009 15:43:09 GMT</pubDate></item><item><title>Kobe – Architectural Overview</title><description>&lt;p&gt;Sometimes, you have to make a distinction between the system architecture and the system implementation. It is possible to have a great architecture and have the implementers butcher it by not paying attention at some points.&lt;/p&gt;  &lt;p&gt;Sometimes, the problem in the code implementation is so bad that it becomes an architectural problem. Kobe is one such example.&lt;/p&gt;  &lt;p&gt;We can start with the pervasive Primitive obsession that is all over the map. The common use of “string thisIsReallyGuid”, Copy &amp;amp; paste programming, horrible Exception Handling and total lack of respect for the fundamentals of OO.&lt;/p&gt;  &lt;p&gt;All of those tie back together to the lack of architectural oversight over the project. I have the feeling that at no point someone stopped and said: “there has &lt;em&gt;got&lt;/em&gt; to be a better way of doing this.”&lt;/p&gt;  &lt;p&gt;DRY is a true principle in development, it transcend programming languages and paradigms, about the only one that I can think of that does so. If you violate DRY, you are in for a world of trouble, sooner than later.&lt;/p&gt;  &lt;p&gt;SOLID is a set of principles used to build good OO applications. If you are using OO language and paradigms and fail to pay attention to SOLID, it will hurt you at some point. Not as soon as if you have violated DRY, but soon enough.&lt;/p&gt;  &lt;p&gt;8.5% of Kobe is copy &amp;amp; pasted code. And that is with the sensitivity dialed high, if we set the threshold to 3, which is what I commonly do, is goes up to 12.5%. A lot of the duplicated code relates to exception handling and caching. Those are classic cases for using an aspect to handle cross cutting concerns. That would reduce a lot of the duplicated code.&lt;/p&gt;  &lt;p&gt;The other problems that I have with Kobe is its total lack of respect for SOLID principles. You know what, let us throw solid out the window, I am going to focus on a single principle, Single Responsibility Principle. Just about any method that you care to name does more than one thing, in many cases, they do a &lt;em&gt;lot&lt;/em&gt; more than one thing.&lt;/p&gt;  &lt;p&gt;This is absolutely wrong.&lt;/p&gt;  &lt;p&gt;The “repositories” in Kobe has so many responsibilities that they are just shy of having a singularity around them.&lt;/p&gt;  &lt;p&gt;Overall, Kobe feels very amaturish, as if it was written without true understanding of what is expected of quality code, and without really understanding the underlying platform, frameworks or the infrastructure that they are using.&lt;/p&gt;  &lt;p&gt;I don’t like it at all, and it is a horrible sample application. In my considered opinioned, it should be pulled from the site, rewritten, and only then published again.&lt;/p&gt;</description><link>http://ayende.com/blog/3953/kobe-architectural-overview?key=85df010e-15db-4d68-9914-45d341fc6e40</link><guid>http://ayende.com/blog/3953/kobe-architectural-overview?key=85df010e-15db-4d68-9914-45d341fc6e40</guid><pubDate>Fri, 17 Apr 2009 07:57:55 GMT</pubDate></item><item><title>Kobe – an example of exception handling done wrong</title><description>&lt;p&gt;In Kobe, pretty much all exception handling is this:&lt;/p&gt;  &lt;pre&gt;&lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception ex)
{
    &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; rethrow = ExceptionPolicy.HandleException(ex, "&lt;span style="color: #8b0000"&gt;Service Policy&lt;/span&gt;");
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (rethrow &amp;amp;&amp;amp; WebOperationContext.Current == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
    {
        &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt;;
    }
    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;These lines appear in just about any method in the application.&lt;/p&gt;

&lt;p&gt;They are wrong. In fact, they are wrong on more than one level. Violating DRY is a big offence, but even ignoring that, they are still wrong.&lt;/p&gt;

&lt;p&gt;Exception handling is not something that you should take lightly, and there is a strong tie between the way that you write the code and the way errors are handled. The whole purpose of this exception handling is to avoid throwing an exception by setting some configuration parameter.&lt;/p&gt;

&lt;p&gt;The problem with this is that this purpose is &lt;em&gt;wrong&lt;/em&gt;. This is a case of writing the code without actually trying to understand what the implications are. You cannot do this sort of thing, because the calling code never expects a null, it expect a valid result or an exception.&lt;/p&gt;

&lt;p&gt;This approach bring us back to the bad old days of error codes. Not to mention that even if we actually checked for a null return value, what the hell is the error that actually caused this to happen.  Oh, it was put in the log, so now we need to go and look at the log file and try to match timestamps (if we even can).&lt;/p&gt;

&lt;p&gt;Exception handling should appear in exactly two places:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;When an error is expected (making a web request call, for example) and there is some meaningful behavior to be done in the case of a failure (such as retrying after some delay)&lt;/li&gt;

  &lt;li&gt;On a system boundary, in which case you need to make a decision about how you are going to expose the error to the outside world.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is important to note that I explicitly used the term system boundary, instead of service boundary, which is more commonly used. Exception handling within a system should &lt;em&gt;not&lt;/em&gt; try to hide errors. Error should propagate all the way to the system boundary, because otherwise we lose a lot of important information.&lt;/p&gt;

&lt;p&gt;System boundary is defined as whatever is visible to the actual user or other systems.&lt;/p&gt;

&lt;p&gt;Oh, and exception handling in the system boundary is a &lt;em&gt;system infrastructure problem&lt;/em&gt;, it is not something that you have to write code for all over the place.&lt;/p&gt;</description><link>http://ayende.com/blog/3952/kobe-an-example-of-exception-handling-done-wrong?key=15d35d88-214b-47d9-b98c-f266b04745e6</link><guid>http://ayende.com/blog/3952/kobe-an-example-of-exception-handling-done-wrong?key=15d35d88-214b-47d9-b98c-f266b04745e6</guid><pubDate>Fri, 17 Apr 2009 07:46:35 GMT</pubDate></item><item><title>Kobe – When the documentation is the only delivery that matters</title><description>&lt;p&gt;When comparing the Kobe code base to the Kobe documentation, I am starting to get a sinking feeling. The documentation is &lt;em&gt;really&lt;/em&gt; nice, the code is anything but.&lt;/p&gt;  &lt;p&gt;When you put out guidance, the documentation is nice, but it is the code that people are going to look it, learn and try to emulate. And when you put out something that doesn’t meet basic parameters for good software, that is a huge problem.&lt;/p&gt;  &lt;p&gt;With Oxite, Microsoft had the excuse of it being slipped out without anyone noticing. This time it is official, it &lt;em&gt;has &lt;/em&gt;passed the proper review procedure, and is explicitly marketed as “intended to guide you with the planning, architecting, and implementing of Web 2.0 applications and services.”&lt;/p&gt;  &lt;p&gt;Sorry, that is entirely unacceptable.&lt;/p&gt;  &lt;p&gt;Putting something like that out there as guidance is actively doing &lt;em&gt;harm&lt;/em&gt; to the community as a whole. It means that people who would look at that and try to use what they see there are going to get bitten by bad practices, bad architecture and overly complex and redundant approaches.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/"&gt;Phil Haack&lt;/a&gt; &lt;a href="http://weblogs.asp.net/rashid/archive/2009/04/16/kobe-ms-new-web-2-0-resource-kit-in-asp-net-mvc-and-my-thoughts.aspx#7048352"&gt;said&lt;/a&gt; that: “I was part of a high-level review and I felt most of the app that I saw was reasonably put together.”&lt;/p&gt;  &lt;p&gt;I submit that high level review of such guidance packages is &lt;em&gt;absolutely &lt;/em&gt;not sufficient. You have to get people to do a full review cycle of that, which include the code, the documentation, the reasoning and anything else that is going out there.&lt;/p&gt;</description><link>http://ayende.com/blog/3951/kobe-when-the-documentation-is-the-only-delivery-that-matters?key=1f77da42-00ea-4d51-95d0-373456ba4ecd</link><guid>http://ayende.com/blog/3951/kobe-when-the-documentation-is-the-only-delivery-that-matters?key=1f77da42-00ea-4d51-95d0-373456ba4ecd</guid><pubDate>Fri, 17 Apr 2009 07:23:44 GMT</pubDate></item><item><title>Kobe – Data Access done wrong</title><description>&lt;p&gt;From the Kobe documentation:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The Repository pattern is applied to mediate access to the data store through a Repository provider. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;From &lt;a href="http://martinfowler.com/eaaCatalog/repository.html"&gt;PoEAA&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;A system with a complex domain model often benefits from a layer, such as the one provided by Data Mapper (165), that isolates domain objects from details of the database access code. In such systems it can be worthwhile to build another layer of abstraction over the mapping layer where query construction code is concentrated. This becomes more important when there are a large number of domain classes or heavy querying. In these cases particularly, adding this layer helps minimize duplicate query logic.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I think that Repository is a fad, which is why I don’t use it much anymore myself, and looking at the usage semantics of the “repositories” in Kobe, they certainly don’t fit the bill.&lt;/p&gt;  &lt;p&gt;Repositories are here to encapsulate query logic, that is not the case with Kobe. Here is a partial view of some of the repositories that it have:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/KobeDataAccessdonewrong_891D/image_2.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="200" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/KobeDataAccessdonewrong_891D/image_thumb.png" width="609" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In general, looking at the any of the repositories in detail, I really want to cry. I mean, just take a look:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/KobeDataAccessdonewrong_891D/image_4.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="1195" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/KobeDataAccessdonewrong_891D/image_thumb_1.png" width="331" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;More to the point, let us look at GroupRepository.AcceptGroupInvite (I removed all the copy &amp;amp; paste crap to concentrate on the actual code):&lt;/p&gt;  &lt;pre&gt;GroupInvite groupInvite = _context.GroupInviteSet
                                 .Where(gi =&amp;gt; gi.GroupInviteId == groupInviteId)
                                 .FirstOrDefault();

&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (groupInvite == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
    &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DataException("&lt;span style="color: #8b0000"&gt;Invalid Invite Id&lt;/span&gt;", &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;);

groupInvite.InvitationStatuses = _context.InvitationStatusSet
                                        .Where(s =&amp;gt; s.InvitationStatusName == "&lt;span style="color: #8b0000"&gt;Accepted&lt;/span&gt;")
                                        .FirstOrDefault(); ;

_context.SaveChanges(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;There are so many things wrong with this approach that I don’t even know where to &lt;em&gt;start&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You can &lt;em&gt;see&lt;/em&gt; how the architects or developers resented having to use an ORM. If they couldn’t have stored procedures in the database, then by Jove and his keyboard, they will write stored procedures in code.&lt;/p&gt;

&lt;p&gt;Kobe uses Entity Framework for data access, and they treat it as if it was a dataset. As an OR/M aficionado, I am insolated. This shows complete lack of understanding how Entity Framework work, doing a lot more work than you should, brute force &amp;amp; big hammer approach.&lt;/p&gt;

&lt;p&gt;From an architectural perspective, most of what Kobe is doing is calling down to the repository to perform the data access details. Business logic, such as there is, is spread between the data access, the controllers and the service layer, in such a way that make is very hard to have a good idea about what is actually happening in the application.&lt;/p&gt;

&lt;p&gt;Data access details are quite pervasive throughout the application, and the whole &lt;em&gt;feeling&lt;/em&gt; of the application is of a circa 2001 sample app using stored procedures and hand rolled data access layers.&lt;/p&gt;</description><link>http://ayende.com/blog/3950/kobe-data-access-done-wrong?key=f8ca863e-f373-4ec9-8bec-6050c4c144dd</link><guid>http://ayende.com/blog/3950/kobe-data-access-done-wrong?key=f8ca863e-f373-4ec9-8bec-6050c4c144dd</guid><pubDate>Fri, 17 Apr 2009 06:45:08 GMT</pubDate></item><item><title>Kobe – In the nuts &amp; bolts and don’t really liking it</title><description>&lt;p&gt;There is another &lt;a href="http://msdn.microsoft.com/en-us/architecture/bb194897.aspx"&gt;ASP.Net MVC sample app&lt;/a&gt;, this time it is official, passed the proper review procedure, and is explicitly marketed as “intended to guide you with the planning, architecting, and implementing of Web 2.0 applications and services.”&lt;/p&gt;  &lt;p&gt;I am saying all of that in order to distinguish it from Oxite, which was non of this things. There have been a &lt;a href="http://codebetter.com/blogs/karlseguin/archive/2009/04/16/kobe-oh-dead-lord-why.aspx"&gt;couple&lt;/a&gt; of &lt;a href="http://weblogs.asp.net/rashid/archive/2009/04/16/kobe-ms-new-web-2-0-resource-kit-in-asp-net-mvc-and-my-thoughts.aspx#comments"&gt;reviews&lt;/a&gt; of Kobe already. Frankly, I don’t really care for them, mostly because I think that they dealt too much with nitty gritty details of the app that doesn’t really matter much. I don’t much care for extra using or the use of System.Int32 vs. int, the naming convention used or even what sort of HTML formatting they used. I mostly care about the code and architecture. So I decided to take a look myself.&lt;/p&gt;  &lt;p&gt;This post is going to go over the nuts &amp;amp; bolts, looking at low level coding details. I am going to have another that is going to look at the architecture and probably a few others that talk about some additional concerns that I have.&lt;/p&gt;  &lt;p&gt;Let us start by looking at the code via some tools. &lt;a href="http://www.redhillconsulting.com.au/products/simian/"&gt;Simian&lt;/a&gt; reports:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/KobeInthenutsboltsanddontreallylikingit_861D/image_2.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="219" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/KobeInthenutsboltsanddontreallylikingit_861D/image_thumb.png" width="439" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;And that is when the similarity threshold is 6 lines, I usually run it with three, if we try &lt;em&gt;that&lt;/em&gt;, we get:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Found 5138 duplicate lines in 873 blocks in 67 files&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Next, the most important code metric to me in most cases, Cyclomatic Complexity. Two methods literally jump out of the solution and beg for mercy.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;HomeController.Discovery with CC index of 35(!)&lt;/li&gt;    &lt;li&gt;GroupController.Profile with CC index of 22&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I am going to show them both in all their glory, and let you be the judge of them:&lt;/p&gt;  &lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ActionResult Discovery(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; query)
{
    query = query.Trim();

    query = Server.HtmlEncode(query);

    List&amp;lt;PresentationSummary&amp;gt; presentationsAll = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
    List&amp;lt;PresentationSummary&amp;gt; presentationsMostPopular = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
    List&amp;lt;PresentationSummary&amp;gt; presentationsMostViewed = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
    List&amp;lt;PresentationSummary&amp;gt; presentationsMostDownload = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
    List&amp;lt;PresentationSummary&amp;gt; presentationsNew = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;

    List&amp;lt;UserSummary&amp;gt; activeusers = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
    List&amp;lt;UserSummary&amp;gt; allusers = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
    List&amp;lt;Group&amp;gt; activegroups = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
    List&amp;lt;Group&amp;gt; allgroups = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;

    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; iNewMemberPageCount = 0;
    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; iNewGroupPageCount = 0;
    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; ipresentationsAll = 0; 
    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; ipresentationsMostPopular =  0;
    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; ipresentationsMostViewed = 0;
    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; ipresentationsMostDownload = 0;
    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; ipresentationsNew = 0;

    UserSummary user = _userService.GetUserByName(query);
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (user != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
    {
        presentationsAll = _userService.GetAuthoredPresentations(user.UserName);
        presentationsMostPopular = presentationsAll.OrderByDescending(p =&amp;gt; p.Favorites).ToList();
        presentationsMostViewed = presentationsAll.Where(p =&amp;gt; p.Views &amp;gt; 0).OrderByDescending(p =&amp;gt; p.Views).ToList();
        presentationsMostDownload = presentationsAll.Where(p =&amp;gt; p.Downloads &amp;gt; 0).OrderByDescending(p =&amp;gt; p.Downloads).ToList();
        presentationsNew = presentationsAll.OrderByDescending(p =&amp;gt; p.InsertedDate).ToList();

        ipresentationsAll = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(presentationsAll.Count, 10).ToInt();
        ipresentationsMostPopular = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(presentationsMostPopular.Count, 10).ToInt();
        ipresentationsMostViewed = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(presentationsMostViewed.Count, 10).ToInt();
        ipresentationsMostDownload = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(presentationsMostDownload.Count, 10).ToInt();
        ipresentationsNew = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(presentationsNew.Count, 10).ToInt();

        activeusers = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;UserSummary&amp;gt; { user };
        allusers = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;UserSummary&amp;gt; { user };
        iNewMemberPageCount = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(allusers.Count, 8).ToInt();

        allgroups = _userService.GetGroups(user.UserName);
        activegroups = allgroups.OrderByDescending(g =&amp;gt; g.InsertedDate).ToList();
        iNewGroupPageCount = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(allgroups.Count, 8).ToInt();
    }
    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
    {
        Group group = _groupService.GetGroupByName(query);
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (group != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
        {
            presentationsAll = _groupService.GetPresentations(group.GroupName);
            presentationsMostPopular = presentationsAll.OrderByDescending(p =&amp;gt; p.Favorites).ToList();
            presentationsMostViewed = presentationsAll.Where(p =&amp;gt; p.Views &amp;gt; 0).OrderByDescending(p =&amp;gt; p.Views).ToList();
            presentationsMostDownload = presentationsAll.Where(p =&amp;gt; p.Downloads &amp;gt; 0).OrderByDescending(p =&amp;gt; p.Downloads).ToList();
            presentationsNew = presentationsAll.OrderByDescending(p =&amp;gt; p.InsertedDate).ToList();

            ipresentationsAll = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(presentationsAll.Count, 10).ToInt();
            ipresentationsMostPopular = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(presentationsMostPopular.Count, 10).ToInt();
            ipresentationsMostViewed = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(presentationsMostViewed.Count, 10).ToInt();
            ipresentationsMostDownload = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(presentationsMostDownload.Count, 10).ToInt();
            ipresentationsNew = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(presentationsNew.Count, 10).ToInt();

            allusers = _groupService.GetMembers(group.GroupName);
            activeusers = allusers.OrderByDescending(u =&amp;gt; u.DateOfJoining).ToList();
            iNewMemberPageCount = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(allusers.Count, 8).ToInt();

            allgroups = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;Group&amp;gt; { group };
            activegroups = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;Group&amp;gt; { group };
            iNewGroupPageCount = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(allgroups.Count, 8).ToInt();
        }
        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
        {
            presentationsAll = _presentationService.GetAllPresentationsByKewordTimeLine(query, "&lt;span style="color: #8b0000"&gt;Day&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;0&lt;/span&gt;", 10, 1);
            presentationsMostPopular = _presentationService.GetMostPopularPresentationsByKewordTimeLine(query, "&lt;span style="color: #8b0000"&gt;Day&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;0&lt;/span&gt;", 10, 1);
            presentationsMostViewed = _presentationService.GetMostViewedPresentationsByKewordTimeLine(query, "&lt;span style="color: #8b0000"&gt;Day&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;0&lt;/span&gt;", 10, 1); 
            presentationsMostDownload = _presentationService.GetMostDownloadedPresentationsByKewordTimeLine(query, "&lt;span style="color: #8b0000"&gt;Day&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;0&lt;/span&gt;", 10, 1); 
            presentationsNew = _presentationService.GetNewPresentations(query, "&lt;span style="color: #8b0000"&gt;Day&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;0&lt;/span&gt;", 10, 1);

            ipresentationsAll = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(_presentationService.GetAllPresentationsByKewordTimeLine(query, "&lt;span style="color: #8b0000"&gt;Day&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;0&lt;/span&gt;").Count, 10).ToInt();
            ipresentationsMostPopular = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(_presentationService.GetMostPopularPresentationsByKewordTimeLine(query, "&lt;span style="color: #8b0000"&gt;Day&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;0&lt;/span&gt;").Count, 10).ToInt();
            ipresentationsMostViewed = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(_presentationService.GetMostViewedPresentationsByKewordTimeLine(query, "&lt;span style="color: #8b0000"&gt;Day&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;0&lt;/span&gt;").Count, 10).ToInt();
            ipresentationsMostDownload = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(_presentationService.GetMostDownloadedPresentationsByKewordTimeLine(query, "&lt;span style="color: #8b0000"&gt;Day&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;0&lt;/span&gt;").Count, 10).ToInt();
            ipresentationsNew = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(_presentationService.GetNewPresentations(query, "&lt;span style="color: #8b0000"&gt;Day&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;0&lt;/span&gt;").Count, 10).ToInt();

            activeusers = _userService.GetMostActiveUsers(query, 8, 1);
            allusers = _userService.GetAllUsers(query, 8, 1);
            iNewMemberPageCount = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(_userService.GetMostActiveUsers(query).Count,8).ToInt();

            activegroups = _groupService.GetMostActiveGroupByKeyword(query, 8, 1);
            allgroups = _groupService.GetAllGroupByKeyword(query, 8, 1);
            iNewGroupPageCount = &lt;span style="color: #0000ff"&gt;decimal&lt;/span&gt;.Divide(_groupService.GetMostActiveGroupByKeyword(query).Count, 8).ToInt();
        }
    }

    ViewData.Add("&lt;span style="color: #8b0000"&gt;membersList-mostactive&lt;/span&gt;", activeusers);
    ViewData.Add("&lt;span style="color: #8b0000"&gt;membersList-all&lt;/span&gt;", allusers);
    ViewData.Add("&lt;span style="color: #8b0000"&gt;groupsList-mostactive&lt;/span&gt;", activegroups);
    ViewData.Add("&lt;span style="color: #8b0000"&gt;groupsList-all&lt;/span&gt;", allgroups);

    ViewData.Add("&lt;span style="color: #8b0000"&gt;presentations-all&lt;/span&gt;",presentationsAll);
    ViewData.Add("&lt;span style="color: #8b0000"&gt;presentations-mostpopular&lt;/span&gt;",presentationsMostPopular);
    ViewData.Add("&lt;span style="color: #8b0000"&gt;presentations-mostviewed&lt;/span&gt;",presentationsMostViewed);
    ViewData.Add("&lt;span style="color: #8b0000"&gt;presentations-mostdownload&lt;/span&gt;",presentationsMostDownload);
    ViewData.Add("&lt;span style="color: #8b0000"&gt;presentations-new&lt;/span&gt;",presentationsNew);
   
    ViewData.Add("&lt;span style="color: #8b0000"&gt;Query&lt;/span&gt;", query);
    &lt;span style="color: #008000"&gt;//ViewData.Add("Presentations", presentations);&lt;/span&gt;

    ViewData.Add("&lt;span style="color: #8b0000"&gt;members-totalcount&lt;/span&gt;", iNewMemberPageCount);
    ViewData.Add("&lt;span style="color: #8b0000"&gt;groups-totalcount&lt;/span&gt;", iNewGroupPageCount);

    ViewData.Add("&lt;span style="color: #8b0000"&gt;presentations-alltotalcount&lt;/span&gt;", ipresentationsAll);
    ViewData.Add("&lt;span style="color: #8b0000"&gt;presentations-mostpopulartotalcount&lt;/span&gt;", ipresentationsMostPopular);
    ViewData.Add("&lt;span style="color: #8b0000"&gt;presentations-mostviewedtotalcount&lt;/span&gt;", ipresentationsMostViewed);
    ViewData.Add("&lt;span style="color: #8b0000"&gt;presentations-mostdownloadtotalcount&lt;/span&gt;", ipresentationsMostDownload);
    ViewData.Add("&lt;span style="color: #8b0000"&gt;presentations-newtotalcount&lt;/span&gt;", ipresentationsNew);

    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; View();
}&lt;/pre&gt;

&lt;p&gt;This is… a very busy method, I must say. But in a way, the Profile method is much worse:&lt;/p&gt;

&lt;pre&gt;[AcceptVerbs(HttpVerbs.Post)]
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ActionResult Profile(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; gname, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; type, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; section, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; subSection, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; page)
{
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(gname))
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ContentResult { Content = "&lt;span style="color: #8b0000" /&gt;" };

    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (type != "&lt;span style="color: #8b0000"&gt;widget&lt;/span&gt;")
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ContentResult { Content = "&lt;span style="color: #8b0000" /&gt;" };

    Group group = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;

    &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;
    {
        group = _groupService.GetGroupByName(gname);
    }
    &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception)
    {
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ContentResult { Content = "&lt;span style="color: #8b0000" /&gt;" };
    }

    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (group == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
    {
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ContentResult { Content = "&lt;span style="color: #8b0000" /&gt;" };
    }

    &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; groupName = group.GroupName;

    AddUserLevelToViewData(groupName);

    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; pageNo = 1;
    Int32.TryParse(page, &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; pageNo);
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (pageNo == 0)
        pageNo = 1;

    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (section == "&lt;span style="color: #8b0000"&gt;div-GroupPresentations&lt;/span&gt;")
    {
        List&amp;lt;PresentationSummary&amp;gt; presentations = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;

        &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (subSection)
        {
            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;div-GroupPresentations-RecentltAdded&lt;/span&gt;":
                presentations = _groupService.GetRecentlyAddedPresentations(groupName, 5, pageNo);
                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;div-GroupPresentations-MostViewed&lt;/span&gt;":
                presentations = _groupService.GetMostViewedPresentations(groupName, 5, pageNo);
                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;div-GroupPresentations-MostDownloaded&lt;/span&gt;":
                presentations = _groupService.GetMostDownloadedPresentations(groupName, 5, pageNo);
                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;div-GroupPresentations-All&lt;/span&gt;":
                presentations = _groupService.GetPresentations(groupName, 5, pageNo);
                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
        }

        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; View("&lt;span style="color: #8b0000"&gt;PresentationsList&lt;/span&gt;", presentations);
    }
    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (section == "&lt;span style="color: #8b0000"&gt;div-GroupWall&lt;/span&gt;")
    {
        &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (subSection)
        {
            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;div-GroupWall-Messages&lt;/span&gt;":
                ViewData["&lt;span style="color: #8b0000"&gt;GroupMessages&lt;/span&gt;"] = _groupService.GetMessages(groupName, 5, pageNo);
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; View("&lt;span style="color: #8b0000"&gt;GroupMessageList&lt;/span&gt;", ViewData["&lt;span style="color: #8b0000"&gt;GroupMessages&lt;/span&gt;"]);
            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;div-GroupWall-MemberRequests&lt;/span&gt;":
                ViewData["&lt;span style="color: #8b0000"&gt;GroupJoiningRequests&lt;/span&gt;"] = _groupService.GetGroupJoiningRequests(groupName, 5, pageNo);
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; View("&lt;span style="color: #8b0000"&gt;GroupJoiningRequestList&lt;/span&gt;", ViewData["&lt;span style="color: #8b0000"&gt;GroupJoiningRequests&lt;/span&gt;"]);
        }
    }
    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (section == "&lt;span style="color: #8b0000"&gt;div-GroupInfoExtended&lt;/span&gt;")
    {
        &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (subSection)
        {
            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;div-GroupInfoExtended-GroupMembers&lt;/span&gt;":
                ViewData["&lt;span style="color: #8b0000"&gt;GroupMembers&lt;/span&gt;"] = _groupService.GetMembers(groupName, 4, pageNo);
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; View("&lt;span style="color: #8b0000"&gt;MembersList&lt;/span&gt;", ViewData["&lt;span style="color: #8b0000"&gt;GroupMembers&lt;/span&gt;"]);
        }
    }

    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ContentResult { Content = "&lt;span style="color: #8b0000" /&gt;" };
}&lt;/pre&gt;

&lt;p&gt;Just look at the code. I &lt;em&gt;thought&lt;/em&gt; that the whole point of MVC was to &lt;em&gt;separate&lt;/em&gt; the logic from the view. Having the view strongly tied to the controller output is fine by me, but having the &lt;em&gt;controller&lt;/em&gt; strongly tied to the HTML format of the page? That isn’t right.&lt;/p&gt;

&lt;p&gt;Another thing that isn’t right is HomeController.Index():&lt;/p&gt;

&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ActionResult Index()
{
    GetFeaturedPresentations(); &lt;span style="color: #008000"&gt;//*** Dummy call the the Database to activate the Connection.&lt;/span&gt;
    List&amp;lt;PresentationSummary&amp;gt; featured = _presentationService.GetFeaturedPresentations();
    List&amp;lt;PresentationSummary&amp;gt; beingViewed = _presentationService.GetPresentationRecentlyViewed();
    List&amp;lt;PresentationSummary&amp;gt; mostDownloaded = _presentationService.GetMostDownloadedPresentation();
    PresentationSummary presentationOfDay = _presentationService.GetPresentationOfDay();

    ViewData.Add("&lt;span style="color: #8b0000"&gt;FeaturedPresentations&lt;/span&gt;", featured.ToArray());
    ViewData.Add("&lt;span style="color: #8b0000"&gt;RecentlyViewedPresentations&lt;/span&gt;", beingViewed.ToArray());
    ViewData.Add("&lt;span style="color: #8b0000"&gt;MostDownloadedPresentations&lt;/span&gt;", mostDownloaded.ToArray());
    ViewData.Add("&lt;span style="color: #8b0000"&gt;presentationsOfDay&lt;/span&gt;", presentationOfDay);
    ViewData["&lt;span style="color: #8b0000"&gt;Tags&lt;/span&gt;"] = _presentationService.GetPopularTags();

    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; View();
}&lt;/pre&gt;

&lt;p&gt;Notice the first call?&lt;/p&gt;

&lt;pre&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; GetFeaturedPresentations()
{
    &lt;span style="color: #0000ff"&gt;try&lt;/span&gt; {
        &lt;span style="color: #008000"&gt;//*** Dummy call to the Presentation Service to get the Featured presentations,&lt;/span&gt;
        &lt;span style="color: #008000"&gt;//*** this call is place because, an exception thrown from the Data layered on first hit to the DB (failed to open DB) &lt;/span&gt;
        &lt;span style="color: #008000"&gt;//*** and the second hit to the DB gets success.&lt;/span&gt;
        _presentationService.GetFeaturedPresentations();
    }
    &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception)
    { &lt;span style="color: #008000"&gt;/*do nothing with this exception*/&lt;/span&gt; }
}&lt;/pre&gt;

&lt;p&gt;I really like it when you work around a bug instead of actually fix it.&lt;/p&gt;

&lt;p&gt;Moving on, let us look at the service layer. Most of it looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ADs GetAdById(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; adId)
{
    &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;
    {
        &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; key = "&lt;span style="color: #8b0000"&gt;Ads-&lt;/span&gt;" + adId;
        ADs data = cacheService.Get&amp;lt;ADs&amp;gt;(key);
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (data == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
        {
            data = provider.GetAdById(adId.ToGuid());
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (data != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; data.Image != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
            {
                cacheService.Add(key, data &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Object, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, DateTime.MaxValue, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TimeSpan(0, 10, 0), System.Web.Caching.CacheItemPriority.Normal, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;);
            }
        }
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; data;

    }
    &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception ex)
    {
        &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; rethrow = ExceptionPolicy.HandleException(ex, "&lt;span style="color: #8b0000"&gt;Service Policy&lt;/span&gt;");
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (rethrow &amp;amp;&amp;amp; WebOperationContext.Current == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
        {
            &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt;;
        }
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
    }
}&lt;/pre&gt;

&lt;p&gt;I am not joking about all of them looking alike, by the way, it is obviously has been cut &amp;amp; paste a lot.&lt;/p&gt;

&lt;p&gt;Nitpick, “data as Object” – that is not something you often see. But this is even better (from CacheService):&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/KobeInthenutsboltsanddontreallylikingit_861D/image_4.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="20" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/KobeInthenutsboltsanddontreallylikingit_861D/image_thumb_1.png" width="172" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;I like how we have a cacheService but we coupled its interface with System.Web.Caching, or the fact that most of this code is just a very long winded way of calling GetAdById.&lt;/p&gt;

&lt;p&gt;But wait, I spared you the method documentation, which is a real masterpiece:&lt;/p&gt;

&lt;pre&gt;&lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #808080"&gt;/// Returns Advertisment.&lt;/span&gt;
&lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #808080"&gt;/// &amp;lt;param name="adId"&amp;gt; GUID of an Advertisment&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span style="color: #808080"&gt;/// &amp;lt;returns&amp;gt;Ads&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ADs GetAdById(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; adId)&lt;/pre&gt;

&lt;p&gt;Yes, the adId is a string which is a guid. We are so lucky to work with VARIANT again, right?&lt;/p&gt;

&lt;p&gt;Let us take another method, just to see what is going on in a typical method inside the project. I intentionally avoid the ones that we already looked at. I took a peek at CommunityController and found the Index method:&lt;/p&gt;

&lt;pre&gt;[AcceptVerbs(HttpVerbs.Post)]
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ActionResult Index(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; type, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; section, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; subSection, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; page)
{
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (type != "&lt;span style="color: #8b0000"&gt;widget&lt;/span&gt;")
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ContentResult { Content = "&lt;span style="color: #8b0000" /&gt;" };

    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; pageNo = 1;
    Int32.TryParse(page, &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; pageNo);
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (pageNo == 0)
        pageNo = 1;

    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (section == "&lt;span style="color: #8b0000"&gt;members&lt;/span&gt;")
    {
        List&amp;lt;UserSummary&amp;gt; users = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;

        &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (subSection)
        {
            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;members-new&lt;/span&gt;":
                users = _communityService.GetNewUsers(8, pageNo);
                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;members-mostactive&lt;/span&gt;":
                users = _communityService.GetMostActiveUsers(8, pageNo);
                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;members-all&lt;/span&gt;":
                users = _communityService.GetAllUsers(8, pageNo);
                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
            &lt;span style="color: #0000ff"&gt;default&lt;/span&gt;:
                users = _communityService.GetAllUsers(8, pageNo);
                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
        }

        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; View("&lt;span style="color: #8b0000"&gt;MembersList&lt;/span&gt;", users);
    }
    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (section == "&lt;span style="color: #8b0000"&gt;groups&lt;/span&gt;")
    {
        List&amp;lt;Group&amp;gt; groups = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;

        &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (subSection)
        {
            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;groups-new&lt;/span&gt;":
                groups = _communityService.GetNewGroups(8, pageNo);
                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;groups-mostactive&lt;/span&gt;":
                groups = _communityService.GetMostActiveGroups(8, pageNo);
                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
            &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; "&lt;span style="color: #8b0000"&gt;groups-all&lt;/span&gt;":
                groups = _communityService.GetAllGroups(8, pageNo);
                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
            &lt;span style="color: #0000ff"&gt;default&lt;/span&gt;:
                groups = _communityService.GetAllGroups(8, pageNo);
                &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
        }

        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; View("&lt;span style="color: #8b0000"&gt;GroupsList&lt;/span&gt;", groups);
    }
    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (section == "&lt;span style="color: #8b0000"&gt;favourites&lt;/span&gt;")
    {
        List&amp;lt;PresentationSummary&amp;gt; favouritePresentation = _communityService.GetCommunityFavorite(10, pageNo);
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; View("&lt;span style="color: #8b0000"&gt;PresentationsView&lt;/span&gt;", favouritePresentation.ToArray());
    }


    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ContentResult { Content = "&lt;span style="color: #8b0000" /&gt;" };
}&lt;/pre&gt;

&lt;p&gt;Let me see how many things I can find in a cursory examination:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Hard coding galore&lt;/li&gt;

  &lt;li&gt;Long method&lt;/li&gt;

  &lt;li&gt;&lt;em&gt;Complex&lt;/em&gt; method&lt;/li&gt;

  &lt;li&gt;Controller method return several different views&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And note that I am still not even trying for the architectural concepts or code quality metrics. That I’m going to leave to another post.&lt;/p&gt;

&lt;p&gt;Frankly, I am seeing &lt;em&gt;way&lt;/em&gt; too much bad things in the code to overview all of them. I am going to stop with a goodie, though. &lt;/p&gt;

&lt;p&gt;Let us explore GroupRepository.GetGroup, shall we?&lt;/p&gt;

&lt;pre&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Group GetGroup(Guid groupId, KobeEntities Context)
 {
     &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;
     {
         Group group = Context.GroupSet
                          .Where(g =&amp;gt; g.GroupId == groupId)
                          .FirstOrDefault();

         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (group == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
             &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DataException("&lt;span style="color: #8b0000"&gt;Invalid Group Id&lt;/span&gt;", &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;);

         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; group;
     }
     &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception ex)
     {

         &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; rethrow = ExceptionPolicy.HandleException(ex, "&lt;span style="color: #8b0000"&gt;Data Policy&lt;/span&gt;");
         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (rethrow)
         {
             &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt;;
         }
         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
     }
 }&lt;/pre&gt;

&lt;p&gt;On the face of it, except for the repeated stupid error handling, there doesn’t seems to be something wrong here, right?&lt;/p&gt;

&lt;p&gt;Take note for the different parameter casing on the GetGroup, though. Why is KobeEntities PascalCase? Well, that is because there is also a property called Context on the GroupRepository that you might use by accident. So, what is this Context parameter all about? GetGroup is a private method, who is calling it?&lt;/p&gt;

&lt;p&gt;Here is one such callsite:&lt;/p&gt;

&lt;pre&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddGroupInterests(Guid groupId, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] interests, Guid userId)
 {
     &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;
     {
         KobeEntities _context = Context;

         Group group = GetGroup(groupId, _context);
         User user = GetUser(userId, _context);&lt;/pre&gt;

&lt;p&gt;So, we take the Context property, put it in a _context local variable. Then we pass it to GetGroup, which uses it.&lt;/p&gt;

&lt;p&gt;I must say that I am at a loss to understand what was going on in the mind of whoever wrote it. Was he trying to optimize the number of time we access the property?&lt;/p&gt;

&lt;p&gt;As I said, I am currently writing a few other posts about Kobe, this was just to get to see the code itself, so we have an impression about its quality.&lt;/p&gt;

&lt;p&gt;I am… not impressed.&lt;/p&gt;</description><link>http://ayende.com/blog/3949/kobe-in-the-nuts-bolts-and-dont-really-liking-it?key=9d43c4c0-b064-460c-8703-8774e4395765</link><guid>http://ayende.com/blog/3949/kobe-in-the-nuts-bolts-and-dont-really-liking-it?key=9d43c4c0-b064-460c-8703-8774e4395765</guid><pubDate>Fri, 17 Apr 2009 06:32:17 GMT</pubDate></item><item><title>There are so many things wrong with this code…</title><description>&lt;p&gt;I just want to &lt;a href="http://www.codeproject.com/KB/dotnet/OptLocking_PrefixTable.aspx"&gt;cry&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/Therearesomanythingswrongwiththiscode_14F78/image_2.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="168" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/Therearesomanythingswrongwiththiscode_14F78/image_thumb.png" width="323" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://ayende.com/blog/3944/there-are-so-many-things-wrong-with-this-code?key=dac8ff4b-5d60-4455-bc44-481b22092ee0</link><guid>http://ayende.com/blog/3944/there-are-so-many-things-wrong-with-this-code?key=dac8ff4b-5d60-4455-bc44-481b22092ee0</guid><pubDate>Mon, 13 Apr 2009 20:51:03 GMT</pubDate></item><item><title>On XHEO Conduct</title><description>&lt;p&gt;XHEO &lt;a href="http://www.xheo.com/Blog/post/Response-to-Ayendee28099s-Open-Letter.aspx"&gt;responded&lt;/a&gt; to my &lt;a href="http://ayende.com/Blog/archive/2009/02/02/open-letter-to-xheo-that-is-not-a-good-way.aspx"&gt;open letter&lt;/a&gt;. This is my running commentary during reading their post.&lt;/p&gt; &lt;p&gt;Let us start from this:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;While I can understand the frustrations of a developer under the gun from a manager, or anxious to meet a deadline we really can't work with so little information - who can?&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Here is some of the email exchanges that went by.&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/OnXHEOConduct_14E60/image_2.png"&gt;&lt;img height="661" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/OnXHEOConduct_14E60/image_thumb.png" width="679" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Note that every email with an attachment is including details such as screen shots, assemblies, crash dumps, etc.&lt;/p&gt; &lt;p&gt;I want to point out that I did use their tool to generate a support request with all the details about my system that they could possibly want. I submit all exceptions to them as they came, although I run into several instances where the crash was so severe that the error reporting itself fail to kick in.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;I know that customers world wide have been conditioned to expect refunds for any reason at any time.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;No, customers has grown used to companies &lt;em&gt;respecting signed contracts&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;Looking at the timeline that XHEO provides, it seems that they totally ignored the attachments that I sent, which contained full reproductions of the actual problems. That is strange to say, because during my conversation with support, we continually referred to those screen shots, so I fail to see how they can ignore them or claim that I sent an email with just "it doesn't work either".&lt;/p&gt; &lt;p&gt;In fact, here is that particular email:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/OnXHEOConduct_14E60/image_4.png"&gt;&lt;img height="427" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/OnXHEOConduct_14E60/image_thumb_1.png" width="726" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;He is also missing the part that I &lt;em&gt;did &lt;/em&gt;updated to the latest version, only to find &lt;em&gt;other &lt;/em&gt;bugs:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/OnXHEOConduct_14E60/image_6.png"&gt;&lt;img height="292" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/OnXHEOConduct_14E60/image_thumb_2.png" width="726" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;At this point, I have spent over a week trying to resolve this issue, has been forced to wait for days to get someone from support, got not even a hint of resolution, but what seems like a flurry of "let us try to turn off this setting and see if this works".&lt;/p&gt; &lt;p&gt;I was already investing &lt;em&gt;way&lt;/em&gt; too much time into the product, and it was holding back my own work on NH Prof, not to mention the adverse affect on my ability to actually ship something.&lt;/p&gt; &lt;p&gt;I want to specifically respond to this:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;The post includes issues never reported to support and in far more detail then ever provided to us. Demonstrating Ayende is quite capable for expressing the information but simply chose not to.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I don't just keep screen shots of broken software around, I extract the images that I have shown in the original post from the emails that I sent them. &lt;/p&gt; &lt;p&gt;XHEO also provide more of the email correspondence that went between us. I recommend that you would read them. &lt;a href="http://downloads.xheo.com/blog/ayende/part%201.pdf"&gt;Part 1&lt;/a&gt; | &lt;a href="http://downloads.xheo.com/blog/ayende/part%202.pdf"&gt;Part 2&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Someone in the comments pointed out that doing the entire exchange over email was likely a factor. I agree. And I said so:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/OnXHEOConduct_14E60/image_8.png"&gt;&lt;img height="145" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/OnXHEOConduct_14E60/image_thumb_3.png" width="726" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;I never got a reply to this email.&lt;/p&gt; &lt;p&gt;And finally, there is this:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;We have not ignored the terms of the contract and continue to honor our obligations and offer support.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I honestly don't even know how to approach this statement. The contract that we both signed clearly states that their product should work. It doesn't, and they have failed to provide me with a working product. Hence, we fall back to the refund alternative, which they refuse, thereby breaching our contract.&lt;/p&gt;</description><link>http://ayende.com/blog/3851/on-xheo-conduct?key=a6f46d74-4905-4313-94df-ec7e9bd64dc3</link><guid>http://ayende.com/blog/3851/on-xheo-conduct?key=a6f46d74-4905-4313-94df-ec7e9bd64dc3</guid><pubDate>Thu, 05 Feb 2009 21:47:55 GMT</pubDate></item><item><title>The Challenger of Architecture Astronauts - Two-Tier Service Application Scenario</title><description>&lt;p&gt;It continues to amaze me, the length some people will go to in order to add additional complexity. Let us take this article: &lt;a href="http://www.codeplex.com/AppArch/Wiki/View.aspx?title=App%20Pattern%20-%20Two-Tier%20Service%20Application%20Scenario%20%28REST%29&amp;amp;referringTitle=Application%20Patterns"&gt;Two-Tier Service Application Scenario (REST)&lt;/a&gt;. I will leave aside the arguments about this article gross misrepresentations of what terms like domain modeling, entities and REST. Greg already called &lt;a href="http://codebetter.com/blogs/gregyoung/archive/2009/01/22/the-data-centric-universe.aspx"&gt;the DDD argument&lt;/a&gt;, and Colin is &lt;a href="http://www.lostechies.com/blogs/colinjack/archive/2009/01/22/p-amp-p-web-service-with-rest-application-pattern.aspx"&gt;working on&lt;/a&gt; the problems with the representation of REST. &lt;/p&gt;  &lt;p&gt;What I want to talk about is friction. I am looking at the code that is shown in the article and I cringed. &lt;em&gt;Hard&lt;/em&gt;. Do you want to tell me that it is &lt;em&gt;recommended&lt;/em&gt; that people would write code like this?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheChallengerofArchitectureAstronautsTwo_FD3A/image_2.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="304" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheChallengerofArchitectureAstronautsTwo_FD3A/image_thumb.png" width="404" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I am assuming that I would need to write one of those for each of my “entities” I honestly cannot figure out why. Why create specialized behavior when it would be easier, simpler, cheaper and better to handle this generically?&lt;/p&gt;  &lt;p&gt;Is there &lt;em&gt;any&lt;/em&gt; sort of value in this code? I don’t think so.&lt;/p&gt;  &lt;p&gt;It gets better when you see what you need to do in your Application_Start. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheChallengerofArchitectureAstronautsTwo_FD3A/image_4.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="167" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheChallengerofArchitectureAstronautsTwo_FD3A/image_thumb_1.png" width="397" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So now, not only do I have to create those handlers by hand, I now need to take care to register each them. I’ll leave aside the bug in the routing code vs. the employee route handler code (‘employee’ is not a route value), to focus on a more important subject. Even if I decided that I want to code my way to insanity, why do I give a single class two responsibilities (creating EmployeeHandler and EmployeesHandler).&lt;/p&gt;  &lt;p&gt;I am not even &lt;em&gt;trying &lt;/em&gt;to ask why I need the route handler in the first place. It seems like it is there just so there would be another layer in the architecture diagram. It looks like that was a common requirement, because here comes the next step toward the road of useless code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheChallengerofArchitectureAstronautsTwo_FD3A/image_6.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="364" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheChallengerofArchitectureAstronautsTwo_FD3A/image_thumb_2.png" width="407" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Except for creating additional work for the developer, I cannot think of a single reason why I would want to write this type of code unless I was paid by the line count.&lt;/p&gt;  &lt;p&gt;Let me see how many things I can find here that are going to add friction:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;As written, you are going to need one of those for each of the “entities” that you have. I assume that this is so that all the other per “entity” types wouldn’t feel lonely. On last count, We had:&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;EmployeeRepository&lt;/li&gt;      &lt;li&gt;EmployeeHandler&lt;/li&gt;      &lt;li&gt;EmployeesHandler&lt;/li&gt;      &lt;li&gt;EmployeeRouteHandler&lt;/li&gt;      &lt;li&gt;EmployeeTranslator&lt;/li&gt;      &lt;li&gt;EmployeeScript&lt;/li&gt;      &lt;li&gt;EmployeeFacade&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Mapping “command” whatever that is, to method calls? So every time that I have to add a new method, I have to touch &lt;em&gt;how&lt;/em&gt; many places?&lt;/li&gt;    &lt;li&gt;Why on &lt;em&gt;earth&lt;/em&gt; do I need to do explicit error handling? That is why I have exceptions for. Those should do the &lt;em&gt;Right Thing&lt;/em&gt; and I should not have to explicitly manage errors unless I know about something specific happening.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Oh, and I saved the best for last. Please take a look at the beast. And unlike the story, there is no beauty.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheChallengerofArchitectureAstronautsTwo_FD3A/image_8.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="377" alt="image" src="http://ayende.com/Blog/images/ayende_com/Blog/WindowsLiveWriter/TheChallengerofArchitectureAstronautsTwo_FD3A/image_thumb_3.png" width="387" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I truly find it hard to find a place to start.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Magic numbers all over the place.&lt;/li&gt;    &lt;li&gt;Promote(object[] data) ?! Are we in the stone age again? I really hoped that by 2009 we would be able to get to grip with the notion of &lt;em&gt;meaningful method parameters&lt;/em&gt;! For crying out load, you can use the ASP.Net MVC binder to do the work, you don’t have to do it yourself.&lt;/li&gt;    &lt;li&gt;Null reference exception that are just &lt;em&gt;waiting &lt;/em&gt;to happen.&lt;/li&gt;    &lt;li&gt;Unless PositionEnum is not an enum (a WTF all on its own), then the code wouldn’t even compile! Enums are value types, you cannot use ‘as’ with them.&lt;/li&gt;    &lt;li&gt;busErrors ? &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;First of all, what bus?&lt;/li&gt;      &lt;li&gt;More importantly, are we back in the good ole days of return codes? I thought we were beyond that already!&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;em&gt;Really&lt;/em&gt; bad resource management. C# has try/catch/finally for a reason. If an exception is thrown, you are going to leak the transactions. This is truly sad since the text is very careful to point out that you MUST dispose of those resources before you return.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;As I said, I am not going to even approach the actual guidance that is offered there. I think that it is invalid as best and likely to be harmful. &lt;/p&gt;  &lt;p&gt;From the code sample shown, I would surmise that no one actually sat down and actually coded any sort of system with this. Even the most basic system would crumble under the sheer weight of architecture piled on top of the poor system.&lt;/p&gt;  &lt;p&gt;I am saddened and disappointed to see such a thing being presented as guidance from the P&amp;amp;P.&lt;/p&gt;</description><link>http://ayende.com/blog/3826/the-challenger-of-architecture-astronauts-two-tier-service-application-scenario?key=14122b68-9bd5-47cc-b3fe-a154fec2c5d7</link><guid>http://ayende.com/blog/3826/the-challenger-of-architecture-astronauts-two-tier-service-application-scenario?key=14122b68-9bd5-47cc-b3fe-a154fec2c5d7</guid><pubDate>Fri, 23 Jan 2009 02:00:32 GMT</pubDate></item><item><title>Csc.exe and delegate inference, or: Why C# has awkward syntax</title><description>&lt;p&gt;I just tried to to do a major revamp of Rhino Mocks' interface. It was intended to make it easier to work with C# 3.0 and use the smarter compiler to get better syntax.&lt;/p&gt; &lt;p&gt;I shouldn't have bothered. Take a look at this.&lt;/p&gt;&lt;pre&gt;	&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; TestCsc
	{
		&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; TestMethod()
		{
			Execute(Bar); &lt;span style="color: #008000"&gt;// fail to compile&lt;/span&gt;
			Execute(&lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; ia, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; x) { }); &lt;span style="color: #008000"&gt;// compiles fine&lt;/span&gt;
			Execute((&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; x) =&amp;gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;; }); &lt;span style="color: #008000"&gt;// Compiles fine&lt;/span&gt;
			Execute((&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; x) =&amp;gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;; }); &lt;span style="color: #008000"&gt;// fail to compile&lt;/span&gt;
			Execute(Foo);&lt;span style="color: #008000"&gt;// fail to compile&lt;/span&gt;
			Execute(&lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; ia, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; x) { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;; }); &lt;span style="color: #008000"&gt;// fail to compile&lt;/span&gt;
		}

		&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; Foo(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; ia, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; x)
		{
			&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
		}

		&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Bar(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; ia, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; x)
		{
		}

		&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Execute&amp;lt;T, K&amp;gt;(Action&amp;lt;T, K&amp;gt; e)
		{
			
		}

		&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Execute&amp;lt;T, K&amp;gt;(Func&amp;lt;&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;, T, K&amp;gt; e)
		{

		}
	}&lt;/pre&gt;&lt;pre&gt;Annoyed.&lt;/pre&gt;</description><link>http://ayende.com/blog/3199/csc-exe-and-delegate-inference-or-why-c-has-awkward-syntax?key=930bc225-6837-4863-94c3-a076905abb20</link><guid>http://ayende.com/blog/3199/csc-exe-and-delegate-inference-or-why-c-has-awkward-syntax?key=930bc225-6837-4863-94c3-a076905abb20</guid><pubDate>Thu, 20 Mar 2008 06:18:43 GMT</pubDate></item><item><title>The consequences of web services architecture</title><description>&lt;p&gt;I mentioned before that MS CRM's decision to build all its external API based on web services (that cannot be accessed outside of ASMX proxies) was a big mistake. It is a mistake because you are handing the developer a really clumsy, stupid, API.&lt;/p&gt; &lt;p&gt;I just spent an hour trying to figure out how to set a value to null. An hour!&lt;/p&gt; &lt;p&gt;It couldn't be as simple as this:&lt;/p&gt; &lt;blockquote&gt;&lt;pre&gt;customer.new_employeeintouch = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;It has to be:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;customer.new_employeeintouch = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Lookup();
customer.new_employeeintouch.IsNull = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
customer.new_employeeintouch.IsNullSpecified = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
&lt;/pre&gt;&lt;/blockquote&gt;</description><link>http://ayende.com/blog/3041/the-consequences-of-web-services-architecture?key=58573413-c36e-4c2c-a446-679c15cf6852</link><guid>http://ayende.com/blog/3041/the-consequences-of-web-services-architecture?key=58573413-c36e-4c2c-a446-679c15cf6852</guid><pubDate>Wed, 12 Dec 2007 14:47:18 GMT</pubDate></item></channel></rss>