<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ivan Porto Carrero &#187; .NET 2.0</title>
	<atom:link href="http://flanders.co.nz/category/net20/feed/" rel="self" type="application/rss+xml" />
	<link>http://flanders.co.nz</link>
	<description>thoughts.each { &#38;:propagandise }</description>
	<lastBuildDate>Sat, 03 Sep 2011 09:56:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Beating a dead horse: Stored Procedures</title>
		<link>http://flanders.co.nz/2008/10/23/beating-a-dead-horse-stored-procedures/</link>
		<comments>http://flanders.co.nz/2008/10/23/beating-a-dead-horse-stored-procedures/#comments</comments>
		<pubDate>Thu, 23 Oct 2008 18:37:23 +0000</pubDate>
		<dc:creator>Ivan Porto Carrero</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[.NET 3.0]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[stored procedure]]></category>

		<guid isPermaLink="false">http://flanders.co.nz/2008/10/23/beating-a-dead-horse-stored-procedures/</guid>
		<description><![CDATA[<a href="http://flanders.co.nz/2008/10/23/beating-a-dead-horse-stored-procedures/" title="Beating a dead horse: Stored Procedures"></a>I seem to be having the same conversations with the dev teams whenever I switch clients. The topic of this post is one that many people have written about before. I&#8217;m just going to put my opinion on my blog &#8230;<p class="read-more"><a href="http://flanders.co.nz/2008/10/23/beating-a-dead-horse-stored-procedures/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://flanders.co.nz/2008/10/23/beating-a-dead-horse-stored-procedures/" title="Beating a dead horse: Stored Procedures"></a><p>I seem to be having the same conversations with the dev teams whenever I switch clients. The topic of this post is one that many people have written about before. I&#8217;m just going to put my opinion on my blog so I can refer people to it in the future instead of having to repeat myself every time.<br />
What prompted this post is that since I&#8217;ve moved to Belgium I&#8217;ve had to take a step back from living on the bleeding edge and using open source projects. Most of the work is concentrated in Brussels and is at big corporates or banks not exactly what you&#8217;d see as the progressive thinkers (with reason).<br />
I guess it would be safe to say that I&#8217;ve been immersed in &#8220;enterprise&#8221; development. In short I still haven&#8217;t seen anything that is more complicated than a web app like [Xero](http://www.xero.com). But perhaps more about that in another post. This one is about stored procedures and their valid uses.</p>
<p><span id="more-260"></span><br />
My current client is pretty interested in the newer technologies (anything that is out of beta) and how to put them into production.  As such they use LINQ as their data layer. They follow the classic MS guidance of data logic, business logic and &#8211; the trigger for this post &#8211; stored procedures to encapsulate all the data access.<br />
People that have worked with me in the past will be able to vouch for the fact that I feel strongly against stored procedures. But before we get to why I don&#8217;t want to use them, let&#8217;s look at some of the reasons people have given me in the past why they were using them.</p>
<p>* Performance. Because stored procedures are (pre)compiled<br />
* Security. They can lock down tables from being accessed by users directly but they can get to the database through the stored procedures layer<br />
* Maintenance. You can change a stored procedure more easily than deploying a new build of your application because no compilation is needed.<br />
* Less data to send over the wire because stored procedures can execute more sql statements at once.</p>
<p>All of that stuff sounds pretty great right? As I&#8217;ve said before my current client has developed their data layer in their framework using Linq2Sql. I think Linq2Sql is not too bad, at least it gets the corporates into an ORM mindset because it comes from MS which makes it a vastly easier technology to sell than NHibernate for example.<br />
But when you&#8217;re going to use Linq in conjunction with stored procedures for basic CRUD operations I think you&#8217;re kind of missing the whole point of Linq2Sql or ORM&#8217;s altogether for that matter. So there you have it, this is why I cannot resist posting about this subject although many people have said pretty much the same as I&#8217;m going to say in this post.</p>
<p>###Credit where credit is due<br />
The list of people below have helped me in forming my opinion on this subject. I&#8217;ve had the pleasure of having lengthy discussion on this topic with the first 3 people on the list. I consider the people on this list to be authorities in .NET development and 4 of them have written their own ORM in the past. Alex James and Andrew Peters now both work on the Entity Framework team.<br />
* [Alex James](http://blogs.msdn.com/alexj)<br />
* [Andrew Peters](http://andrewpeters.net)<br />
* [Jeremy Boyd](http://turtle.net.nz)<br />
* [Frans Bouma](http://weblogs.asp.net/fbouma)<br />
* [Ayende (Oren Eini)](http://ayende.com/Blog)<br />
* [Jeremy D. Miller](http://codebetter.com/jmiller)<br />
* [Jeff Atwood](http://codinghorror.com)</p>
<p>Let&#8217;s look at the reasons mentioned above and work our way through them seeing how they pan out in the end and you can draw your own conclusions on the matter.</p>
<p>###Performance<br />
####Stored procedures are precompiled<br />
The fact that stored procedures are precompiled and dynamic queries aren&#8217;t is a complete myth. Ever since Sql Server 7.0 the query plans are cached for both of them. If you change a parameter in a stored procedure it has to be recompiled too.You can check the Sql documentation to verify that.<br />
IMHO this also falls in the category premature optimizations. It could be that you have a query that is so complex or that is a real bottleneck for your application then it might be worth it to invest the time and write a stored procedure for it that queries the database differently and as such get rid of the bottle neck but take on a higher maintenance cost.<br />
####Batching of queries and returning multiple result sets<br />
Another argument people often bring to the table is that in a stored procedure I can issue many sql statements on the same database connection. I hate to break the news to you but you get the same benefits when you&#8217;re using dynamic sql (preferably the parameterized kind). You could issue one command that returns multiple result sets just like the body of your stored procedure. Or you could issue more than one command on the same connection and still get a very similar result.</p>
<p>###Security<br />
####Sql Injection attacks<br />
Another argument I keep hearing is the fact that when you build dynamic sql statements you open yourself up for sql injection attacks which isn&#8217;t that case for stored procedures.<br />
There is some truth in that but it definitely isn&#8217;t the whole truth. What they mean by that is that if you&#8217;re going to build your dynamic query by concatenating strings then you could indeed open yourself up to a sql injection attack but I&#8217;ve seen this happen in stored procedures too it&#8217;s just a little bit harder to do it there.<br />
However if you build your sql statement by using a parameterized query you get the same security benefits as a stored procedure would give you.</p>
<p>####Different permissions on tables and stored procedures<br />
This isn&#8217;t such a big problem. I&#8217;ve mostly seen people use one dedicated user to access the database. Lots of times there is a SOA like architecture that allows the client application to not even know what type of database it&#8217;s connecting too.  I haven&#8217;t seen many places yet where they actually implement security that is that strict.<br />
So the reasoning goes if you secure your application properly then this shouldn&#8217;t be a big problem.<br />
Ayende has a more elaborate post on the subject: [Stored Procedures for Security](http://ayende.com/Blog/archive/2006/04/05/StoredProceduresForSecurity.aspx)</p>
<p>###Maintenance<br />
This is probably a very ambiguous problem. From a development point of view this might probably be the worst argument in favor for stored procedures. However if you look at it from the POV of the enterprise it might actually hold some value.<br />
At my current client all the applications have to be distributed by a separate team, and that makes the deployment a costly scenario.<br />
That is because once your application goes into production and something small needs to change the deployment team has to go around and deploy that application again on every workstation in the company. I know about click-once but nobody has any rights to install anything on their pc which makes that pretty hard to do.<br />
Now from my POV this is the most invalid argument of all of them because of the maintenance overhead it adds.<br />
When you give stored procs to a developer they see shiny quick shortcuts to quickly get some data out and perhaps already transform some of that data in their query. That is all good the first time you have to deploy the application. But the next person needs to add a column to a table and suddenly he will have to go through all the stored procedures (at least 3 of them for the C,R and D of CRUD) to add the column. Then he has to go in the data layer of your n-tiered application and modify the entity and perhaps the methods that map to the stored procedures.  Then comes time to deploy and you forgot to modify your update script with that one column you added to a stored proc. Of course this stored proc is the one that saves one of the core entities of your application and suddenly the new release is throwing errors all over the place.<br />
I skipped the part of transforming some data. As [my previous post](http://flanders.co.nz) suggests: that stuff is business logic and doesn&#8217;t belong in a stored procedure.</p>
<p>###Some more reading on the subject<br />
* Jeff Atwood claiming that T-SQL is the assembly language of contemporary development.</p>
<p>[Who Needs Stored Procedures, Anyways?](http://www.codinghorror.com/blog/archives/000117.html)<br />
* Frans Bouma explaining his point of view:</p>
<p>[Stored procedures are bad, m'kay?](http://weblogs.asp.net/fbouma/archive/2003/11/18/38178.aspx)<br />
* Jeremy Miller swearing this is really going to be his last post on stored procedures:</p>
<p>[Why I do not use Stored Procedures](http://codebetter.com/blogs/jeremy.miller/archive/2006/05/25/145450.aspx)</p>
]]></content:encoded>
			<wfw:commentRss>http://flanders.co.nz/2008/10/23/beating-a-dead-horse-stored-procedures/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>If you ever wanted to play fur elise in the console</title>
		<link>http://flanders.co.nz/2008/10/22/if-you-ever-wanted-to-play-fur-elise-in-the-console/</link>
		<comments>http://flanders.co.nz/2008/10/22/if-you-ever-wanted-to-play-fur-elise-in-the-console/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 13:08:53 +0000</pubDate>
		<dc:creator>Ivan Porto Carrero</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://flanders.co.nz/?p=257</guid>
		<description><![CDATA[<a href="http://flanders.co.nz/2008/10/22/if-you-ever-wanted-to-play-fur-elise-in-the-console/" title="If you ever wanted to play fur elise in the console"></a>At work today we were playing around with the console.. here&#8217;s one of our experiments whilst creating a stoplight workflow (WF). private static void FurElise() { Console.Beep(420, 200); Console.Beep(400, 200); Console.Beep(420, 200); Console.Beep(400, 200); Console.Beep(420, 200); Console.Beep(315, 200); Console.Beep(370, 200); &#8230;<p class="read-more"><a href="http://flanders.co.nz/2008/10/22/if-you-ever-wanted-to-play-fur-elise-in-the-console/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://flanders.co.nz/2008/10/22/if-you-ever-wanted-to-play-fur-elise-in-the-console/" title="If you ever wanted to play fur elise in the console"></a><p>At work today we were playing around with the console.. here&#8217;s one of our experiments whilst creating a stoplight workflow (WF).</p>
<pre name="code" class="csharp">
private static void FurElise()
        {
            Console.Beep(420, 200);
            Console.Beep(400, 200);
            Console.Beep(420, 200);
            Console.Beep(400, 200);
            Console.Beep(420, 200);
            Console.Beep(315, 200);
            Console.Beep(370, 200);
            Console.Beep(335, 200);
            Console.Beep(282, 600);
            Console.Beep(180, 200);
            Console.Beep(215, 200);
            Console.Beep(282, 200);
            Console.Beep(315, 600);
            Console.Beep(213, 200);
            Console.Beep(262, 200);
            Console.Beep(315, 200);
            Console.Beep(335, 600);
            Console.Beep(213, 200);
            Console.Beep(420, 200);
            Console.Beep(400, 200);
            Console.Beep(420, 200);
            Console.Beep(400, 200);
            Console.Beep(420, 200);
            Console.Beep(315, 200);
            Console.Beep(370, 200);
            Console.Beep(335, 200);
            Console.Beep(282, 600);
            Console.Beep(180, 200);
            Console.Beep(215, 200);
            Console.Beep(282, 200);
            Console.Beep(315, 600);
            Console.Beep(213, 200);
            Console.Beep(330, 200);
            Console.Beep(315, 200);
            Console.Beep(282, 600);
        }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://flanders.co.nz/2008/10/22/if-you-ever-wanted-to-play-fur-elise-in-the-console/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Common mistakes in software development (part 2): Mixing up the tiers</title>
		<link>http://flanders.co.nz/2008/10/01/common-mistakes-in-software-development-part-2-mixing-up-the-tiers/</link>
		<comments>http://flanders.co.nz/2008/10/01/common-mistakes-in-software-development-part-2-mixing-up-the-tiers/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 04:10:54 +0000</pubDate>
		<dc:creator>Ivan Porto Carrero</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[.NET 3.0]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[n-tier]]></category>

		<guid isPermaLink="false">http://flanders.co.nz/2008/10/01/common-mistakes-in-software-development-part-2-mixing-up-the-tiers/</guid>
		<description><![CDATA[<a href="http://flanders.co.nz/2008/10/01/common-mistakes-in-software-development-part-2-mixing-up-the-tiers/" title="Common mistakes in software development (part 2): Mixing up the tiers"></a>In my [previous post](http://flanders.co.nz/2008/09/24/common-mistakes-in-software-development/) I explained some very quick wins to make your code a little bit cleaner. As I&#8217;ve been appointed an [asp.net](http://www.asp.net) project at work at the moment I have the chance to get more ammunition for blogging &#8230;<p class="read-more"><a href="http://flanders.co.nz/2008/10/01/common-mistakes-in-software-development-part-2-mixing-up-the-tiers/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://flanders.co.nz/2008/10/01/common-mistakes-in-software-development-part-2-mixing-up-the-tiers/" title="Common mistakes in software development (part 2): Mixing up the tiers"></a><p>In my [previous post](http://flanders.co.nz/2008/09/24/common-mistakes-in-software-development/) I explained some very quick wins to make your code a little bit cleaner. As I&#8217;ve been appointed an [asp.net](http://www.asp.net) project at work at the moment I have the chance to get more ammunition for blogging <img src='http://flanders.co.nz/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .<br />
This time I&#8217;d like to talk about properly separating your tiers so that the next person doesn&#8217;t have to go through the complete application and make changes everywhere just to make a minor change to the application.</p>
<p>One  of the problems; one of the most time consuming that is; I&#8217;ve seen is that people are confused on what they have to put in the data logic layer and what is business logic. In my case this is fairly extreme because there isn&#8217;t an ORM tool but rather every entity gets populated by calling a stored procedure and then in the code the graph objects get set. Whether this is a good approach for fetching your data or not is not within the scope of this blog post, but I&#8217;m guessing there are more people who are facing this type of situation.</p>
<p>Anyway let&#8217;s start with the beginning and explain the typical [n-tier architecture](http://en.wikipedia.org/wiki/N-tier) people seem to follow. This is not a particular pattern like [MVC](http://en.wikipedia.org/wiki/Model-view-controller) or [MVP](http://en.wikipedia.org/wiki/Model-view-presenter) that people are talking about so much lately. This goes back to the guidance that can be found on the [msdn website](http://msdn.microsoft.com).  This type of architecture is often used in combination with data sets but not in my example for this post. This architecture is generally divided in 3 parts that can, but don&#8217;t have to, run on different machines if needs be.  When talking about this type of architecture people mostly talk about an n-tier application.</p>
<p>##The first part is the data layer (tier).<br />
The golden rule for this one: this is the gateway between the rest of your application and the database. **NONE** of the other layers should be talking directly to the database but instead should be doing their talking through this layer.  That means if you have stored procedures you provide wrappers for them in this layer. You populate your entities in this layer too.<br />
Other functions you can perform in this layer is setting the graph members (populating relationships). IMHO if you&#8217;re talking to the database (open/close connection) you&#8217;re doing stuff that belongs in the data layer which includes populating relationships.</p>
<p>Encapsulating this logic in it&#8217;s own layer, which could potentially be walled off through only exposing it with remoting or WCF, allows you to reuse the code in different places of your applications or sharing this data access assembly with multiple applications.</p>
<p>##The second part is the business logic layer (tier).<br />
This layer encapsulates all the operations you do on entities to express the business rules. That means you would probably do most of your work in this layer. Basically **all** of the programming you will be doing for the business rules should be done here. Business logic doesn&#8217;t live in stored procedures, it doesn&#8217;t live in the UI or the data layer. Nope this layer is where it lives and nowhere else.  This statement may raise some eyebrows but only and only when you find that a certain routine is a bottleneck and it is really data intensive you can put it in a stored procedure but more on that subject in another blog post.<br />
If you find yourself transforming data so you can display it in your GUI then you&#8217;re probably expressing business rules that aren&#8217;t explicitly stated as a business rule.<br />
When you find yourself to be concatenating strings or writing logic to translate your pages in your GUI layer then you&#8217;re probably expressing business logic (business logic doesn&#8217;t have to come from business <img src='http://flanders.co.nz/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  in case that wasn&#8217;t clear).<br />
Another common find in business logic is validation for example because this generally expresses some kind of strict rule that comes from the business domain your application deals with. Validation is a tricky one but the rule is you should do **all** validation in your business logic. To provide a better user experience you can maybe reuse that validation on the client side. In the case of web development you probably will have to duplicate that validation in javascript if you really need it.</p>
<p>Separating these rules into their own layer allows you to reuse the methods and classes you create in the business logic layer, in different parts of your UI or even reuse it in different applications.<br />
By separating this logic it should be easier for you to do some automated testing like unit testing and/or integration testing of that code.</p>
<p>##The third and last layer (tier)<br />
This is typically the UI layer but you could easily use web/WCF services as an interface to your logic. The UI doesn&#8217;t have to be a GUI it can also be a CLI (Command-Line Interface) or something. But that is how you interact with the user or external application. The idea is that in this layer you have virtually no logic except for what&#8217;s on the screen **everything** else should be handled by your business logic. To clarify this statement: you can show/hide UI elements or add/remove elements to the UI and respond to events triggered by user actions but the data of that response and the processing really belongs in the business logic layer.</p>
<p>The UI layer can talk to both the business logic and data logic layers. If for example you&#8217;re getting a category list with just an id and name from the database chances are you won&#8217;t need to transform that data so your UI can bind directly to the entities returned by your data layer. But more complex items like an invoice for example will probably need some processing and then it should probably pass through the business logic layer.</p>
<p>This is typically a somewhat harder part of your application to provide tests for although there are some libraries out there that make it easier but still there are easier parts to test in your application.</p>
<p>So that was a quick refresher on what the classic n-tier architecture is about an how it should be structured. I hope you will agree with me into stating that its not that hard and pretty straight-forward to implement, but what I find in the &#8220;enterprise&#8221; is far from the points mentioned above.<br />
It is a bloody mix of everything everywhere, leaving me thinking -come on guys it&#8217;s not that hard-:<br />
*talking to the database =&gt; datalayer*<br />
*showing windows/adding UI elements,&#8230; =&gt; UI layer*<br />
*everything else =&gt; business logic*</p>
<p>Failing to abide by the previous simple rules will result in hell freezing over, entire plagues will be released upon the world; to cut a long story short: the world as you know it will seize to exist and turn into complete chaos.<br />
Following the rules should result in less code duplication, an instantaneously easier to maintain codebase and probably more happy successors for when you move on to the next project.  It should also give you a higher degree of code reuse.<br />
If there is one thing you should take away from this article then it should be:<br />
**Don&#8217;t mix your tiers**</p>
<p>Of course there are a couple of situations when you can diverge from the ideas presented in this post but you should always be able to justify why you break the rule. So you need a good reason to break the proposed architecture and that would probably also warrant a comment so the next guy also knows what&#8217;s going on.<br />
The most important part is to separate all non-UI logic out from the UI layer and put it in one of the lower layers.</p>
<p>Thanks for reading<br />
Ivan &#8211; writing for more maintainable software -</p>
]]></content:encoded>
			<wfw:commentRss>http://flanders.co.nz/2008/10/01/common-mistakes-in-software-development-part-2-mixing-up-the-tiers/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Common mistakes in software development</title>
		<link>http://flanders.co.nz/2008/09/24/common-mistakes-in-software-development/</link>
		<comments>http://flanders.co.nz/2008/09/24/common-mistakes-in-software-development/#comments</comments>
		<pubDate>Wed, 24 Sep 2008 10:31:44 +0000</pubDate>
		<dc:creator>Ivan Porto Carrero</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[.NET 3.0]]></category>
		<category><![CDATA[.NET 3.5]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://flanders.co.nz/?p=247</guid>
		<description><![CDATA[<a href="http://flanders.co.nz/2008/09/24/common-mistakes-in-software-development/" title="Common mistakes in software development"></a>***** Rant Alert ****** &#60;rant&#62; At my current client I&#8217;ve got to do mainly maintenance on existing applications. This gives me the chance to look into codebases that have been created by other people and that don&#8217;t really reflect how &#8230;<p class="read-more"><a href="http://flanders.co.nz/2008/09/24/common-mistakes-in-software-development/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://flanders.co.nz/2008/09/24/common-mistakes-in-software-development/" title="Common mistakes in software development"></a><p>***** Rant Alert ******</p>
<p>&lt;rant&gt;</p>
<p>At my current client I&#8217;ve got to do mainly maintenance on existing applications. This gives me the chance to look into codebases that have been created by other people and that don&#8217;t really reflect how I would write things. That is all good though it gives me a chance to learn new ways of doing things and when I think their way is better I&#8217;ll surely adopt.</p>
<p>Anyway when I&#8217;m browsing these codebases I do find a lot of things that could have been done better or more correctly and that&#8217;s what I&#8217;ll be writing about a little today.</p>
<p>The first one is returning bools:</p>
<p>I&#8217;ve found this in just about every project I&#8217;ve been in:</p>
<pre class="csharp" name="code">public bool IsNull(){
  if(obj == null)
    return true;
  else
    return false;
}</pre>
<p>The snippet above is a very long winded way of writing. IMHO this hurts readability and you&#8217;re saying the same thing twice. obj == null already returns a bool it makes no sense writing it again.</p>
<pre class="csharp" name="code">public bool IsNull() { return obj == null; }</pre>
<p>Another thing I keep seeing is very liberal use of try..catch blocks that catch all exceptions. Admittedly try..catch is cool but it should be used at times you are actually interested in the exception that is thrown. But it shouldn&#8217;t be used as a safeguard to swallow exceptions you don&#8217;t want to fix at this moment.  I keep seeing this code in projects:</p>
<pre class="csharp" name="code">try{
  myBLObject.FindSomething(someId).SomeMethod();
}
catch(Exception){
// Nothing to be done but error stops
}</pre>
<p>Now that can be easily written so that it won&#8217;t throw an exeption and then the try catch isn&#8217;t necessary anymore at all. Try..catch blocks most certainly have their use but throwing and catching exceptions definitely hurts performance because the system has to generate a complete stack trace etc. for every exception that is being thrown.</p>
<pre class="csharp" name="code">var result = myBLObject.FindSomething(someId);
if(result != null) result.SomeMethod();</pre>
<p>The code becomes a lot more readable, not to mention faster. I&#8217;ve seen this being used in OnRowDataBound events etc on grids with 500+ rows, removing the try catch blocks more than doubles the speed of that page.</p>
<p>The next one on the list is using if,else and switch statements. They are sometimes a cause of code bloat. To put it in the words of <a href="http://www.hanselman.com/blog/BackToBasicsLifeAfterIfForAndSwitchLikeADataStructuresReminder.aspx" target="_blank">Scott Hanselman</a>:</p>
<blockquote><p><strong>I think that using only <em>if</em>, <em>for </em>and <em>switch </em>is the Computer Programmer equivalent of using &#8220;like&#8221; in every sentence.</strong></p></blockquote>
<p>Scott does a great job explaining why they can be pretty evil so I&#8217;ll just leave you with a <a href="http://www.hanselman.com/blog/BackToBasicsLifeAfterIfForAndSwitchLikeADataStructuresReminder.aspx" target="_blank">link</a> to his post</p>
<p>I have another couple of posts in the making on this subject but I had to get this out of my system. These are also very quick wins the other things I&#8217;m going to talk about are application architecture and stored procs&#8230;.<br />
&lt;/rant&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://flanders.co.nz/2008/09/24/common-mistakes-in-software-development/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Congratulations to Mindscape</title>
		<link>http://flanders.co.nz/2007/11/05/congratulations-to-mindscape/</link>
		<comments>http://flanders.co.nz/2007/11/05/congratulations-to-mindscape/#comments</comments>
		<pubDate>Mon, 05 Nov 2007 22:34:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[.NET 3.0]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[TechEd]]></category>
		<category><![CDATA[User group]]></category>

		<guid isPermaLink="false">http://blog.koolkraft.net/2007/11/05/congratulations-to-mindscape/</guid>
		<description><![CDATA[<a href="http://flanders.co.nz/2007/11/05/congratulations-to-mindscape/" title="Congratulations to Mindscape"></a>A couple of friends of mine own the company Mindscape They were interviewed by Ron Jacobs at the latest NZ tech ed in August. And that has now just been put up on channel 9 as part of the ARCast &#8230;<p class="read-more"><a href="http://flanders.co.nz/2007/11/05/congratulations-to-mindscape/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://flanders.co.nz/2007/11/05/congratulations-to-mindscape/" title="Congratulations to Mindscape"></a></p>
<p>A couple of friends of mine own the company <a href="http://mindscape.co.nz">Mindscape</a></p>
<p>They were interviewed by <a href="http://blogs.msdn.com/rjacobs/">Ron Jacobs</a> at the latest NZ tech ed in August. And that has now just been put up on channel 9 as part of the ARCast series.</p>
<p>The interview is about their product <a href="http://www.mindscape.co.nz/products/LightSpeed/">LightSpeed</a> which IMHO is one of the nicest ORM&#8217;s out there. I&#8217;ve used it in a couple of things now and I am absolutely surprised by the fact that lightspeed is a good name for it because it is really fast. If you haven&#8217;t taken it for a test drive you should do so immediately.</p>
<p>Now everybody rush over there <a href="http://channel9.msdn.com/ShowPost.aspx?PostID=353738">to see their interview</a>.</p>
<p> </p>
<p>Well done JB, JD and Andrew.</p>
</p>
<div class="wlWriterSmartContent" id="0767317B-992E-4b12-91E0-4F059A8CECA8:fca2a544-e830-481c-9e02-32807fe9dc77" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">del.icio.us tags: <a href="http://del.icio.us/popular/Lightspeed" rel="tag">Lightspeed</a>, <a href="http://del.icio.us/popular/mindscape" rel="tag">mindscape</a>, <a href="http://del.icio.us/popular/ARCast" rel="tag">ARCast</a>, <a href="http://del.icio.us/popular/ORM" rel="tag">ORM</a></div>
]]></content:encoded>
			<wfw:commentRss>http://flanders.co.nz/2007/11/05/congratulations-to-mindscape/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I&#8217;m getting to write a book !!!!!!!!!</title>
		<link>http://flanders.co.nz/2007/11/03/im-getting-to-write-a-book/</link>
		<comments>http://flanders.co.nz/2007/11/03/im-getting-to-write-a-book/#comments</comments>
		<pubDate>Sat, 03 Nov 2007 00:05:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[.NET 3.0]]></category>
		<category><![CDATA[IronRuby]]></category>

		<guid isPermaLink="false">http://blog.koolkraft.net/2007/11/03/im-getting-to-write-a-book/</guid>
		<description><![CDATA[<a href="http://flanders.co.nz/2007/11/03/im-getting-to-write-a-book/" title="I&#039;m getting to write a book !!!!!!!!!"></a>I just got confirmation from Manning publishers that I get to write a book on IronRuby. I personally think this is great news I will keep you updated with more progress as I go along. I just wanted to get &#8230;<p class="read-more"><a href="http://flanders.co.nz/2007/11/03/im-getting-to-write-a-book/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://flanders.co.nz/2007/11/03/im-getting-to-write-a-book/" title="I&#039;m getting to write a book !!!!!!!!!"></a><p>I just got confirmation from Manning publishers that I get to write a book on IronRuby.</p>
<p>I personally think this is great news <img src='http://flanders.co.nz/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>I will keep you updated with more progress as I go along.</p>
<p>I just wanted to get this message out.</p>
]]></content:encoded>
			<wfw:commentRss>http://flanders.co.nz/2007/11/03/im-getting-to-write-a-book/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Woohoo IronRuby alpha1</title>
		<link>http://flanders.co.nz/2007/07/23/woohoo-ironruby-alpha1/</link>
		<comments>http://flanders.co.nz/2007/07/23/woohoo-ironruby-alpha1/#comments</comments>
		<pubDate>Mon, 23 Jul 2007 22:26:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>

		<guid isPermaLink="false">http://blog.koolkraft.net/2007/07/23/woohoo-ironruby-alpha1/</guid>
		<description><![CDATA[<a href="http://flanders.co.nz/2007/07/23/woohoo-ironruby-alpha1/" title="Woohoo IronRuby alpha1"></a>Well I&#8217;m pretty excited about the drop of IronRuby We took it for  a quick spin at work.. and it looks really promising As you can read on John Lams blog there are a bunch of things that aren&#8217;t implemented &#8230;<p class="read-more"><a href="http://flanders.co.nz/2007/07/23/woohoo-ironruby-alpha1/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://flanders.co.nz/2007/07/23/woohoo-ironruby-alpha1/" title="Woohoo IronRuby alpha1"></a><p>Well I&#8217;m pretty excited about the drop of IronRuby </p>
<p>We took it for  a quick spin at work.. and it looks really promising <img src='http://flanders.co.nz/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>As you can read on John Lams blog there are a bunch of things that aren&#8217;t implemented yet.</p>
<p>One of those things would be to enumerate the methods of a class.</p>
<p>We thought String would be a good fit as John is explaining how much time they put in that one.</p>
<p>so this is what we tried.</p>
<p>start up the ironruby console</p>
<p>str_test = &#8220;Hello World&#8221;</p>
<p>10.times { puts str_test }</p>
<p>which gives the expected output</p>
<p>Iterations over arrays etc work as expected.</p>
<p>however one of the things i use a lot are the methods : methods and attributes</p>
<p>attributes shouldn&#8217;t exist on a string class but methods should only now it throws an error.</p>
<p>All in all I&#8217;m very impressed by what they&#8217;ve accomplished so far and I&#8217;ll definitely be looking at contributing to this project as soon as I have completed my last 2 projects for clients.</p>
]]></content:encoded>
			<wfw:commentRss>http://flanders.co.nz/2007/07/23/woohoo-ironruby-alpha1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dark Visual studio scheme with resharper support</title>
		<link>http://flanders.co.nz/2007/07/18/dark-visual-studio-scheme-with-resharper-support/</link>
		<comments>http://flanders.co.nz/2007/07/18/dark-visual-studio-scheme-with-resharper-support/#comments</comments>
		<pubDate>Wed, 18 Jul 2007 22:32:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://blog.koolkraft.net/2007/07/18/dark-visual-studio-scheme-with-resharper-support/</guid>
		<description><![CDATA[<a href="http://flanders.co.nz/2007/07/18/dark-visual-studio-scheme-with-resharper-support/" title="Dark Visual studio scheme with resharper support"></a>This is more for my own reference but I decided to put it here. This is the color scheme I&#8217;ve been using over the past couple of weeks. It looks like this:  ///         /// Gets or sets the &#8230;<p class="read-more"><a href="http://flanders.co.nz/2007/07/18/dark-visual-studio-scheme-with-resharper-support/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://flanders.co.nz/2007/07/18/dark-visual-studio-scheme-with-resharper-support/" title="Dark Visual studio scheme with resharper support"></a><p>This is more for my own reference but I decided to put it here.</p>
<p>This is the color scheme I&#8217;ve been using over the past couple of weeks.</p>
<p>It looks like this:</p>
<div style="font-size: 10pt; background: #202020; color: #e8e8e8; font-family: consolas">
<p style="margin: 0px"> <span style="color: #909090">///</span><span style="color: #ffff80"> </span><span style="color: #909090"><br />
<summary></span></p>
<p style="margin: 0px">        <span style="color: #909090">///</span><span style="color: #ffff80"> Gets or sets the date.</span></p>
<p style="margin: 0px">        <span style="color: #909090">///</span><span style="color: #ffff80"> </span><span style="color: #909090"></summary>
<p></span></p>
<p style="margin: 0px">        <span style="color: #909090">///</span><span style="color: #ffff80"> </span><span style="color: #909090"><value></span><span style="color: #ffff80">The date.</span><span style="color: #909090"></value></span></p>
<p style="margin: 0px">        <span style="color: #fa8072">public</span> <span style="color: #00d2d2">DateTime</span> <span style="color: #d0d0d0">Date</span></p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: #fa8072">get</span> { <span style="color: #fa8072">return</span> <span style="color: #d0d0d0">date</span>; }</p>
<p style="margin: 0px">            <span style="color: #fa8072">set</span> { <span style="color: #d0d0d0">date</span> <span style="color: silver">=</span> <span style="color: #fa8072">value</span>; }</p>
<p style="margin: 0px">        }</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px">        <span style="color: #909090">///</span><span style="color: #ffff80"> </span><span style="color: #909090"><br />
<summary></span></p>
<p style="margin: 0px">        <span style="color: #909090">///</span><span style="color: #ffff80"> Gets or sets the memberName.</span></p>
<p style="margin: 0px">        <span style="color: #909090">///</span><span style="color: #ffff80"> </span><span style="color: #909090"></summary>
<p></span></p>
<p style="margin: 0px">        <span style="color: #909090">///</span><span style="color: #ffff80"> </span><span style="color: #909090"><value></span><span style="color: #ffff80">The name of the member.</span><span style="color: #909090"></value></span></p>
<p style="margin: 0px">        <span style="color: #fa8072">public</span> <span style="color: #fa8072">string</span> <span style="color: #d0d0d0">MemberName</span></p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: #fa8072">get</span> { <span style="color: #fa8072">return</span> <span style="color: #d0d0d0">memberName</span>; }</p>
<p style="margin: 0px">            <span style="color: #fa8072">set</span> { <span style="color: #d0d0d0">memberName</span><span style="color: silver">=</span> <span style="color: #fa8072">value</span>; }</p>
<p style="margin: 0px">        }</p>
<p style="margin: 0px"> </p>
<p style="margin: 0px">        <span style="color: #909090">///</span><span style="color: #ffff80"> </span><span style="color: #909090"><br />
<summary></span></p>
<p style="margin: 0px">        <span style="color: #909090">///</span><span style="color: #ffff80"> Gets or sets the source of the member.</span></p>
<p style="margin: 0px">        <span style="color: #909090">///</span><span style="color: #ffff80"> </span><span style="color: #909090"></summary>
<p></span></p>
<p style="margin: 0px">        <span style="color: #909090">///</span><span style="color: #ffff80"> </span><span style="color: #909090"><value></span><span style="color: #ffff80">The source of the member.</span><span style="color: #909090"></value></span></p>
<p style="margin: 0px">        <span style="color: #fa8072">public</span> <span style="color: #00d2d2">MemberSource</span> <span style="color: #d0d0d0">SourceOfMember</span></p>
<p style="margin: 0px">        {</p>
<p style="margin: 0px">            <span style="color: #fa8072">get</span> { <span style="color: #fa8072">return</span> <span style="color: #d0d0d0">sourceOfMember</span>; }</p>
<p style="margin: 0px">            <span style="color: #fa8072">set</span> { <span style="color: #d0d0d0">sourceOfMember</span> <span style="color: silver">=</span> <span style="color: #fa8072">value</span>; }</p>
<p style="margin: 0px">        }</p>
</div>
<p> </p>
<p>Oops.. looks like copy as html doesn&#8217;t quite look the same.. anyway you can give it a try if you want</p>
<p><a title="Dark Scheme with resharper settings" href="http://koolkraft.net/DarkSchemeWithResharper.zip" rel="nofollow">Dark Scheme with resharper settings</a></p>
]]></content:encoded>
			<wfw:commentRss>http://flanders.co.nz/2007/07/18/dark-visual-studio-scheme-with-resharper-support/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Unit Testing Legacy Code</title>
		<link>http://flanders.co.nz/2007/07/15/unit-testing-legacy-code/</link>
		<comments>http://flanders.co.nz/2007/07/15/unit-testing-legacy-code/#comments</comments>
		<pubDate>Sun, 15 Jul 2007 12:22:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>

		<guid isPermaLink="false">http://blog.koolkraft.net/2007/07/15/unit-testing-legacy-code/</guid>
		<description><![CDATA[<a href="http://flanders.co.nz/2007/07/15/unit-testing-legacy-code/" title="Unit Testing Legacy Code"></a>Whenever I&#8217;m faced with a bunch of legacy code that I would like to write unit tests for I get quickly demotivated because I know the code works but still i&#8217;d love to know if the code will still work &#8230;<p class="read-more"><a href="http://flanders.co.nz/2007/07/15/unit-testing-legacy-code/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://flanders.co.nz/2007/07/15/unit-testing-legacy-code/" title="Unit Testing Legacy Code"></a><p>Whenever I&#8217;m faced with a bunch of legacy code that I would like to write unit tests for I get quickly demotivated because I know the code works but still i&#8217;d love to know if the code will still work after I&#8217;ve been working on it.</p>
<p>Lately I&#8217;ve been faced with a lot of legacy code so I decided to make a little tool that does the same as what VSTS testing does when you select generate unit tests.</p>
<p>I haven&#8217;t made an add in yet, it&#8217;s just a little winforms app I started it this afternoon and i have something working now. It&#8217;s also one of my very first winform apps so things have a lot fo room for improving.</p>
<p>I&#8217;m open for suggestions and i decided to open source it so if you have a fix or would like to make it a better tool let me know and I&#8217;ll add you to the list of contributors</p>
<p>You can find the tool @ my subversion repo:  <a href="https://svn.koolkraft.net/test_generator/trunk">https://svn.koolkraft.net/test_generator/trunk</a></p>
<p>I know that it&#8217;s against the rules of TDD to do this stuff but i just want to save some time by generating stubs that don&#8217;t actually do anything except setup objects and initial values</p>
<p>Let me know what you think <img src='http://flanders.co.nz/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://flanders.co.nz/2007/07/15/unit-testing-legacy-code/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Minimizing css files</title>
		<link>http://flanders.co.nz/2007/07/04/minimizing-css-files/</link>
		<comments>http://flanders.co.nz/2007/07/04/minimizing-css-files/#comments</comments>
		<pubDate>Wed, 04 Jul 2007 08:09:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[.NET 2.0]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://blog.koolkraft.net/2007/07/04/minimizing-css-files/</guid>
		<description><![CDATA[<a href="http://flanders.co.nz/2007/07/04/minimizing-css-files/" title="Minimizing css files"></a>Before I join the language debate I&#8217;d like to share something entirely different. My take on optimizing your css files for production. Making css files production ready is surprisingly simple.  I use the following setup in my applications. The css &#8230;<p class="read-more"><a href="http://flanders.co.nz/2007/07/04/minimizing-css-files/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://flanders.co.nz/2007/07/04/minimizing-css-files/" title="Minimizing css files"></a><p>Before I join the language debate I&#8217;d like to share something entirely different. My take on optimizing your css files for production.</p>
<p>Making css files production ready is surprisingly simple.  I use the following setup in my applications.</p>
<p>The css compressor (just removes whitespace in this configuration).</p>
<p><span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">CssMinifier</span></p>
<pre>
<div style="font-size: 10pt; background: white; color: black; font-family: consolas">
<p style="margin: 0px">    {
<p style="margin: 0px">        <span style="color: blue">static</span> <span style="color: blue">readonly</span> <span style="color: #2b91af">Regex</span> whitespaceRegex = <span style="color: blue">new</span> <span style="color: #2b91af">Regex</span>(<span style="color: #a31515">@"\s+"</span>, <span style="color: #2b91af">RegexOptions</span>.Compiled | <span style="color: #2b91af">RegexOptions</span>.Multiline | <span style="color: #2b91af">RegexOptions</span>.ECMAScript);
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: green">// You can uncomment the following line if you're not using css hacks that rely on comment notation.</span>
<p style="margin: 0px">        <span style="color: green">//static readonly Regex commentsRegex = new Regex(@"\/\*(.*?)\*\/ ", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.ECMAScript);</span>
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: blue">static</span> <span style="color: blue">readonly</span> <span style="color: #2b91af">Regex</span> addLineBreaksRegex = <span style="color: blue">new</span> <span style="color: #2b91af">Regex</span>(<span style="color: #a31515">@"\} "</span>, <span style="color: #2b91af">RegexOptions</span>.Compiled | <span style="color: #2b91af">RegexOptions</span>.Multiline | <span style="color: #2b91af">RegexOptions</span>.ECMAScript);
<p style="margin: 0px">        <span style="color: blue">static</span> <span style="color: blue">readonly</span> <span style="color: #2b91af">Regex</span> removeLastBreakRegex = <span style="color: blue">new</span> <span style="color: #2b91af">Regex</span>(<span style="color: #a31515">@"\n$"</span>, <span style="color: #2b91af">RegexOptions</span>.Compiled | <span style="color: #2b91af">RegexOptions</span>.Multiline | <span style="color: #2b91af">RegexOptions</span>.ECMAScript);
<p style="margin: 0px">        <span style="color: blue">static</span> <span style="color: blue">readonly</span> <span style="color: #2b91af">Regex</span> trimInsideLeftBracketsRegex = <span style="color: blue">new</span> <span style="color: #2b91af">Regex</span>(<span style="color: #a31515">@" \{ "</span>, <span style="color: #2b91af">RegexOptions</span>.Compiled | <span style="color: #2b91af">RegexOptions</span>.Multiline | <span style="color: #2b91af">RegexOptions</span>.ECMAScript);
<p style="margin: 0px">        <span style="color: blue">static</span> <span style="color: blue">readonly</span> <span style="color: #2b91af">Regex</span> trimInsideRightBracketsRegex = <span style="color: blue">new</span> <span style="color: #2b91af">Regex</span>(<span style="color: #a31515">@"; \}"</span>, <span style="color: #2b91af">RegexOptions</span>.Compiled | <span style="color: #2b91af">RegexOptions</span>.Multiline | <span style="color: #2b91af">RegexOptions</span>.ECMAScript);
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">string</span> Compress(<span style="color: blue">string</span> source)
<p style="margin: 0px">        {
<p style="margin: 0px">            source = whitespaceRegex.Replace(source, <span style="color: #a31515">" "</span>);
<p style="margin: 0px"> 
<p style="margin: 0px">            <span style="color: green">// You can uncomment the following line if you're not using css hacks that rely on comment notation.</span>
<p style="margin: 0px">            <span style="color: green">//source = commentsRegex.Replace(source, string.Empty);</span>
<p style="margin: 0px"> 
<p style="margin: 0px">            source = addLineBreaksRegex.Replace(source, <span style="color: #a31515">"}\r\n"</span>);
<p style="margin: 0px">            source = removeLastBreakRegex.Replace(source, <span style="color: blue">string</span>.Empty);
<p style="margin: 0px">            source = trimInsideLeftBracketsRegex.Replace(source, <span style="color: #a31515">" {"</span>);
<p style="margin: 0px">            source = trimInsideRightBracketsRegex.Replace(source, <span style="color: #a31515">"}"</span>);
<p style="margin: 0px"> 
<p style="margin: 0px">            <span style="color: blue">return</span> source;
<p style="margin: 0px">        }
<p style="margin: 0px">    }
</div>
</pre>
<p><span --="" \}}="" ??="" \}\par="" true\cf0="" \cf1="" return\cf0="" \{="" get\cf0="" \{\par="" isreusable\par="" bool\cf0="" public\cf0="" ??\par="" windowstheme));\par="" cssbase,="" \{1\}.css?\cf0="" window_themes="" ?\{0\}="" .format(\cf5="" string\cf0="" readpath(target,="" .isnullorempty(windowstheme))\par="" (!\cf1="" if\cf0="" s);\par="" csslib)\par="" in\cf0="" s="" (\cf1="" foreach\cf0="" .topdirectoryonly));\par="" searchoption\cf0="" \cf4="" ?*.css?\cf0="" \cf5="" .getfiles(path,="" directory\cf0="" >(\cf4=&#8221;" <\cf1="" list\cf0="" new\cf0="" csslib="\par" >=&#8221;" .mappath(folder);\par=&#8221;" fileoperations\cf0=&#8221;" path=&#8221;\cf4&#8243; folder)\par=&#8221;" target,=&#8221;" stringbuilder\cf0=&#8221;" readfolder(\cf4=&#8221;" void\cf0=&#8221;" static\cf0=&#8221;" private\cf0=&#8221;" );\par=&#8221;" ?\\r\\n?\cf0=&#8221;" target.append(\cf5=&#8221;" target.append(readfile(fpath));\par=&#8221;" fpath);\par=&#8221;" \\r\\n\\r\\n?\cf0=&#8221;" *=&#8221;" \{0\}=&#8221;" ?=&#8221;" target.appendformat(\cf5=&#8221;" fpath)\par=&#8221;" readpath(\cf4=&#8221;" ??\cf0=&#8221;" #endif\par=&#8221;" ??\cf1=&#8221;" .readalltext(path);\par=&#8221;" file\cf0=&#8221;" system.io.\cf4=&#8221;" #else\par=&#8221;" fileoperations.readfile(path);\par=&#8221;" return=&#8221;" ??\cf7=&#8221;" mode.\par=&#8221;" production=&#8221;" in=&#8221;" is=&#8221;" app=&#8221;" the=&#8221;" when=&#8221;" disk=&#8221;" from=&#8221;" read=&#8221;" file=&#8221;" cache=&#8221;" \cf6=&#8221;" !debug=&#8221;" #if\cf0=&#8221;" .mappath(relativepath);\par=&#8221;" relativepath)\par=&#8221;" readfile(\cf1=&#8221;" context.response.write(sb.tostring());\par=&#8221;" context.response.write(cssminifier.compress(sb.tostring()));\par=&#8221;" context.response.cache.setvaliduntilexpires(true);\par=&#8221;" context.response.cache.setexpires(datetime.now.adddays(1));\par=&#8221;" context.response.cache.setcacheability(httpcacheability.public);\par=&#8221;" mode\par=&#8221;" release=&#8221;" handler=&#8221;" this=&#8221;" of=&#8221;" results=&#8221;" caching=&#8221;" start=&#8221;" ;\par=&#8221;" css?\cf0=&#8221;" ?text=&#8221;" context.response.contenttype=&#8221;\cf5&#8243; cssbase);\par=&#8221;" readfolder(sb,=&#8221;" ))\par=&#8221;" ?application?\cf0=&#8221;" (context.request.url.absoluteuri.contains(\cf5=&#8221;" ();\par=&#8221;" sb=&#8221;\cf1&#8243; ];\par=&#8221;" ?windows?\cf0=&#8221;" windowstheme=&#8221;context.Request.QueryString[\cf5" context.response.clear();\par="" context)\par="" httpcontext\cf0="" processrequest(\cf4="" common="" ~="">I will typically have a FileOperations helper class that takes care of common file system things.<br /></span></p>
<pre><!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red128\green128\blue128;\red255\green255\blue255;\red0\green128\blue0;\red0\green0\blue0;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf1 ///\cf3  \cf1
<summary>\par ??\cf0     \cf1 ///\cf3  This are operations that are perfomed on the file system \par ??\cf0     \cf1 ///\cf3  \cf1 </summary>

\par ??\cf0     \cf5 public\cf0  \cf5 static\cf0  \cf5 class\cf0  \cf6 FileOperations\par ??\cf0     \{\par ??        \cf5 public\cf0  \cf5 static\cf0  \cf5 string\cf0  basePath;\par ??\par ??        \cf5 public\cf0  \cf5 static\cf0  \cf5 string\cf0  CurrentDirectory\par ??        \{\par ??            \cf5 get\par ??\cf0             \{\par ??                \cf5 return\par ??\cf0                     \cf6 HttpContext\cf0 .Current != \cf5 null\par ??\cf0                         ? \cf6 HttpContext\cf0 .Current.Server.MapPath(\cf7 "~/"\cf0 )\par ??                        : \cf6 Environment\cf0 .CurrentDirectory;\par ??            \}\par ??        \}\par ??\par ??        \cf5 public\cf0  \cf5 static\cf0  \cf5 string\cf0  MapPath(\cf5 string\cf0  relativePath)\par ??        \{\par ??            \cf5 return\cf0  \cf6 Path\cf0 .Combine(CurrentDirectory, MakeRelative(relativePath));\par ??        \}\par ??\par ??        \cf5 private\cf0  \cf5 static\cf0  \cf5 string\cf0  MakeRelative(\cf5 string\cf0  path)\par ??        \{\par ??            \cf5 return\cf0  path.StartsWith(\cf7 "~/"\cf0 ) ? path.Remove(0, 2).Replace(\cf7 "/"\cf0 , \cf7 "\\\\"\cf0 ) : path.Replace(\cf7 "/"\cf0 , \cf7 "\\\\"\cf0 );\par ??        \}\par ??\par ??        \cf1 ///\cf3  \cf1
<summary>\par ??\cf0         \cf1 ///\cf3  Builds the attachment URL.\par ??\cf0         \cf1 ///\cf3  \cf1 </summary>

\par ??\cf0         \cf1 ///\cf3  \cf1
<param name="folder">\cf3 The folder.\cf1 </param>\par ??\cf0         \cf1 ///\cf3  \cf1
<param name="subFolder">\cf3 The sub folder.\cf1 </param>\par ??\cf0         \cf1 ///\cf3  \cf1 <returns></returns>\par ??\cf0         \cf5 public\cf0  \cf5 static\cf0  \cf5 string\cf0  BuildFileLink(\cf5 string\cf0  folder, \cf5 string\cf0  subFolder)\par ??        \{\par ??            basePath = \cf6 ConfigurationManager\cf0 .AppSettings[\cf7 "FileBasePath"\cf0 ];\par ??            \cf5 string\cf0  pathformat = basePath.EndsWith(\cf7 &#8220;/&#8221;\cf0 ) ? \cf7 &#8220;\{0\}\{1\}/\{2\}&#8221;\cf0  : \cf7 &#8220;\{0\}/\{1\}&#8221;\cf0 ;\par ??            \cf5 return\cf0  \cf5 string\cf0 .Format(pathformat, basePath, folder, subFolder);\par ??        \}\par ??\par ??        \cf5 private\cf0  \cf5 static\cf0  \cf5 string\cf0  buildPath(\cf5 string\cf0  folder, \cf5 string\cf0  subFolder)\par ??        \{\par ??            \cf5 try\par ??\cf0             \{\par ??                \cf5 return\cf0  MapPath(BuildFileLink(folder, subFolder));\par ??            \}\par ??            \cf5 catch\par ??\cf0             \{\par ??                \cf5 return\cf0  basePath + folder;\par ??            \}\par ??        \}\par ??\par ??        \cf1 ///\cf3  \cf1
<summary>\par ??\cf0         \cf1 ///\cf3  Deletes the folder.\par ??\cf0         \cf1 ///\cf3  \cf1 </summary>

\par ??\cf0         \cf1 ///\cf3  \cf1
<param name="username">\cf3 The username.\cf1 </param>\par ??\cf0         \cf5 public\cf0  \cf5 static\cf0  \cf5 void\cf0  DeleteFolder(\cf5 string\cf0  username)\par ??        \{\par ??            \cf6 Directory\cf0 .Delete(buildPath(username, \cf5 string\cf0 .Empty), \cf5 true\cf0 );\par ??        \}\par ??\par ??        \cf1 ///\cf3  \cf1
<summary>\par ??\cf0         \cf1 ///\cf3  Reads the file.\par ??\cf0         \cf1 ///\cf3  \cf1 </summary>

\par ??\cf0         \cf1 ///\cf3  \cf1
<param name="path">\cf3 The path.\cf1 </param>\par ??\cf0         \cf1 ///\cf3  \cf1 <returns></returns>\par ??\cf0         \cf5 public\cf0  \cf5 static\cf0  \cf5 string\cf0  ReadFile(\cf5 string\cf0  path)\par ??        \{\par ??            \cf5 string\cf0  key = path.Replace(\cf7 &#8221; &#8220;\cf0 , \cf7 &#8220;&#8221;\cf0 );\par ??            \cf5 if\cf0  (\cf6 HttpRuntime\cf0 .Cache[key] == \cf5 null\cf0 )\par ??            \{\par ??                \cf6 CacheDependency\cf0  fileDep = \cf5 new\cf0  \cf6 CacheDependency\cf0 (path);\par ??                \cf6 StreamReader\cf0  rdr = \cf5 new\cf0  \cf6 StreamReader\cf0 (path);\par ??                \cf6 HttpRuntime\cf0 .Cache.Insert(key, rdr.ReadToEnd(), fileDep);\par ??                rdr.Close();\par ??                rdr.Dispose();\par ??            \}\par ??            \cf5 return\cf0  \cf6 HttpRuntime\cf0 .Cache[key].ToString();\par ??        \}\par ??\par ??        \cf1 ///\cf3  \cf1
<summary>\par ??\cf0         \cf1 ///\cf3  Gets the folders in the specified path.\par ??\cf0         \cf1 ///\cf3  \cf1 </summary>

\par ??\cf0         \cf1 ///\cf3  \cf1
<param name="path">\cf3 The path.\cf1 </param>\par ??\cf0         \cf1 ///\cf3  \cf1 <returns></returns>\par ??\cf0         \cf5 public\cf0  \cf5 static\cf0  \cf5 string\cf0 [] GetFolders(\cf5 string\cf0  path)\par ??        \{\par ??            \cf5 return\cf0  \cf6 Directory\cf0 .GetDirectories(MapPath(path));\par ??        \}\par ??    \}}
&#8211;>
<div style="font-size: 10pt; background: white; color: black; font-family: consolas">
<p style="margin: 0px"><span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">
<summary></span>
<p style="margin: 0px">    <span style="color: gray">///</span><span style="color: green"> This are operations that are perfomed on the file system </span>
<p style="margin: 0px">    <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"></summary>

</span>
<p style="margin: 0px">    <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">class</span> <span style="color: #2b91af">FileOperations</span>
<p style="margin: 0px">    {
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">string</span> basePath;
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">string</span> CurrentDirectory
<p style="margin: 0px">        {
<p style="margin: 0px">            <span style="color: blue">get</span>
<p style="margin: 0px">            {
<p style="margin: 0px">                <span style="color: blue">return</span>
<p style="margin: 0px">                    <span style="color: #2b91af">HttpContext</span>.Current != <span style="color: blue">null</span>
<p style="margin: 0px">                        ? <span style="color: #2b91af">HttpContext</span>.Current.Server.MapPath(<span style="color: #a31515">&#8220;~/&#8221;</span>)
<p style="margin: 0px">                        : <span style="color: #2b91af">Environment</span>.CurrentDirectory;
<p style="margin: 0px">            }
<p style="margin: 0px">        }
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">string</span> MapPath(<span style="color: blue">string</span> relativePath)
<p style="margin: 0px">        {
<p style="margin: 0px">            <span style="color: blue">return</span> <span style="color: #2b91af">Path</span>.Combine(CurrentDirectory, MakeRelative(relativePath));
<p style="margin: 0px">        }
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">static</span> <span style="color: blue">string</span> MakeRelative(<span style="color: blue">string</span> path)
<p style="margin: 0px">        {
<p style="margin: 0px">            <span style="color: blue">return</span> path.StartsWith(<span style="color: #a31515">&#8220;~/&#8221;</span>) ? path.Remove(0, 2).Replace(<span style="color: #a31515">&#8220;/&#8221;</span>, <span style="color: #a31515">&#8220;\\&#8221;</span>) : path.Replace(<span style="color: #a31515">&#8220;/&#8221;</span>, <span style="color: #a31515">&#8220;\\&#8221;</span>);
<p style="margin: 0px">        }
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">
<summary></span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> Builds the attachment URL.</span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"></summary>

</span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">
<param name="folder"></span><span style="color: green">The folder.</span><span style="color: gray"></param></span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">
<param name="subFolder"></span><span style="color: green">The sub folder.</span><span style="color: gray"></param></span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"><returns></returns></span>
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">string</span> BuildFileLink(<span style="color: blue">string</span> folder, <span style="color: blue">string</span> subFolder)
<p style="margin: 0px">        {
<p style="margin: 0px">            basePath = <span style="color: #2b91af">ConfigurationManager</span>.AppSettings[<span style="color: #a31515">"FileBasePath"</span>];
<p style="margin: 0px">            <span style="color: blue">string</span> pathformat = basePath.EndsWith(<span style="color: #a31515">&#8220;/&#8221;</span>) ? <span style="color: #a31515">&#8220;{0}{1}/{2}&#8221;</span> : <span style="color: #a31515">&#8220;{0}/{1}&#8221;</span>;
<p style="margin: 0px">            <span style="color: blue">return</span> <span style="color: blue">string</span>.Format(pathformat, basePath, folder, subFolder);
<p style="margin: 0px">        }
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">static</span> <span style="color: blue">string</span> buildPath(<span style="color: blue">string</span> folder, <span style="color: blue">string</span> subFolder)
<p style="margin: 0px">        {
<p style="margin: 0px">            <span style="color: blue">try</span>
<p style="margin: 0px">            {
<p style="margin: 0px">                <span style="color: blue">return</span> MapPath(BuildFileLink(folder, subFolder));
<p style="margin: 0px">            }
<p style="margin: 0px">            <span style="color: blue">catch</span>
<p style="margin: 0px">            {
<p style="margin: 0px">                <span style="color: blue">return</span> basePath + folder;
<p style="margin: 0px">            }
<p style="margin: 0px">        }
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">
<summary></span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> Deletes the folder.</span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"></summary>

</span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">
<param name="username"></span><span style="color: green">The username.</span><span style="color: gray"></param></span>
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">void</span> DeleteFolder(<span style="color: blue">string</span> username)
<p style="margin: 0px">        {
<p style="margin: 0px">            <span style="color: #2b91af">Directory</span>.Delete(buildPath(username, <span style="color: blue">string</span>.Empty), <span style="color: blue">true</span>);
<p style="margin: 0px">        }
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">
<summary></span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> Reads the file.</span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"></summary>

</span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">
<param name="path"></span><span style="color: green">The path.</span><span style="color: gray"></param></span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"><returns></returns></span>
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">string</span> ReadFile(<span style="color: blue">string</span> path)
<p style="margin: 0px">        {
<p style="margin: 0px">            <span style="color: blue">string</span> key = path.Replace(<span style="color: #a31515">&#8221; &#8220;</span>, <span style="color: #a31515">&#8220;&#8221;</span>);
<p style="margin: 0px">            <span style="color: blue">if</span> (<span style="color: #2b91af">HttpRuntime</span>.Cache[key] == <span style="color: blue">null</span>)
<p style="margin: 0px">            {
<p style="margin: 0px">                <span style="color: #2b91af">CacheDependency</span> fileDep = <span style="color: blue">new</span> <span style="color: #2b91af">CacheDependency</span>(path);
<p style="margin: 0px">                <span style="color: #2b91af">StreamReader</span> rdr = <span style="color: blue">new</span> <span style="color: #2b91af">StreamReader</span>(path);
<p style="margin: 0px">                <span style="color: #2b91af">HttpRuntime</span>.Cache.Insert(key, rdr.ReadToEnd(), fileDep);
<p style="margin: 0px">                rdr.Close();
<p style="margin: 0px">                rdr.Dispose();
<p style="margin: 0px">            }
<p style="margin: 0px">            <span style="color: blue">return</span> <span style="color: #2b91af">HttpRuntime</span>.Cache[key].ToString();
<p style="margin: 0px">        }
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">
<summary></span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> Gets the folders in the specified path.</span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"></summary>

</span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray">
<param name="path"></span><span style="color: green">The path.</span><span style="color: gray"></param></span>
<p style="margin: 0px">        <span style="color: gray">///</span><span style="color: green"> </span><span style="color: gray"><returns></returns></span>
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">string</span>[] GetFolders(<span style="color: blue">string</span> path)
<p style="margin: 0px">        {
<p style="margin: 0px">            <span style="color: blue">return</span> <span style="color: #2b91af">Directory</span>.GetDirectories(MapPath(path));
<p style="margin: 0px">        }
<p style="margin: 0px">    }
</div>
</pre>
<p><span --="" \}}="" ??="" \}\par="" true\cf0="" \cf1="" return\cf0="" \{="" get\cf0="" \{\par="" isreusable\par="" bool\cf0="" public\cf0="" ??\par="" windowstheme));\par="" cssbase,="" \{1\}.css?\cf0="" window_themes="" ?\{0\}="" .format(\cf5="" string\cf0="" readpath(target,="" .isnullorempty(windowstheme))\par="" (!\cf1="" if\cf0="" s);\par="" csslib)\par="" in\cf0="" s="" (\cf1="" foreach\cf0="" .topdirectoryonly));\par="" searchoption\cf0="" \cf4="" ?*.css?\cf0="" \cf5="" .getfiles(path,="" directory\cf0="" >(\cf4="" <\cf1="" list\cf0="" new\cf0="" csslib="\par" >="" .mappath(folder);\par="" fileoperations\cf0="" path="\cf4" folder)\par="" target,="" stringbuilder\cf0="" readfolder(\cf4="" void\cf0="" static\cf0="" private\cf0="" );\par="" ?\\r\\n?\cf0="" target.append(\cf5="" target.append(readfile(fpath));\par="" fpath);\par="" \\r\\n\\r\\n?\cf0="" *="" \{0\}="" ?="" target.appendformat(\cf5="" fpath)\par="" readpath(\cf4="" ??\cf0="" #endif\par="" ??\cf1="" .readalltext(path);\par="" file\cf0="" system.io.\cf4="" #else\par="" fileoperations.readfile(path);\par="" return="" ??\cf7="" mode.\par="" production="" in="" is="" app="" the="" when="" disk="" from="" read="" file="" cache="" \cf6="" !debug="" #if\cf0="" .mappath(relativepath);\par="" relativepath)\par="" readfile(\cf1="" context.response.write(sb.tostring());\par="" context.response.write(cssminifier.compress(sb.tostring()));\par="" context.response.cache.setvaliduntilexpires(true);\par="" context.response.cache.setexpires(datetime.now.adddays(1));\par="" context.response.cache.setcacheability(httpcacheability.public);\par="" mode\par="" release="" handler="" this="" of="" results="" caching="" start="" ;\par="" css?\cf0="" ?text="" context.response.contenttype="\cf5" cssbase);\par="" readfolder(sb,="" ))\par="" ?application?\cf0="" (context.request.url.absoluteuri.contains(\cf5="" ();\par="" sb="\cf1" ];\par="" ?windows?\cf0="" windowstheme="context.Request.QueryString[\cf5" context.response.clear();\par="" context)\par="" httpcontext\cf0="" processrequest(\cf4="" common="" ~="">And the last piece of the setup is a handler that reads the css files into one string and outputs the minified version to the browser.<br />My handler will only work at production time while you're in debug mode it doesn't do anything but read them into one file.</span></p>
<p><span --="" \}}="" ??="" \}\par="" true\cf0="" \cf1="" return\cf0="" \{="" get\cf0="" \{\par="" isreusable\par="" bool\cf0="" public\cf0="" ??\par="" windowstheme));\par="" cssbase,="" \{1\}.css?\cf0="" window_themes="" ?\{0\}="" .format(\cf5="" string\cf0="" readpath(target,="" .isnullorempty(windowstheme))\par="" (!\cf1="" if\cf0="" s);\par="" csslib)\par="" in\cf0="" s="" (\cf1="" foreach\cf0="" .topdirectoryonly));\par="" searchoption\cf0="" \cf4="" ?*.css?\cf0="" \cf5="" .getfiles(path,="" directory\cf0="" >(\cf4="" <\cf1="" list\cf0="" new\cf0="" csslib="\par" >="" .mappath(folder);\par="" fileoperations\cf0="" path="\cf4" folder)\par="" target,="" stringbuilder\cf0="" readfolder(\cf4="" void\cf0="" static\cf0="" private\cf0="" );\par="" ?\\r\\n?\cf0="" target.append(\cf5="" target.append(readfile(fpath));\par="" fpath);\par="" \\r\\n\\r\\n?\cf0="" *="" \{0\}="" ?="" target.appendformat(\cf5="" fpath)\par="" readpath(\cf4="" ??\cf0="" #endif\par="" ??\cf1="" .readalltext(path);\par="" file\cf0="" system.io.\cf4="" #else\par="" fileoperations.readfile(path);\par="" return="" ??\cf7="" mode.\par="" production="" in="" is="" app="" the="" when="" disk="" from="" read="" file="" cache="" \cf6="" !debug="" #if\cf0="" .mappath(relativepath);\par="" relativepath)\par="" readfile(\cf1="" context.response.write(sb.tostring());\par="" context.response.write(cssminifier.compress(sb.tostring()));\par="" context.response.cache.setvaliduntilexpires(true);\par="" context.response.cache.setexpires(datetime.now.adddays(1));\par="" context.response.cache.setcacheability(httpcacheability.public);\par="" mode\par="" release="" handler="" this="" of="" results="" caching="" start="" ;\par="" css?\cf0="" ?text="" context.response.contenttype="\cf5" cssbase);\par="" readfolder(sb,="" ))\par="" ?application?\cf0="" (context.request.url.absoluteuri.contains(\cf5="" ();\par="" sb="\cf1" ];\par="" ?windows?\cf0="" windowstheme="context.Request.QueryString[\cf5" context.response.clear();\par="" context)\par="" httpcontext\cf0="" processrequest(\cf4="" common="" ~=""></span><span --="" \}}="" ??="" \}\par="" true\cf0="" \cf1="" return\cf0="" \{="" get\cf0="" \{\par="" isreusable\par="" bool\cf0="" public\cf0="" ??\par="" windowstheme));\par="" cssbase,="" \{1\}.css?\cf0="" window_themes="" ?\{0\}="" .format(\cf5="" string\cf0="" readpath(target,="" .isnullorempty(windowstheme))\par="" (!\cf1="" if\cf0="" s);\par="" csslib)\par="" in\cf0="" s="" (\cf1="" foreach\cf0="" .topdirectoryonly));\par="" searchoption\cf0="" \cf4="" ?*.css?\cf0="" \cf5="" .getfiles(path,="" directory\cf0="" >(\cf4="" <\cf1="" list\cf0="" new\cf0="" csslib="\par" >="" .mappath(folder);\par="" fileoperations\cf0="" path="\cf4" folder)\par="" target,="" stringbuilder\cf0="" readfolder(\cf4="" void\cf0="" static\cf0="" private\cf0="" );\par="" ?\\r\\n?\cf0="" target.append(\cf5="" target.append(readfile(fpath));\par="" fpath);\par="" \\r\\n\\r\\n?\cf0="" *="" \{0\}="" ?="" target.appendformat(\cf5="" fpath)\par="" readpath(\cf4="" ??\cf0="" #endif\par="" ??\cf1="" .readalltext(path);\par="" file\cf0="" system.io.\cf4="" #else\par="" fileoperations.readfile(path);\par="" return="" ??\cf7="" mode.\par="" production="" in="" is="" app="" the="" when="" disk="" from="" read="" file="" cache="" \cf6="" !debug="" #if\cf0="" .mappath(relativepath);\par="" relativepath)\par="" readfile(\cf1="" context.response.write(sb.tostring());\par="" context.response.write(cssminifier.compress(sb.tostring()));\par="" context.response.cache.setvaliduntilexpires(true);\par="" context.response.cache.setexpires(datetime.now.adddays(1));\par="" context.response.cache.setcacheability(httpcacheability.public);\par="" mode\par="" release="" handler="" this="" of="" results="" caching="" start="" ;\par="" css?\cf0="" ?text="" context.response.contenttype="\cf5" cssbase);\par="" readfolder(sb,="" ))\par="" ?application?\cf0="" (context.request.url.absoluteuri.contains(\cf5="" ();\par="" sb="\cf1" ];\par="" ?windows?\cf0="" windowstheme="context.Request.QueryString[\cf5" context.response.clear();\par="" context)\par="" httpcontext\cf0="" processrequest(\cf4="" common="" ~=""> </span></p>
<pre><!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red43\green145\blue175;\red163\green21\blue21;\red0\green128\blue0;\red128\green128\blue128;}??\fs20 \cf1 public\cf0  \cf1 class\cf0  \cf4 StylesHandler\cf0  :\cf4 IHttpHandler\par ??\cf0     \{\par ??        \cf1 private\cf0  \cf1 static\cf0  \cf1 string\cf0  windowsTheme;\par ??        \cf1 private\cf0  \cf1 const\cf0  \cf1 string\cf0  CSSBASE = \cf5 "~/common/css"\cf0 ;\par ??\par ??        \cf1 public\cf0  \cf1 void\cf0  ProcessRequest(\cf4 HttpContext\cf0  context)\par ??        \{\par ??            context.Response.Clear();\par ??\par ??            windowsTheme = context.Request.QueryString[\cf5 "windows"\cf0 ];\par ??\par ??            \cf4 StringBuilder\cf0  sb = \cf1 new\cf0  \cf4 StringBuilder\cf0 ();\par ??\par ??            \cf1 if\cf0  (context.Request.Url.AbsoluteUri.Contains(\cf5 "application"\cf0 ))\par ??                ReadFolder(sb, CSSBASE);\par ??\par ??            context.Response.ContentType = \cf5 "text/css"\cf0 ;\par ??\par ??\cf1 #if\cf0  !DEBUG \cf6 //start caching the results of this handler when in release mode\par ??\cf7             context.Response.Cache.SetCacheability(HttpCacheability.Public);\par ??            context.Response.Cache.SetExpires(DateTime.Now.AddDays(1));\par ??            context.Response.Cache.SetValidUntilExpires(true);\par ??            context.Response.Write(CssMinifier.Compress(sb.ToString()));\par ??\cf1 #else\par ??\cf0             context.Response.Write(sb.ToString());\par ??\cf1 #endif\par ??\cf0         \}\par ??\par ??        \cf1 private\cf0  \cf1 static\cf0  \cf1 string\cf0  ReadFile(\cf1 string\cf0  relativePath)\par ??        \{\par ??            \cf1 string\cf0  path = \cf4 FileOperations\cf0 .MapPath(relativePath);\par ??\cf1 #if\cf0  !DEBUG \cf6 //Cache the file read from disk when the app is in production mode.\par ??\cf7             return FileOperations.ReadFile(path);\par ??\cf1 #else\par ??\cf0             \cf1 return\cf0  System.IO.\cf4 File\cf0 .ReadAllText(path);\par ??\cf1 #endif\par ??\cf0         \}\par ??\par ??        \cf1 private\cf0  \cf1 static\cf0  \cf1 void\cf0  ReadPath(\cf4 StringBuilder\cf0  target, \cf1 string\cf0  fPath)\par ??        \{\par ??            target.AppendFormat(\cf5 "/* \{0\} */\\r\\n\\r\\n"\cf0 , fPath);\par ??            target.Append(ReadFile(fPath));\par ??            target.Append(\cf5 "\\r\\n"\cf0 );\par ??        \}\par ??\par ??        \cf1 private\cf0  \cf1 static\cf0  \cf1 void\cf0  ReadFolder(\cf4 StringBuilder\cf0  target, \cf1 string\cf0  folder)\par ??        \{\par ??            \cf1 string\cf0  path = \cf4 FileOperations\cf0 .MapPath(folder);\par ??\par ??            \cf4 List\cf0 <\cf1 string\cf0 > csslib =\par ??                \cf1 new\cf0  \cf4 List\cf0 <\cf1 string\cf0 >(\cf4 Directory\cf0 .GetFiles(path, \cf5 "*.css"\cf0 , \cf4 SearchOption\cf0 .TopDirectoryOnly));\par ??\par ??            \cf1 foreach\cf0  (\cf1 string\cf0  s \cf1 in\cf0  csslib)\par ??            \{\par ??                ReadPath(target, s);\par ??            \}\par ??\par ??            \cf1 if\cf0 (!\cf1 string\cf0 .IsNullOrEmpty(windowsTheme))\par ??            \{\par ??                ReadPath(target, \cf1 string\cf0 .Format(\cf5 "\{0\}/window_themes/\{1\}.css"\cf0 , CSSBASE, windowsTheme));\par ??            \}\par ??        \}\par ??\par ??\par ??        \cf1 public\cf0  \cf1 bool\cf0  IsReusable\par ??        \{\par ??            \cf1 get\cf0  \{ \cf1 return\cf0  \cf1 true\cf0 ; \}\par ??        \}\par ??    \}}
-->
<div style="font-size: 10pt; background: white; color: black; font-family: consolas">
<p style="margin: 0px"><span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">StylesHandler</span> :<span style="color: #2b91af">IHttpHandler</span>
<p style="margin: 0px">    {
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">static</span> <span style="color: blue">string</span> windowsTheme;
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">const</span> <span style="color: blue">string</span> CSSBASE = <span style="color: #a31515">"~/common/css"</span>;
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">void</span> ProcessRequest(<span style="color: #2b91af">HttpContext</span> context)
<p style="margin: 0px">        {
<p style="margin: 0px">            context.Response.Clear();
<p style="margin: 0px"> 
<p style="margin: 0px">            windowsTheme = context.Request.QueryString[<span style="color: #a31515">"windows"</span>];
<p style="margin: 0px"> 
<p style="margin: 0px">            <span style="color: #2b91af">StringBuilder</span> sb = <span style="color: blue">new</span> <span style="color: #2b91af">StringBuilder</span>();
<p style="margin: 0px"> 
<p style="margin: 0px">            <span style="color: blue">if</span> (context.Request.Url.AbsoluteUri.Contains(<span style="color: #a31515">"application"</span>))
<p style="margin: 0px">                ReadFolder(sb, CSSBASE);
<p style="margin: 0px"> 
<p style="margin: 0px">            context.Response.ContentType = <span style="color: #a31515">"text/css"</span>;
<p style="margin: 0px"> 
<p style="margin: 0px"><span style="color: blue">#if</span> !DEBUG <span style="color: green">//start caching the results of this handler when in release mode</span>
<p style="margin: 0px"><span style="color: gray">            context.Response.Cache.SetCacheability(HttpCacheability.Public);</span>
<p style="margin: 0px"><span style="color: gray">            context.Response.Cache.SetExpires(DateTime.Now.AddDays(1));</span>
<p style="margin: 0px"><span style="color: gray">            context.Response.Cache.SetValidUntilExpires(true);</span>
<p style="margin: 0px"><span style="color: gray">            context.Response.Write(CssMinifier.Compress(sb.ToString()));</span>
<p style="margin: 0px"><span style="color: blue">#else</span>
<p style="margin: 0px">            context.Response.Write(sb.ToString());
<p style="margin: 0px"><span style="color: blue">#endif</span>
<p style="margin: 0px">        }
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">static</span> <span style="color: blue">string</span> ReadFile(<span style="color: blue">string</span> relativePath)
<p style="margin: 0px">        {
<p style="margin: 0px">            <span style="color: blue">string</span> path = <span style="color: #2b91af">FileOperations</span>.MapPath(relativePath);
<p style="margin: 0px"><span style="color: blue">#if</span> !DEBUG <span style="color: green">//Cache the file read from disk when the app is in production mode.</span>
<p style="margin: 0px"><span style="color: gray">            return FileOperations.ReadFile(path);</span>
<p style="margin: 0px"><span style="color: blue">#else</span>
<p style="margin: 0px">            <span style="color: blue">return</span> System.IO.<span style="color: #2b91af">File</span>.ReadAllText(path);
<p style="margin: 0px"><span style="color: blue">#endif</span>
<p style="margin: 0px">        }
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">static</span> <span style="color: blue">void</span> ReadPath(<span style="color: #2b91af">StringBuilder</span> target, <span style="color: blue">string</span> fPath)
<p style="margin: 0px">        {
<p style="margin: 0px">            target.AppendFormat(<span style="color: #a31515">"/* {0} */\r\n\r\n"</span>, fPath);
<p style="margin: 0px">            target.Append(ReadFile(fPath));
<p style="margin: 0px">            target.Append(<span style="color: #a31515">"\r\n"</span>);
<p style="margin: 0px">        }
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: blue">private</span> <span style="color: blue">static</span> <span style="color: blue">void</span> ReadFolder(<span style="color: #2b91af">StringBuilder</span> target, <span style="color: blue">string</span> folder)
<p style="margin: 0px">        {
<p style="margin: 0px">            <span style="color: blue">string</span> path = <span style="color: #2b91af">FileOperations</span>.MapPath(folder);
<p style="margin: 0px"> 
<p style="margin: 0px">            <span style="color: #2b91af">List</span><<span style="color: blue">string</span>> csslib =
<p style="margin: 0px">                <span style="color: blue">new</span> <span style="color: #2b91af">List</span><<span style="color: blue">string</span>>(<span style="color: #2b91af">Directory</span>.GetFiles(path, <span style="color: #a31515">"*.css"</span>, <span style="color: #2b91af">SearchOption</span>.TopDirectoryOnly));
<p style="margin: 0px"> 
<p style="margin: 0px">            <span style="color: blue">foreach</span> (<span style="color: blue">string</span> s <span style="color: blue">in</span> csslib)
<p style="margin: 0px">            {
<p style="margin: 0px">                ReadPath(target, s);
<p style="margin: 0px">            }
<p style="margin: 0px"> 
<p style="margin: 0px">            <span style="color: blue">if</span>(!<span style="color: blue">string</span>.IsNullOrEmpty(windowsTheme))
<p style="margin: 0px">            {
<p style="margin: 0px">                ReadPath(target, <span style="color: blue">string</span>.Format(<span style="color: #a31515">"{0}/window_themes/{1}.css"</span>, CSSBASE, windowsTheme));
<p style="margin: 0px">            }
<p style="margin: 0px">        }
<p style="margin: 0px"> 
<p style="margin: 0px"> 
<p style="margin: 0px">        <span style="color: blue">public</span> <span style="color: blue">bool</span> IsReusable
<p style="margin: 0px">        {
<p style="margin: 0px">            <span style="color: blue">get</span> { <span style="color: blue">return</span> <span style="color: blue">true</span>; }
<p style="margin: 0px">        }
<p style="margin: 0px">    }
</div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://flanders.co.nz/2007/07/04/minimizing-css-files/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

