<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7455565</id><updated>2012-01-15T03:42:21.049-06:00</updated><category term='c#'/><category term='alt.net'/><category term='reflection'/><category term='nunit'/><title type='text'>Scott White's Tech Blog</title><subtitle type='html'>Technology with opinion</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>76</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7455565.post-1267503376992040463</id><published>2011-04-04T19:53:00.000-05:00</published><updated>2011-04-04T19:53:10.623-05:00</updated><title type='text'>The Way of Kung Fu Programming</title><content type='html'>&lt;p&gt;Kung Fu's literally meaning is &lt;b&gt;the skill achieved through hard work&lt;/b&gt;.  I was watching my kids watch the new version of Karate Kid and caught the scene where the kid is taking of his jacket and putting it back on repeatedly.&lt;/p&gt;&lt;p&gt;In the original Karate Kid the student was doing chores for his master, however, in politically correct times such as these this would be considered child labor so they decided to have him put on his jacket over and over again.  Nevertheless, the point that is being made in both films (and throughout all martial arts movies and dojos) is that skill is achieved through hard work and practice.&lt;/p&gt;&lt;p&gt;This is something that is severely lacking from most of our occupations and lives.  Our society is full of quick fixes for people in search of a quick buck within a culture that is driven more by money than passion.  For the uber ambitious you can trade your weekends and in a few years have an MBA (weekend MBA programs).  For the technically inclined, you can become Microsoft certified within one week even if you lack real world experience.  Nothing is wrong with either of these in of itself however they are more/less marketing tools for yourself to land a job. &lt;/p&gt;&lt;p&gt;Trades used to have apprenticeship where individuals would be mentored within their occupation and people were given time to mature based upon their natural abilities and ambition.  Repetition and practice is the key to becoming good at anything, but these two things are also great at filtering out people from a career for which they have no ambition.  Of course, management and programming are part of many careers which people seek out without any true ambition of the subject.  Unfortunately, the natural filters which used to exist that required someone to practice something no longer exist.  Today with enough money, charisma or connection just about anybody can &lt;b&gt;be&lt;/b&gt; anything, but that doesn't mean they can &lt;b&gt;achieve&lt;/b&gt; anything.&lt;/p&gt;&lt;p&gt;Having Kung fu programming would mean that you are skilled.  It doesn't mean that you're a a "Senior Developer" or "Architect"; these are just titles that our employers give to us.  Seek your passion and if that passion is programming then follow in the ways of Kung fu programmers such as: &lt;a href="http://lostechies.com/jimmybogard/"&gt;Jimmy Bogard&lt;/a&gt;, &lt;a href="http://ayende.com/blog/default.aspx"&gt;Oren (AKA Ayande)&lt;/a&gt;, &lt;a href="http://lostechies.com/derickbailey/"&gt;Derick Bailey&lt;/a&gt;, &lt;a href="http://codebetter.com/jeremymiller/"&gt;Jeremy Miller&lt;/a&gt; or anyone blogging at &lt;a href="http://lostechies.com/"&gt;Los Techies&lt;/a&gt; or &lt;a href="http://codebetter.com/"&gt;CodeBetter&lt;/a&gt;.  Also don't forget to practice even things that originally seem like basics and take some risks.  It will help you improve and open up opportunities.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-1267503376992040463?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/1267503376992040463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=1267503376992040463' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/1267503376992040463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/1267503376992040463'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2011/04/way-of-kung-fu-programming.html' title='The Way of Kung Fu Programming'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-7546672722635219512</id><published>2011-03-29T22:32:00.000-05:00</published><updated>2011-03-29T22:32:36.303-05:00</updated><title type='text'>"Whatever happens is the only thing..</title><content type='html'>that could have happened" .... &amp;nbsp;this is the creed of Open Spaces:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;"Whatever Happens is the Only Thing that Could have Happened"&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To some people, this saying sounds ludicrous, and honestly when I first heard it I laughed. &amp;nbsp;Since the time I first heard it a few years ago at the first Open Spaces I attended, it seems more true every day.&lt;br /&gt;&lt;br /&gt;Obviously there are no absolutes in life. &amp;nbsp;Self help books are one of the most popular categories in nonfiction but there is very little progress, why is this? &amp;nbsp;Perhaps because there is a difference between wanting your problems to go away and being ambitious &amp;amp; forward thinking enough for the fix.&lt;br /&gt;&lt;br /&gt;One of the first books that I read early in my career was Code Complete and the Software Project Survival Guide. &amp;nbsp;Both were good books however the psychology of a project team is not often a discussed topic. &amp;nbsp;The purpose of this creed and the point behind Open Spaces is empowerment. &amp;nbsp;When people are empowered they will make the most honest decisions, work harder and be happier.&lt;br /&gt;&lt;br /&gt;So why don't we do this more often and why does the word "deadline" even exist since it's only used to drive fear? &amp;nbsp;I asked a question on Twitter not too long ago, it was: &lt;i&gt;"serious question, have you ever seen a project that was on time, on schedule and on budget (within the original scope)?"&lt;/i&gt;. &amp;nbsp;Not one response from someone saying, "yes, we did". &amp;nbsp;One reply sums this up from &lt;b&gt;@sdether&lt;/b&gt; &lt;i&gt;"@kibbled_bits I've yet to see a product that finished with original scope"&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Do projects ever finish on time, scope &amp;amp; budget? &amp;nbsp;It's probably very uncommon but I'm sure it has happened before. &amp;nbsp;The magical question is why the mass delusion? &amp;nbsp;Collectively, programmers, analysts &amp;amp; project managers on any team have been on dozens of projects that have been late, over budget or delivered with less scope.&lt;br /&gt;&lt;br /&gt;Do we all suffer from a God complex, thinking we can fix everything with the power of our brains and refuse to accept the things that are outside of our control? &amp;nbsp;Or is the pressure of accepting the reality so great that denying the ultimate reality is easier than dealing with the pressure of knowing that you aren't tracking or worse, that you will miss the target.&lt;br /&gt;&lt;br /&gt;Agile projects are the reality, whether you are practicing this discipline or not. &amp;nbsp;The only thing that is released is the only thing that could have been released. &amp;nbsp;Unfortunately, this mindset is hard for some to accept so you can either accept the reality or keep living in the dark.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-7546672722635219512?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/7546672722635219512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=7546672722635219512' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7546672722635219512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7546672722635219512'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2011/03/whatever-happens-is-only-thing.html' title='&quot;Whatever happens is the only thing..'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-1090095112006361894</id><published>2010-11-14T20:02:00.002-06:00</published><updated>2010-11-14T20:10:13.317-06:00</updated><title type='text'>Nescafe Tasters Choice instant Coffee Reviewed</title><content type='html'>&lt;div class="mobile-photo"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_qZcJ0BAqrdY/TOCVD2rgeoI/AAAAAAAAAEk/r901lxk0Amg/s1600/photo-739278.JPG" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5539591435115854466" src="http://2.bp.blogspot.com/_qZcJ0BAqrdY/TOCVD2rgeoI/AAAAAAAAAEk/r901lxk0Amg/s320/photo-739278.JPG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;They were giving out these instant coffees at the PATH station.  Justto be clear, I've never been a big fan of Tasters Choice coffee or anyof the other big coffee makers however I did like Starbucks instantcoffee but found the price a bit steep.&lt;br /&gt;&lt;br /&gt;I chose a normal size mug, not an over sized mug, to pour one of thesepackets into as the higher ratio of water to instant grounds will makeit weaker. &amp;nbsp;The coffee produced from this packet was pretty good, at least theColumbian Roast was.  The body was even, low acidity but strong for aninstant coffee.&lt;br /&gt;&lt;br /&gt;Overall about as good as the Starbucks instant and at a fraction ofthe cost.  Amazon has both brands as cheap as 70 cents per packet forthe Starbucks instant compared to 17 cents for the Nescafe.  Verdict:recommended as alternative to mediocre work coffee or on the go.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-1090095112006361894?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/1090095112006361894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=1090095112006361894' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/1090095112006361894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/1090095112006361894'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2010/11/nescafe-tasters-choice-instant-coffee_14.html' title='Nescafe Tasters Choice instant Coffee Reviewed'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_qZcJ0BAqrdY/TOCVD2rgeoI/AAAAAAAAAEk/r901lxk0Amg/s72-c/photo-739278.JPG' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-579090710793882602</id><published>2010-11-14T14:18:00.003-06:00</published><updated>2010-11-14T16:10:07.788-06:00</updated><title type='text'>Getting Started: Programming Objective C on Windows</title><content type='html'>&lt;h3&gt;Why Learn Objective C?&lt;/h3&gt;&lt;p&gt;Objective C has made C programming cool again and it's making a comeback.  I've been interested in learning Objective C for many reasons: iPhone Development, statically compiled language with dynamic features and to brush up on my C programming.&lt;/p&gt;&lt;p&gt;It's been many years since I've done any C or C++ programming.  If the C language gave birth to C++ then Objective C would be its sibling.  Current versions of Objective C is basically the C language sandwiched with Smalltalk sprinkled with the goodness of dynamic programming and syntactic sugar.&lt;/p&gt;&lt;p&gt;Many people struggle writting iPhone applications in my opinion because they neglect the fact that Objective C is a first class language and like C# (.Net) or Java require time and patience to learn it first before learning the frameworks and paradigms.  This would be akin to trying to learn C#, HTML &amp; JQuery for the first time on an ASP.Net MVC project.&lt;/p&gt;&lt;p&gt;I will be treating Objective C like a first class language and I will be learning it on Windows first because I want to focus on the language first and not the frameworks (such as Cocoa).  My first goal is to get a running development environment on Windows for Objective C programming, write a simple "Hello World" app and compile it using both gcc and a make file.&lt;/p&gt;&lt;h3&gt;Setting up Development Environment on Windows from scratch&lt;/h3&gt;&lt;p&gt;GNUstep is the cross platform, free &amp; open source version of Objective C.  First download and install &lt;a href="http://ftpmain.gnustep.org/pub/gnustep/binaries/windows/gnustep-core-0.25.0-setup.exe"&gt;GNUstep Core&lt;/a&gt;, &lt;a href="http://ftpmain.gnustep.org/pub/gnustep/binaries/windows/gnustep-msys-system-0.25.1-setup.exe"&gt;GNUstep System&lt;/a&gt;, &lt;a href="http://ftpmain.gnustep.org/pub/gnustep/binaries/windows/gnustep-devel-1.1.1-setup.exe"&gt;GNUstep Development Environment&lt;/a&gt; and your favorite text editor such as &lt;a href="http://notepad-plus-plus.org/download"&gt;Notepad++&lt;/a&gt;.  After installing this a group will be added to your Start menu in Windows named GNUstep, beneath it is a shortcut to a "Shell".  Once open, you will be in a full command shell (BASH) you will be able to compile Objective C code files using make or gcc but we will first have to create a class file&lt;/p&gt;&lt;p&gt;The gcc that comes with GNUstep can compile C or Objective C apps.  We will first start with a Hello World app that uses C header files and then tweak it to use Objective C header files to make sure everything is lined up and configured correctly in your development environment.  Create a file called &lt;b&gt;main.m&lt;/b&gt; and paste the following into it.&lt;/p&gt;&lt;script class="brush: c" type="syntaxhighlighter"&gt;&lt;![CDATA[#import &lt;stdio.h&gt;int main (){ printf("hello world"); return 0;}]]&gt;&lt;/script&gt;&lt;p&gt;Within the GNUstep Shell navigate to the same folder and compile it (within GNUstep shell C:\YourProject would be /c/YourProject) by typing the following:&lt;/p&gt;&lt;script class="brush: bash" type="syntaxhighlighter"&gt;&lt;![CDATA[gcc -o helloworld main.m]]&gt;&lt;/script&gt;&lt;p&gt;Then test the output in shell by running the app and make sure the output is correct before continuing.&lt;/p&gt;&lt;script class="brush: bash" type="syntaxhighlighter"&gt;&lt;![CDATA[helloworld]]&gt;&lt;/script&gt;&lt;p&gt;Next we will modify the helloworld source to use Objective C library and make a build file for it so that it will compile.  First, update main.m to below:&lt;/p&gt;&lt;script class="brush: c" type="syntaxhighlighter"&gt;&lt;![CDATA[#import &lt;Foundation/Foundation.h&gt;int main (){  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  NSLog (@"Hello World");  return 0;}]]&gt;&lt;/script&gt;&lt;p&gt;GNUstep provides makefiles which include the references to the libraries and folders that you will need.  Create a file named GNUmakefile in our project directory and put the following into it.&lt;/p&gt;&lt;script class="brush: bash" type="syntaxhighlighter"&gt;&lt;![CDATA[# This makefile builds our HelloWorld App# Set a path variable to gnustep library directoryexport GNUSTEP_MAKEFILES=/c/GNUstep/gnustep/System/Library/Makefiles# Common Makefile Variablesinclude $(GNUSTEP_MAKEFILES)/common.make# Console Projectinclude $(GNUSTEP_MAKEFILES)/tool.make# Output NameTOOL_NAME = TestApp# Source FilesTestApp_OBJC_FILES = main.m# Additional Rules-include GNUmakefile.preamble# Objective C Rulesinclude $(GNUSTEP_MAKEFILES)/tool.make# Additional Rules-include GNUmakefile.postamble]]&gt;&lt;/script&gt;&lt;p&gt;Now to build it is simple, just type the following into our shell.&lt;/p&gt;&lt;script class="brush: bash" type="syntaxhighlighter"&gt;&lt;![CDATA[make]]&gt;&lt;/script&gt;&lt;p&gt;Some warnings should appear from the compiler but it should compile.  Run the output which should be in a folder named obj and verify the output.  There we go, our first Objective C app.  For more info on make files within GNUstep see the &lt;a href="http://www.gnustep.org/resources/documentation/Developer/Make/Manual/make_1.html"&gt;reference manual&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-579090710793882602?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/579090710793882602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=579090710793882602' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/579090710793882602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/579090710793882602'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2010/11/getting-started-programming-objective-c.html' title='Getting Started: Programming Objective C on Windows'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-8658641378706009583</id><published>2010-11-12T21:41:00.000-06:00</published><updated>2010-11-12T21:41:54.223-06:00</updated><title type='text'>Tips for Surviving NY Transit</title><content type='html'>Transit in the NY Metropolitan can be an exhausting nightmare or it can be a fun adventure. &amp;nbsp;Like most things in NY it all depends on your reaction to it. &amp;nbsp;Through a series of trial &amp;amp; error below is a list of things to do to make your way about NY area transit more enjoyable or at least less unenjoyable &amp;nbsp;;-)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Plan ahead&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;Even simple trips doing from one part of&amp;nbsp;Manhattan&amp;nbsp;to another can turn into an hour if you get lost or have to walk 20 long blocks. &amp;nbsp;Manhattan is a deceptively large place and just because it looks like a short walk on the map doesn't mean it is. &amp;nbsp;Take the subway as many connection to get as close to your destination as possible. &amp;nbsp;Trust me, you will get plenty of exercise going up &amp;amp; down stairs and walking a few blocks from the subway.&lt;br /&gt;&lt;br /&gt;Google Maps (web &amp;amp; mobile version) do an excellent job of providing directions &amp;amp; connections through NY transit but don't rely entirely on it because you will find yourself underground without a signal and if you cannot read a subway map then you will have to resort to begging complete strangers for help.&lt;br /&gt;&lt;br /&gt;Streets in Manhattan are like a grid and they are very straight and consistent. &amp;nbsp;Numbered streets are positioned North (higher numbers) to South (lower numbers) and avenues are positioned East (lower numbers) to West (higher numbers). &amp;nbsp;You can use these numbers as a compass and easily figure out which subway to go on since most subway lines in Manhattan run North (Uptown/Bronx) to South (Downtown/Brooklyn).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Don't Rush&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;It's tempting when going into the subway to be coming down the stairs and hear "Ding... Ding" and think: "That's my train". &amp;nbsp;It may be the completely wrong train or the right line in the wrong direction because remember each line goes in two directions (unless you are at the end of the line). &amp;nbsp;You will find yourself on a train on occasion after rushing onto the wrong one, always double check yourself and make sure you are on the right line and going the right direction. &amp;nbsp;It's not a big deal to get off at the next stop and go the other direction.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Avoid the Bus&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;If you live right near a bus stop that drops you off within walking distance of your destination then you cannot complain too much. &amp;nbsp;For everyone else the unpleasantness of the stop &amp;amp; go driving on top of the unreliability of the bus makes it a terrible way to travel not to mention the&amp;nbsp;Manhattan&amp;nbsp;Bus Terminal being a daunting place to learn the NYC bus system by. &amp;nbsp;Stick to the subway for simplicity &amp;amp; affordability.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;During rush hours avoid them empty seats&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;Choosing a seat with empty seats next to you just allow anyone to sit next to you and during rush hour the entire place it going to be packed and face it you don't want the smelly guy that takes up two seats sitting next to you. &amp;nbsp;Men, if your choice in seating is between an attractive young lady or an unknown quantity (and the possibility of overweight &amp;amp; smelly sitting next to you) you know what you are going to pick. &amp;nbsp;Ladies may choose to sit next to a young clean guy or choose the empty seat and stand the risk of sitting next to a bum rambling to himself or mole lady.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Choose the Train (heavy rail) for Long Distances&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;The train is blazing fast over long distances. &amp;nbsp;I swear I don't have time to even do small amounts of work before arriving at destination. &amp;nbsp;Train rides will cost about double the fair of the subway but if your time &amp;amp; comfort is more important than choose the train.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;Sidenote: La Guardia Airport Sucks&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;La Guardia is an&amp;nbsp;awful&amp;nbsp;airport. &amp;nbsp;Commuting to it is terrible because you cannot take a train or subway without having to transfer through a slow ass city bus. &amp;nbsp;Also the terminals are disconnected which means if you get dropped off at the wrong one you cannot walk through corridors to get to your desired terminal. &amp;nbsp;Choose JFK (my 1st pick) or Newark (in NJ). Sidenote's sidenote: also JetBlue rocks if you have a chance to fly them, they make flying pleasant again).&lt;br /&gt;&lt;br /&gt;I have a terrible sense of direction and I've gotten lost plenty of times, went the wrong way on the wrong line and wound up in Brooklyn instead of uptown, just work smart not hard in the NY transit system and you will be finding your way around in no time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-8658641378706009583?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/8658641378706009583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=8658641378706009583' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/8658641378706009583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/8658641378706009583'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2010/11/tips-for-surviving-ny-transit.html' title='Tips for Surviving NY Transit'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-749658146165190449</id><published>2010-11-07T19:37:00.000-06:00</published><updated>2010-11-07T19:37:40.025-06:00</updated><title type='text'>Relocation to NY</title><content type='html'>I haven't blogged lately, mostly because over the summer I took a job at Infusion Development to work as a consultant in New York. &amp;nbsp;Development in New York is mostly centered around financial services which provides inherently more complicated business processes than most industries.&lt;br /&gt;&lt;br /&gt;For the previous two years I had worked at Loomis in Houston and I have enjoyed my time there. &amp;nbsp;We worked with many banks and retail establishments which offered a lot of opportunity for integration and working with cash management systems. &amp;nbsp;I also had the opportunity to work with some people in IT that I really appreciated and&lt;br /&gt;&lt;br /&gt;In my short time here, I have enjoyed myself working on a project with one of the banks, developing on a trading platform. &amp;nbsp;Some of the challenges working on a WinForms trading application are: multiple threads &amp;amp;&amp;nbsp;concurrency, separation of concern in a traditional WinForms app and the performance on a real-time system.&lt;br /&gt;&lt;br /&gt;Relocating a family and settling in takes time but as things return to normal I'd like to blog about some of the following things I've been thinking of:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Learning Objective C on Windows&lt;/li&gt;&lt;li&gt;A fluent API for UI development&lt;/li&gt;&lt;li&gt;Surviving a .Net 2.0 Project and enjoy it&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Infusion is hiring Senior .Net programmers if you are interested in relocating to NYC and have a passion for development send me a message.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-749658146165190449?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/749658146165190449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=749658146165190449' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/749658146165190449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/749658146165190449'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2010/11/relocation-to-ny.html' title='Relocation to NY'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-7863984630420540178</id><published>2010-04-26T00:10:00.000-05:00</published><updated>2010-04-26T00:10:48.817-05:00</updated><title type='text'>NDepend 3.0 analysis of NAsserter</title><content type='html'>NDepend is an effective tool for analyzing .Net assemblies and provides information so that you can have an idea of whats going on. There are use cases for this in our development cycles. &amp;nbsp;For the purposes of simplicity I'm going to show the usage based on analyzing NAsserter.&lt;br /&gt;&lt;br /&gt;I recently posted some code to Google Code called NAsserter.  NAsserter started off as a proof of concept for prototyping something I had been able to do within Unit Tests (being able to make fluent style assertions in code) except for the purpose of throwing exceptions in code.  This is the first fluent API I have written.&lt;br /&gt;&lt;br /&gt;The API for NAsserter started as a small simple class and grew bit by bit.  I tried to refactor as much as it made sense to me.  I didn't model my internal constructs after any other fluent library as most of them have a need for much more extensibility than this.  The biggest inspirations were &lt;a href="http://code.google.com/p/nunitex/"&gt;NUnitEx&lt;/a&gt;, &lt;a href="http://www.nunit.org/index.php?p=constraintModel&amp;amp;r=2.5.5"&gt;NUnit's constraint based model&lt;/a&gt; and &lt;a href="http://fluentvalidation.codeplex.com/"&gt;Fluent Validation&lt;/a&gt;. These three projects provide exactly what they aim to, in which NAsserter is not intended to overlap.  NAsserter is NOT a Unit Testing or Validation framework.  It's simply for throwing exceptions in a predictable manner, including the messages. Thanks to &lt;a href="http://twitter.com/tehlike"&gt;Tuna&lt;/a&gt; (NHibernate &amp;amp; Castle contributor) constructive feedback.&lt;br /&gt;&lt;br /&gt;Upon getting a version of NAsserter (0.1) released that I am comfortable with, I proceeded to analyze it with NDepend; which I am still learning.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_qZcJ0BAqrdY/S9UYdZ1eA_I/AAAAAAAAAEE/Hzw7k9g7sww/s1600/Query+Edit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="384" src="http://3.bp.blogspot.com/_qZcJ0BAqrdY/S9UYdZ1eA_I/AAAAAAAAAEE/Hzw7k9g7sww/s640/Query+Edit.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;One of my favorite sections of the report is the assembly metrics which shows how abstract, stable, complex and well commented the code is. &amp;nbsp;I think the metrics of what you are looking for may be a little different based on if you are developing a framework (even the type of framework) or enterprise systems. &amp;nbsp;For instance, often times frameworks developers will make compromises in design for&amp;nbsp;simplicity&amp;nbsp;of use which is pragmatic: &amp;nbsp;use common sense.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_qZcJ0BAqrdY/S9UZnkiyxNI/AAAAAAAAAEM/xdaleHbQfj0/s1600/metrics.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="123" src="http://4.bp.blogspot.com/_qZcJ0BAqrdY/S9UZnkiyxNI/AAAAAAAAAEM/xdaleHbQfj0/s640/metrics.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;NAsserter is a simple codebase which shows through the analysis (the only dependency is mscorlib the .Net CLR) and doesn't really do NDepend justice.  NDepend is nice on large projects with a number of dependencies, especially for keeping track of different design metrics.  I am still learning the tool myself and I am finding new uses for it continually.  You can track your project's progress on different metrics since it keeps a baseline of the metrics.  NDepend is also very helpful for code reviews to be able to have an objective analysis of code, reducing some of the human element.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-7863984630420540178?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/7863984630420540178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=7863984630420540178' title='30 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7863984630420540178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7863984630420540178'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2010/04/ndepend-30-analysis-of-nasserter.html' title='NDepend 3.0 analysis of NAsserter'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_qZcJ0BAqrdY/S9UYdZ1eA_I/AAAAAAAAAEE/Hzw7k9g7sww/s72-c/Query+Edit.png' height='72' width='72'/><thr:total>30</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-9161367183985007002</id><published>2010-04-15T10:07:00.002-05:00</published><updated>2010-04-15T10:07:52.131-05:00</updated><title type='text'>Generic Singleton Factory</title><content type='html'>&lt;p&gt;Not too long after writing and blogging about a generic singleton base, I changed the code to use a Factory - a singleton factory to be specific.  Below is a factory which can be used to create a singleton instance of any class.  The original &lt;a href="http://scottwhite.blogspot.com/2010/03/when-you-implement-non-threadsafe.html"&gt;singleton base class&lt;/a&gt; implementors needed to be sealed or have unintended consequences of getting an instance of the wrong class.  This caused me to reflect and conclude that the design was deceptive as it was almost in essense a factory.  &lt;/p&gt;&lt;p&gt;Below is a refactored version which is a little more genuine.  This is my first crack, and requires generics.  I do not use this everywhere I use singletons but where the usage of a Factory fits better than a singleton such as when you have many implementors of the same interface and you want singleton creational behavior.&lt;/p&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[public static class SingletonFactory&lt;T&gt; where T : class{ private static readonly T _instance = (T)Activator.CreateInstance(typeof(T), true); public static T Instance() {  return _instance; }}]]&gt;&lt;/script&gt;&lt;p&gt;Jon Skeet's has a great article on some different singleton designs in his &lt;a href="http://www.yoda.arachsys.com/csharp/singleton.html"&gt;blog&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-9161367183985007002?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/9161367183985007002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=9161367183985007002' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/9161367183985007002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/9161367183985007002'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2010/04/generic-singleton-factory.html' title='Generic Singleton Factory'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-2036499037797140131</id><published>2010-04-07T11:20:00.000-05:00</published><updated>2010-04-07T11:20:46.698-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reflection'/><category scheme='http://www.blogger.com/atom/ns#' term='alt.net'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><category scheme='http://www.blogger.com/atom/ns#' term='nunit'/><title type='text'>Automatically mapping objects of same derived types</title><content type='html'>&lt;p&gt;I had a need to automatically map all properties from one class to another class.  These two classes had the same derived type, this was by design and not by accident. FYI: this example's Unit Test uses &lt;a href="http://www.nunit.org/"&gt;NUnit&lt;/a&gt; (2.5), &lt;a href="http://code.google.com/p/nbuilder/"&gt;NBuilder&lt;/a&gt;, both are optional as the test below can be easily adapted.&lt;/p&gt;&lt;p&gt;The scenario goes like this: you have a base class called BaseTransaction with derived classes DebitTransaction and CreditTransaction.  Often where there are many properties from the base class to map, it's redundant to write and tedious.  This bit of reflection below iterates through each property of the base class and maps it to a new object that it creates and returns this object.&lt;/p&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[public static class ObjectMapper{ public static TDest MapDerivedMembers&lt;TDerived, TDest&gt;(TDerived sourceObj) where TDest : TDerived {  var destinationObj = Activator.CreateInstance&lt;TDest&gt;();  foreach (var prop in typeof(TDerived).GetProperties(BindingFlags.Public | BindingFlags.Instance))  {   if (prop.CanRead &amp;&amp; prop.CanWrite)   {    var propValue = prop.GetValue(sourceObj, null);    prop.SetValue(destinationObj, propValue, null);   }  }  return destinationObj; }}]]&gt;&lt;/script&gt;&lt;p&gt;The following unit test shows the usage of this function, as well as outputs to the console showing that the bases members were in fact mapped.  Each derived class has unique properties of the same name (TransactionId), neither of these were mapped - otherwise an exception would have been thrown during the reflection code (prop.SetValue...).&lt;/p&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[    public class ObjectMapper_tests : AssertionHelper    {        [Test]        public void MapDerivedMembers_derived_class_to_sealed()        {            var debitIdGen = new SequentialGenerator&lt;int&gt;();            debitIdGen.StartingWith(1);            var debitTransactions = Builder&lt;DebitTransaction&gt;                .CreateListOfSize(10)                .WhereAll()                .Have(x =&gt; x.TransactionId = debitIdGen.Generate())                .Build();            var creditTransactions = new List&lt;CreditTransaction&gt;();            debitTransactions.ToList().ForEach(x =&gt; creditTransactions.Add(ObjectMapper.MapDerivedMembers&lt;BaseTransaction, CreditTransaction&gt;(x)));            Assert.AreEqual(debitTransactions.Count, creditTransactions.Count);            const string consoleOutputTemplate =                "TransactionId: {0} | Amount: {1} | Vendor Name: {2}";            for (int i = 0; i &lt; debitTransactions.Count; i++)            {                Expect(debitTransactions[i].Amount == creditTransactions[i].Amount);                Expect(debitTransactions[i].VendorName == creditTransactions[i].VendorName);                Console.Write("Debit object - " + consoleOutputTemplate + "\t",                    debitTransactions[i].TransactionId,                     debitTransactions[i].Amount,                    debitTransactions[i].VendorName);                Console.WriteLine("Mapped to Credit object - " + consoleOutputTemplate,                    creditTransactions[i].TransactionId,                     creditTransactions[i].Amount,                    creditTransactions[i].VendorName);            }        }    }    public abstract class BaseTransaction    {        public int Amount { get; set; }        public string VendorName { get; set; }    }    public sealed class CreditTransaction : BaseTransaction    {        private Guid _transactionId = Guid.NewGuid();        public Guid TransactionId        {            get { return _transactionId; }            set { _transactionId = value; }        }    }    public class DebitTransaction : BaseTransaction    {        public int TransactionId { get; set; }    }]]&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-2036499037797140131?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/2036499037797140131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=2036499037797140131' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/2036499037797140131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/2036499037797140131'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2010/04/automatically-mapping-objects-of-same.html' title='Automatically mapping objects of same derived types'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-5013675824137372247</id><published>2010-04-01T11:22:00.000-05:00</published><updated>2010-04-01T11:22:19.860-05:00</updated><title type='text'>DRY is dead, long live MOISTURE</title><content type='html'>&lt;p&gt;&lt;b&gt;&lt;a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself"&gt;DRY&lt;/a&gt;&lt;/b&gt; has become a big buzzword these days that puts emphasis on &lt;b&gt;reusability&lt;/b&gt;.  While there are some advantages to &lt;b&gt;reuse&lt;/b&gt;, I'm going to look at the downside; having DRY applications which are rigid crack over time due to the lack of &lt;b&gt;Moisture&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;What is &lt;b&gt;Moisture&lt;/b&gt;?  It is the syntactic sugar that makes procedural languages like JScript, VBScript, FoxPro and T-SQL powerful and fast.  Unless you've been hiding in a cave, you have started migrating from an ORM (such as NHibernate) to more future-proof constructs like Stored Procedures or DataSets.&lt;/p&gt;&lt;p&gt;In the past, the only downside to Stored Procedures was that Refactoring them took a lot of effort.  However, JetBrains has recently announced &lt;b&gt;ReProcedural&lt;/b&gt; to which lets you refactor code written in VBScript, Microsoft JScript or T-SQL&lt;/p&gt;&lt;p&gt;Once you have moved all of your business logic to stored procedures, just plan on having an average of 4 stored procedures per table (for insert, update, delete and select).  In a medium sized system with 50 tables, it's completely acceptable to have an upwards of 200 stored procedures or more.  At this point, your team should have enough T-SQL work to justify having a DBA letting you focus on increasing system &lt;b&gt;Moisture&lt;/b&gt; with procedural programming&lt;/p&gt;&lt;p&gt;Finally, you will want to rewrite any aspects &lt;b&gt;(AOP)&lt;/b&gt; as table triggers.  For non-DBAs out there, triggers are essentially AOP for databases.  For instance, if you wanted to implement logging your pointcut will either be your Stored Procedure or your Trigger.&lt;/p&gt;&lt;p&gt;Remember the basics of &lt;b&gt;Moisture&lt;/b&gt;: the more OO code you can migrate to a procedural language, the better.  While you can do procedural programming in C# or Java, it's not something enforceable as there is nothing stopping some n00b developer from creating an Interface or an Abstract Class.  As a general rule, all methods should be public and static&lt;/p&gt;&lt;p&gt;&lt;b&gt;April Fools!!!  :-)&lt;/b&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-5013675824137372247?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/5013675824137372247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=5013675824137372247' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/5013675824137372247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/5013675824137372247'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2010/04/dry-is-dead-long-live-moisture.html' title='DRY is dead, long live MOISTURE'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-2834753105097682196</id><published>2010-03-17T12:05:00.002-05:00</published><updated>2010-03-17T12:53:56.268-05:00</updated><title type='text'>Utility function to facilitate Domain AddChild functions</title><content type='html'>&lt;p&gt;As I make certain domain models more rich, one of the first things I will do is make the property of Child lists on the target domain model to a setter that is internal or public:&lt;/p&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[    public abstract class Reptile    {        public abstract bool HasShell { get; }    }    public class Turtle : Reptile    {        public void AddBaby(Turtle babyTurtle)        {            if (babyTurtle == null) throw new ArgumentNullException("babyTurtle");            if (BabyTurtles == null) BabyTurtles = new List&lt;Turtle&gt;();               BabyTurtles.Add(babyTurtle);            babyTurtle.Parent = this;        }        public IList&lt;Turtle&gt; BabyTurtles { get; protected internal set; }        public override bool HasShell { get { return true; } }        public Turtle MommyTurtle { get; protected set; }    }]]&gt;&lt;/script&gt;&lt;p&gt;There's nothing wrong with this code, it's short &amp; concise.  My only problem with it is that there is a repeatable pattern here, we are always going to check to see if the child is null, we will always need to check for the nullability of the target list, etc, etc.  If we could centralize this pattern, then if it changes we could change it there too.  The silver lining being that if we can reduce it to one line of code and that is always a good thing  :-).&lt;/p&gt;&lt;b&gt;Utility Function for Adding Child to Parent:&lt;/b&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[ public static void Add(object parent, object child, string parentPropertyName, string listPropertyName) {  // We have to pretty much use all reflection here because a a parent or child may have a derived class of a different type  // so we access generic lists of those types without using reflection  if (child == null) throw new ArgumentNullException("child");  if (parent == null) throw new ArgumentNullException("parent");  // Assign and initialize Child list  var listProp = parent.GetType().GetProperty(listPropertyName, BindingFlags.Public | BindingFlags.Instance);    if (listProp.GetValue(parent, null) == null)  {   var propType = listProp.PropertyType;   // generic lists   if (propType.IsGenericType)   {     var genericType = propType.GetGenericTypeDefinition();     var genericArg = propType.GetGenericArguments()[0];     // only the following generic collection types have an Add function     if (genericType == typeof(IList&lt;&gt;) || genericType == typeof(List&lt;&gt;) || genericType == typeof(ICollection&lt;&gt;))     {       listProp.SetValue(parent, Activator.CreateInstance(typeof(List&lt;&gt;).MakeGenericType(genericArg)), null);     }   }   // non-generic lists   else if (propType == typeof(IList) || propType == typeof(ArrayList)) // only non-generic types that have an Add function   {     listProp.SetValue(parent, Activator.CreateInstance&lt;ArrayList&gt;(), null);   }  }  var list = listProp.GetValue(parent, null);  list.GetType().GetMethod("Add").Invoke(list, new[] {child});  // Assign Parent reference on Child  child.GetType().GetProperty(parentPropertyName, BindingFlags.Public | BindingFlags.Instance)    .SetValue(child, parent, null); }]]&gt;&lt;/script&gt;&lt;b&gt;Usage:&lt;/b&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[ public void AddBaby(Turtle babyTurtle) {  CollectionUtil.Add(this, babyTurtle, "MommyTurtle", "BabyTurtles"); }]]&gt;&lt;/script&gt;&lt;p&gt;It works pretty well and I've ran unit tests against it for both generic lists and non-generic lists.  I first started off thinking I could do this with delegates, but I concluded that this code was not a proper use of delegates.  Feel free to sound off if I've gone completely mad or if there is a better way to do this.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-2834753105097682196?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/2834753105097682196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=2834753105097682196' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/2834753105097682196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/2834753105097682196'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2010/03/utility-function-to-facilitate-domain.html' title='Utility function to facilitate Domain AddChild functions'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-7344976842449880531</id><published>2010-02-15T11:10:00.001-06:00</published><updated>2010-02-15T11:16:10.290-06:00</updated><title type='text'>Unit Testing Daos with NHibernate with SessionScopes Version 2</title><content type='html'>&lt;p&gt;In a previous post I outlined how to modify Ayende's post to support contextual sessions.  With Contextual Sessions in NHibernate instead of injecting a Session into each DAO you will be injecting a SessionFactory in which the caller will invoke the SessionFactory's GetCurrentSession() in order to get the session tied to the context.  The previous example I mocked the SessionFactory and stubbed the GetCurrentSession() to return one session that would have been open for the life of a TestFixture.&lt;/p&gt;&lt;p&gt;This really isn't necessary if you bind the SessionFactory to a context.  This is very easy with NHibernate and the only requirement is that you tell NHibernate through it's configuration the scope of your session context.&lt;/p&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[                config = new Configuration()     ...                    .SetProperty(NHibernate.Cfg.Environment.CurrentSessionContextClass, typeof(CallSessionContext).FullName)     ...                 CurrentSessionContext.Bind(SessionFactory.OpenSession());]]&gt;&lt;/script&gt;&lt;p&gt;Something else I've thought about was that each TestFixture should only every test one DAO.  The tests in said fixture should also only ever reference one DAO to be an independent test.  Therefore if you are testing and a function from your DAO and need another object from persistence it would be better to call get the persisted object directly from your Session than from a separate DAO.  Too often I see people trying to reuse objects in their Unit Tests which violates the integrity of the tests because they would no longer be independent.&lt;/p&gt;&lt;p&gt;Therefore it would be nice if the InMemoryDatabaseTest exposed the target DAO to the TestFixture to make it easier, it could also set the SessionFactory of the DAO.  We can do this easily with Generics:&lt;/p&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[    public abstract class InMemoryDatabaseTest&lt;t&gt; : InMemoryDatabaseTest where T : BaseDao, new()    {        private T _dao;    ...         public T Dao        {            get            {                if (_dao == null) { _dao = new T() { SessionFactory = SessionFactory }; }                return _dao;            }        }]]&gt;&lt;/script&gt;&lt;p&gt;I have extended my existing base test fixture InMemoryDatabaseTest so that I don't break compatability with existing tests.  All my new DAO TestFixtures will inherit from the new Generic version.  I have also added some overloads for debugging.  If you pass a true debug flag to the constructor it will output the SQL to the output Window.  Also you can pass in a path to an actual SQLite file/db which will let you save the changes.  This is helpful for complicated tests where you want to see what is being saved to the database and test the queries NHibernate is executing against SQLite.&lt;/p&gt;&lt;b&gt;BaseDao&lt;/b&gt; that all your DAOs inherit from to facilitate contextual sessions.  This code should be in a separate assembly I call (rootnamespace).Data.Common&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[    public abstract class BaseDao    {        /// &lt;summary&gt;        /// Gets or sets the SessionFactory        /// &lt;/summary&gt;        /// &lt;remarks&gt;This setter is for DI.&lt;/remarks&gt;        public ISessionFactory SessionFactory { private get; set; }        /// &lt;summary&gt;Gets the current Session.&lt;/summary&gt;        /// &lt;remarks&gt;Returns the current session from the session factory.&lt;/remarks&gt;        public ISession Session        {            get { return SessionFactory.GetCurrentSession(); }        }        public IStatelessSession GetStatelessSession()        {            return SessionFactory.OpenStatelessSession();        }    }]]&gt;&lt;/script&gt;&lt;b&gt;InMemoryDatabaseTest&lt;/b&gt; that your test fixtures would inherit from.  This code should be in a separate assmebly I call (rootnamespace).Testing.Common&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[    public abstract class InMemoryDatabaseTest : IDisposable    {        // Using Static Dictionaries to support multiple mapping assemblies or databases        private static readonly Dictionary&lt;string, Configuration&gt; _configurations = new Dictionary&lt;string, Configuration&gt;();        private static readonly Dictionary&lt;string, ISessionFactory&gt; _realSessionFactories = new Dictionary&lt;string, ISessionFactory&gt;();        protected InMemoryDatabaseTest(Assembly assemblyContainingMapping) : this(assemblyContainingMapping, false, null) { }        protected InMemoryDatabaseTest(Assembly assemblyContainingMapping, bool debug) : this(assemblyContainingMapping, debug, null) { }        protected InMemoryDatabaseTest(Assembly assemblyContainingMapping, string connectionString) : this(assemblyContainingMapping, false, connectionString) { }        protected InMemoryDatabaseTest(Assembly assemblyContainingMapping, bool debug, string connectionString)        {            var key = assemblyContainingMapping.FullName;            Configuration config;            _configurations.TryGetValue(key, out config);            if (config == null)            {                config = new Configuration()                    .SetProperty(NHibernate.Cfg.Environment.ReleaseConnections, "on_close")                    .SetProperty(NHibernate.Cfg.Environment.ConnectionDriver, typeof(SQLite20Driver).AssemblyQualifiedName)                    .SetProperty(NHibernate.Cfg.Environment.ConnectionString, connectionString ?? "data source=:memory:;Version=3;")                    .SetProperty(NHibernate.Cfg.Environment.CurrentSessionContextClass, typeof(CallSessionContext).FullName)                    .SetProperty(NHibernate.Cfg.Environment.Dialect, typeof(SQLiteDialect).AssemblyQualifiedName)                    .SetProperty(NHibernate.Cfg.Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName)                    .SetProperty(NHibernate.Cfg.Environment.ShowSql, debug.ToString())                    .AddAssembly(assemblyContainingMapping);                                var sessionFactory = config.BuildSessionFactory();                                SessionFactory = config.BuildSessionFactory();                _configurations.Add(key, config);                _realSessionFactories.Add(key, sessionFactory);            }            else            {                SessionFactory = _realSessionFactories[key];            }            CurrentSessionContext.Bind(SessionFactory.OpenSession());            // Forward engineers the database and tables from the Hibernate Mappings            new SchemaExport(config).Execute(true, true, false, Session.Connection, null);        }        /// &lt;summary&gt;        /// Gets the SessionFactory        /// &lt;/summary&gt;        public ISessionFactory SessionFactory { get; private set; }        protected ISession Session { get { return SessionFactory.GetCurrentSession(); } }        public T CreateDao&lt;t&gt;() where T : BaseDao, new()        {            return new T() {SessionFactory = SessionFactory};        }        public void Dispose()        {            Session.Dispose();            SessionFactory.Dispose();        }    }    public abstract class InMemoryDatabaseTest&lt;t&gt; : InMemoryDatabaseTest where T : BaseDao, new()    {        private T _dao;        protected InMemoryDatabaseTest(Assembly assemblyContainingMapping) : this(assemblyContainingMapping, false) { }        protected InMemoryDatabaseTest(Assembly assemblyContainingMapping, bool debug) : this(assemblyContainingMapping, debug, null) { }        protected InMemoryDatabaseTest(Assembly assemblyContainingMapping, string connectionString) : this(assemblyContainingMapping, false, connectionString) { }                protected InMemoryDatabaseTest(Assembly assemblyContainingMapping, bool debug, string connectionString) : base(assemblyContainingMapping, debug, connectionString) { }        public T Dao        {            get            {                if (_dao == null) { _dao = new T() { SessionFactory = SessionFactory }; }                return _dao;            }        }    }]]&gt;&lt;/script&gt;&lt;b&gt;Usage&lt;/b&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[public class WidgetDao_Tests : InMemoryDatabaseTest&lt;widgetdao&gt;{        public WidgetDao_Tests() : base(typeof(Widget).Assembly, true) { }    [Test]  public void FindById_returns_with_valid_id()  {   var o = Dao.FindById(1); // a valid id   Assert.IsNotNull(o);  }]]&gt;&lt;/script&gt;&lt;p&gt;As you can see, the DAOs Unit Test didn't have to instantiate an instance of the target DAO since it already specified it as a Generic paramter.  While this only eliminates 2 lines of code it more importantly enforces one DAO per test.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-7344976842449880531?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/7344976842449880531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=7344976842449880531' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7344976842449880531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7344976842449880531'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2010/02/unit-testing-daos-with-nhibernate-with.html' title='Unit Testing Daos with NHibernate with SessionScopes Version 2'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-3071269285305420952</id><published>2009-11-19T10:10:00.004-06:00</published><updated>2009-11-21T17:21:32.122-06:00</updated><title type='text'>Mapping Date &amp; Time fields With NHibernate</title><content type='html'>&lt;div&gt;Let&amp;#39;s say you have an entity or POCO that you have mapped from NHibernate (or any ORM) and the database has separated out the Date &amp;amp; Time values into separate fields.  Your best best is to map these Date &amp;amp; Time fields into properties (DateTime for Date and TimeSpan for Time).  Then create a helper property in your POCO to add them together.  I&amp;#39;d like to add that I&amp;#39;m not a fan of separating these sorts of things in the database, but some people do this for some reason:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;HBM:&lt;/b&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: xml"&gt;&lt;![CDATA[&lt;property name="LogDate" column="LogDate" type="date" /&gt;&lt;property name="LogTime" column="LogTime" type="TimeAsTimeSpan" /&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;POCO&lt;/b&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[public virtual DateTime? LogDate { get; set; }public virtual TimeSpan? LogTime { get; set; }public virtual DateTime? LogDateAndTime{	get	{		return LogDate != null &amp;&amp; LogTime != null ? new DateTime(LogDate.Value.Ticks + LogTime.Value.Ticks) : (DateTime?)null;	}}]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In my case either of these could be null (yes another &lt;i&gt;great &lt;/i&gt;idea) which means I had to handle the nullability however this illustrates at least in worse case scenerio what will happen.  Date &amp;amp; Time data types are available in SQL Server 2008 and work with NHibernate 2.1 with .Net 2.0 or above.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-3071269285305420952?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/3071269285305420952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=3071269285305420952' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/3071269285305420952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/3071269285305420952'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/11/mapping-date-time-fields-with.html' title='Mapping Date &amp; Time fields With NHibernate'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-5412205526352547110</id><published>2009-11-16T17:20:00.002-06:00</published><updated>2009-11-21T17:24:36.361-06:00</updated><title type='text'>Associating Users &amp; Logins in SQL Server after Database Restore</title><content type='html'>Often times when you restore a database in SQL Server from one server to the next the Logins will become disassociated with the User a specific database.  We ran into this today and another software engineer found a good script from a guy he knows:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script type="syntaxhighlighter" class="brush: sql"&gt;&lt;![CDATA[USE Northwind -- whatever database you want to target DECLARE @UserName nvarchar(255)DECLARE orphanuser_cur cursor forSELECT UserName = nameFROM sysusersWHERE issqluser = 1 and (sid is not null and sid &lt;&gt; 0x0) and suser_sname(sid) is null ORDER BY name OPEN orphanuser_curFETCH NEXT FROM orphanuser_cur INTO @UserName WHILE (@@fetch_status = 0)BEGINPRINT @UserName + ' user name being resynced' EXEC sp_change_users_login 'Update_one', @UserName, @UserName FETCH NEXT FROM orphanuser_cur INTO @UserName END CLOSE orphanuser_curDEALLOCATE orphanuser_curGO]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Executing this script should find unassociated logins and reassociate them with the users in the current database&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-5412205526352547110?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/5412205526352547110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=5412205526352547110' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/5412205526352547110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/5412205526352547110'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/11/associating-users-logins-in-sql-server.html' title='Associating Users &amp; Logins in SQL Server after Database Restore'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-1559032753482298598</id><published>2009-11-06T08:53:00.003-06:00</published><updated>2009-11-21T17:47:38.022-06:00</updated><title type='text'>CI Done Simple with CruiseControl.Net + MSBuild</title><content type='html'>If you want to setup Continuous Integration the learning curve for automated builds can be moderate for some.&amp;nbsp;&lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET"&gt;CruiseControl.Net&lt;/a&gt;&amp;nbsp;(CCNet) allows you to integrate with automated build technologies such as &lt;a href="http://nant.sourceforge.net/"&gt;NAnt&lt;/a&gt;, MSBuild, etc. &amp;nbsp;The advantage of this is that you can specify the Visual Studio Solution so that MSBuild knows the references and source code to build.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This example assumes using TFS for source code control, which&amp;nbsp;definitely&amp;nbsp;isn't my favorite SCM tool but odds are if you want to keep it simple and you're not using NAnt then you're probably in a shop that uses TFS.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: xml;"&gt;&lt;![CDATA[&lt;project name="MySolution" queue="MySolution"&gt;	&lt;tasks&gt;		&lt;triggers&gt;			&lt;intervaltrigger seconds="30"/&gt;		&lt;/triggers&gt;		&lt;sourcecontrol type="vsts" autoGetSource="true"&gt;			&lt;username&gt;run_of_the_mill_NT_admin&lt;/username&gt;			&lt;password&gt;i_heart_m$&lt;/password&gt;			&lt;server&gt;http://mytfsserver:8080/&lt;/server&gt;			&lt;project&gt;$/MySolution/src/trunk&lt;/project&gt;			&lt;workingdirectory&gt;C:\dev\MySolution\trunk&lt;/workingDirectory&gt;		&lt;/sourcecontrol&gt;		&lt;msbuild&gt;			&lt;executable&gt;C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe&lt;/executable&gt;			&lt;workingdirectory&gt; C:\dev\MySolution\trunk &lt;/workingDirectory&gt;			&lt;projectfile&gt;My Solution.sln&lt;/projectFile&gt;			&lt;buildargs&gt;/noconsolelogger /p:Configuration=Debug /v:diag&lt;/buildArgs&gt;			&lt;logger&gt;C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll&lt;/logger&gt;		&lt;/msbuild&gt;	&lt;/tasks&gt;	&lt;publishers&gt;		&lt;modificationHistory/&gt;		&lt;statistics/&gt;		&lt;xmllogger logDir="log"/&gt;	&lt;/publishers&gt;&lt;/project&gt;]]&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-1559032753482298598?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/1559032753482298598/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=1559032753482298598' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/1559032753482298598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/1559032753482298598'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/11/ci-done-simple-with-cruisecontrolnet.html' title='CI Done Simple with CruiseControl.Net + MSBuild'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-7550256179389881362</id><published>2009-10-25T11:53:00.001-05:00</published><updated>2009-10-25T11:53:31.971-05:00</updated><title type='text'>Alt.Net Google Reader Bundle</title><content type='html'>&lt;div&gt;Google Reader is a great way to subscribe to different RSS feeds because it enables certain social networking features on top of them.  If you are &amp;quot;Sharing&amp;quot; with other users then you will see what other users in your network liked and their comments.  It also makes it very easy to send links to people via email.&lt;/div&gt; &lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;I created an ALT.Net Google Reader bundles a while back that I try to keep updated with different ALT.Net blogs that I subscribe to.  To subscribe to this bundle click the link below and then click the link &amp;quot;Subscribe&amp;quot;.&lt;/div&gt; &lt;a href="http://www.google.com/reader/bundle/user/03066432769507324653/bundle/Alt.Net"&gt;http://www.google.com/reader/bundle/user/03066432769507324653/bundle/Alt.Net&lt;/a&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;You can expand the feeds to see what you are subscribing to and even remove certain feeds after you add the bundle.  If you have an ALT.Net blog and would like your blog added to this bundle just send me a message on Twitter or leave a comment here.&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-7550256179389881362?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/7550256179389881362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=7550256179389881362' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7550256179389881362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7550256179389881362'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/10/altnet-google-reader-bundle.html' title='Alt.Net Google Reader Bundle'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-2316669106403880081</id><published>2009-09-29T21:43:00.017-05:00</published><updated>2009-11-21T17:46:39.883-06:00</updated><title type='text'>Practical use for NUNit 2.5's [TestCase]</title><content type='html'>Since &lt;a href="http://nunit.org/index.php"&gt;NUnit 2.5&lt;/a&gt;, NUnit has supported a concept of Test Cases. &amp;nbsp;Briefly a test case to NUnit is a test which runs with a different set of parameters and can expect a different set of results. &amp;nbsp;This has the potential to minimize the amount of code required to write new test methods.&lt;br /&gt;&lt;br /&gt;To this point I've been using standard [Test] attributes and since seeing this attribute in the documentation I've been thinking about uses for it. &amp;nbsp;Now that I've started using [TestCase] I've thought of some other uses for it cutting my test fixtures down to 1/2 or less the size previously.&lt;br /&gt;&lt;br /&gt;Below is an simple example of the code without the [TestCase] using the traditional [Test] attribute:&lt;br /&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[[Test]public void Valid_user(){    WebUser user = new WebUser { Id = 1, Username = "jdoe", Password = "asdf", PasswordReminder = "home row" };    IValidatior validator = new UserValidator();    Assert.IsFalse(validator.Validate(user));}[Test]public void Invalid_password_reminder_is_empty(){    WebUser user = new WebUser { Id = 1, Username = "jdoe", Password = "asdf", PasswordReminder = string.Empty };    IValidatior validator = new UserValidator();    Assert.IsFalse(validator.Validate(user));}[Test]public void Invalid_password_is_empty(){    WebUser user = new WebUser { Id = 1, Username = "jdoe", Password = string.Empty, PasswordReminder = "home row" };    IValidatior validator = new UserValidator();    Assert.IsFalse(validator.Validate(user));}]]&gt;&lt;/script&gt;&lt;br /&gt;The above code can be trimmed down to one function using the [TestCase] attribute:&lt;br /&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[[TestCase(0, "jdoe", "mypass", "my favorite pass", Result = true, TestName = "Valid New WebUser")][TestCase(1, "jdoe", "", "home row", Result = false, TestName = "Invalid WebUser - Empty Password")][TestCase(1, "jdoe", "asdf", "", Result = false, TestName = "Invalid WebUser - Empty PasswordReminder")]public bool Validate_users(int id, string username, string password, string passwordReminder){    WebUser user = new WebUser { Id = id, Username = username, Password = password, PasswordReminder = passwordReminder };    IValidatior validator = new UserValidator();    return validator.Validate(user);}]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Consolas, 'Courier New', Courier, monospace; font-size: small; white-space: pre;"&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium; white-space: normal;"&gt;The other beautiful thing about [TestCase]s is that it collapses each test case underneath a node which actually looks cleaner:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_qZcJ0BAqrdY/SsLFjOJh1dI/AAAAAAAAAD4/2aag_NIl5U0/s1600-h/nunit-2.5-pic.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_qZcJ0BAqrdY/SsLFjOJh1dI/AAAAAAAAAD4/2aag_NIl5U0/s320/nunit-2.5-pic.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;A couple of notes on the code above. &amp;nbsp;The compiler (C# here) will not allow you to use object initializers as a parameter to the [TestCase] so you &lt;b&gt;cannot&lt;/b&gt; create a test function Validate(object myUser) and do something like below.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[// Will not work[TestCase(new WebUser { Id = id, Username = username, Password = password, PasswordReminder = passwordReminder })]]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;This is because the compiler will only allow constants in attributes, however if you really need something like this, NUnit allows a work around. This is documented here.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-2316669106403880081?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/2316669106403880081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=2316669106403880081' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/2316669106403880081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/2316669106403880081'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/09/practical-use-for-nunit-25.html' title='Practical use for NUNit 2.5&apos;s [TestCase]'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_qZcJ0BAqrdY/SsLFjOJh1dI/AAAAAAAAAD4/2aag_NIl5U0/s72-c/nunit-2.5-pic.PNG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-4859062444993690566</id><published>2009-09-27T15:15:00.001-05:00</published><updated>2009-09-27T15:15:56.544-05:00</updated><title type='text'>Houston TechFest Samples</title><content type='html'>Houston TechFest was a lot of fun, I attended some very interesting sessions and had the opportunity to present on the topic of NHibernate.  I have uploaded the samples and they are downloadable by &lt;a href="http://files.me.com/scott.w.white/b5m1ar"&gt;clicking here&lt;/a&gt;.  The presentation is available &lt;a href="http://files.me.com/scott.w.white/o44hab"&gt;here&lt;/a&gt;. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-4859062444993690566?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/4859062444993690566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=4859062444993690566' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/4859062444993690566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/4859062444993690566'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/09/houston-techfest-samples.html' title='Houston TechFest Samples'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-5729128757891267286</id><published>2009-09-23T17:13:00.002-05:00</published><updated>2009-11-21T17:51:42.158-06:00</updated><title type='text'>Unit Testing - Mocking to test Edge Cases with NHibernate</title><content type='html'>Sometimes in code you want to test edge cases, some of these can be difficult to test even with integration tests because of database constraints, etc.  This may be a business key or unique identifier (that&amp;#39;s not a primary key)- may be enforced or not.  The key is you make an assumption that in code you want to test for.  Mocking dependencies is the key here, to create behavior that would not otherwise be possible.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unlike the pattern illustrated by &lt;a href="http://ayende.com/Blog/archive/2009/04/28/nhibernate-unit-testing.aspx"&gt;Ayende&lt;/a&gt; or that I added onto &lt;a href="http://scottwhite.blogspot.com/2009/06/unit-testing-nhibernate-with.html"&gt;here&lt;/a&gt;, I wanted NHibernate&amp;#39;s SessionFactory and Session objects to return data that I could not return from the database because of unique index constraints.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In this scenerio I&amp;#39;m returning data from the database that matches certain values and it should always return a list that contains either 0 or 1 objects otherwise it throws an exception:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[IList&lt;Animal&gt; list = Session.CreateCriteria(typeof(Animal))	.Add(Expression.Eq("TagNumber", tagNumber))	.List&lt;Animal&gt;();switch (list.Count){	case 0:		return null;	case 1:		return list[0];	default:		throw new InvalidResultsException(list.Count, 0, 1);}]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;div&gt;Problem is that integration tests are unlikely to uncover this error with normal data and end user testing won&amp;#39;t uncover it either.  This is simple, but I want to make certain that the exception is correctly thrown.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The only tricky part really is that after mocking the ISessionFactory &amp;amp; ISession objects you need to also mock each ICriteria object returned from the Session object.  So with Rhino Mocks after telling it to expect a call to CreateCriteria that returns an ICriteria, we also need to create expectations for this result calling Add and its result calling list.  This is because fluent interfaces use method chaining which makes this part a little tedious:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[[Test][ExpectedException(typeof(InvalidResultsException))]public void Find_by_tag_with_multiple_matches(){AnimalDao dao = new AnimalDao();MockRepository mocks = new MockRepository();var sessionFactory = mocks.CreateMock&lt;ISessionFactory&gt;();dao.SessionFactory = sessionFactory;ISession session = mocks.CreateMock&lt;ISession&gt;();ICriteria createCriteria = mocks.CreateMock&lt;ICriteria&gt;();ICriteria addCrit = mocks.CreateMock&lt;ICriteria&gt;();using (mocks.Record()){	Expect.Call(sessionFactory.GetCurrentSession()).Return(session);	var bogusList = Builder&lt;Animal&gt;.CreateListOfSize(2).Build();	Expect.Call(session.CreateCriteria(typeof(Animal))).Return(createCriteria);	Expect.Call(createCriteria.Add(null)).IgnoreArguments().Return(addCrit);	Expect.Call(addCrit.List&lt;Animal&gt;()).Return(bogusList);}using (mocks.Playback()){	dao.FindByTag("1234");}]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;div&gt;This allows us to now test what would actually happen if more than one Animal objects were returned.  NHibernate makes this easy because there are interfaces for pretty much every object.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;FYI: this code uses Rhino Mocks, NBuilder, NUnit &amp;amp; NHibernate&lt;/i&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-5729128757891267286?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/5729128757891267286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=5729128757891267286' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/5729128757891267286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/5729128757891267286'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/09/unit-testing-mocking-to-test-edge-cases.html' title='Unit Testing - Mocking to test Edge Cases with NHibernate'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-7237475398660918676</id><published>2009-09-11T22:05:00.005-05:00</published><updated>2009-11-22T22:38:14.099-06:00</updated><title type='text'>NHibernate, Spring.Net &amp; Dependency Injection</title><content type='html'>&lt;div&gt;Inverson of Control (IoC) is a very powerful concept.  The basic premise of IoC is to invert elements of your programming paradigm for flexibility and extensibility.  Most procedural or OO code the linkages are hard code.  Most data access code, take DAO for instance, need a handle to a connection object.  Fortunately if you are using a good persistence framework like NHibernate you don't have to directly deal with the ADO Connection object as it handles that for your, however you need to efficiently manage an NHibernate Session.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How to do so is very important in ASP.Net applciations as you may have dozens of request per second and if you handle this poorly your application performance will suffer.  Handle it well and you will often have better performance than straight ADO.Net applications.&lt;/div&gt;&lt;div&gt;Let's take two simple application layers UI and Data Layer.  Our data layer contains our DAOs (data access objects) which perform direct interaction with our database and of course our UI contains all necessary user interface related code. &lt;br /&gt;&lt;/div&gt;&lt;div&gt;UI Code&lt;/div&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[private IDao&lt;appsection&gt; _genericAppSectionDao;public IDao&lt;appsection&gt; GenericAppSectionDao{  set { _genericAppSectionDao = value; }}protected void ApplicationGrid_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e){  ApplicationGrid.DataSource = _genericAppSectionDao.FindAll();}]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;div&gt;The public setter that we declare here exists for dependency injection (DI), this will allow Spring.Net to set (or inject) our dependencies for us.  We configure Spring to set this pages dependencies in our configuration file like the following:&lt;/div&gt;&lt;script type="syntaxhighlighter" class="brush: xml"&gt;&lt;![CDATA[&lt;object type="Applications/Default.aspx"&gt;  &lt;property name="GenericAppSectionDao" ref="GenericAppSectionDao" /&gt;&lt;/object&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;div&gt;This section is telling Spring that the page (Applications/Default.aspx) has a property named GenericAppSectionDao which needs to be set to a reference of an object named GenericAppSectionDao&lt;br /&gt;&lt;br /&gt;At your applications first run (first request for a website) Spring will create all of these objects in memory for you and set them up (unless you configure them differently of course).  This requires an upstart cost but saves performance with each request after the first.&lt;br /&gt;&lt;br /&gt;Next we need to tell Spring how to create this object GenericAppSectionDao:&lt;br /&gt;&lt;/div&gt;&lt;script type="syntaxhighlighter" class="brush: xml"&gt;&lt;![CDATA[&lt;object id="BaseDao" type="Project.Data.BaseDao, Project.Data" abstract="true"&gt;	&lt;property name="SessionFactory" ref="SessionFactory"/&gt;&lt;/object&gt;&lt;object id="GenericAppSectionDao" type="Project.Data.Common.Dao&amp;lt;Project.Domain.AppSection, Loomis.Portal.Domain&amp;gt;" parent="BaseDao"/&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;The first object element creates an abstract object so that Spring knows to create before the objects that are dependent on it.  Next we tell Spring to create an instance of a generic class called Dao that provides basic Dao functions and we tell Spring that it's dependent upon BaseDao (again so that Spring knows to create this object after it creates its parent).  The generic Dao class looks like the following:&lt;br /&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[public class Dao&lt;t&gt; : BaseDao, IDao&lt;T&gt;{  /// &lt;summary&gt;  /// Deletes a persisted object.  /// &lt;/summary&gt;  /// &lt;param name="entity"&gt;Target object to be deleted.&lt;/param&gt;  public void Delete(T entity)  {    Session.Delete(entity);  }  /// &lt;summary&gt;  /// Retrieves all objects of desired type..  /// &lt;/summary&gt;  /// &lt;returns&gt;All objects of desired type.&lt;/returns&gt;  public IList&lt;t&gt; FindAll()  {    return Session.CreateCriteria(typeof(T)).List&lt;t&gt;();  }]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;Lastly is BaseDao which provides a public setter to set the SessionFactory with a public Getter to get the current session.  This enables SessionScopes which are a good idea for web apps.  BaseDao code is below&lt;br /&gt;&lt;/div&gt;&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[public abstract class BaseDao{  private ISessionFactory _sessionFactory;  /// &lt;summary&gt;  /// Sets the SessionFactory  /// &lt;/summary&gt;  /// &lt;remarks&gt;This setter is for DI.&lt;/remarks&gt;  public ISessionFactory SessionFactory  {    set { _sessionFactory = value; }  }  /// &lt;summary&gt;Gets the current Session.&lt;/summary&gt;  /// &lt;remarks&gt;Returns the current session from the session factory.&lt;/remarks&gt;  public ISession Session  {    get { return _sessionFactory.GetCurrentSession(); }  }}]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;You could obviously perform the same exact methods with any IoC framework (Castle or anything else).  The only difference should be the XML files.  Dependency Injection (DI) is a form of IoC and reinforces best practices for writing proper unit tests because you can isolate each layer you are testing and mock its dependencies.  It also facilitates AOP so you can do all sorts of stuff (transactions, logging, etc) between application layers automatically.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-7237475398660918676?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/7237475398660918676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=7237475398660918676' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7237475398660918676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7237475398660918676'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/09/nhibernate-springnet-dependency.html' title='NHibernate, Spring.Net &amp; Dependency Injection'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-7319926448618033695</id><published>2009-08-26T16:44:00.003-05:00</published><updated>2009-11-21T17:56:45.919-06:00</updated><title type='text'>Working Around DLL Hell in .Net</title><content type='html'>&lt;b&gt;Assembly Bindings with different Public Key Tokens&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;There was a little &lt;a href="http://forum.springframework.net/archive/index.php/t-470.html"&gt;fiasco&lt;/a&gt; started when log4net accidentally generated a new public key token for log4net from version 1.2.9.0 to 1.2.10.0.  This became evident to me when I tried to do an &lt;a href="http://scottwhite.blogspot.com/2009/08/using-springnet-proxy-factory-with.html"&gt;assembly redirect&lt;/a&gt; in the .config file for NAnt so that it would use the newer version of log4net.  You get the public key token from any .Net assembly by executing the following command on it:&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: shell"&gt;&lt;![CDATA[sn -T log4net.dll]]&gt;&lt;/script&gt;&lt;br /&gt;If you perforrm this against log4net 1.2.9 &amp;amp; 1.2.10 you will get b32731d11ce58905 &amp;amp; 1b44e1d426115821.  Therefore if you are executing a custom task that requires log4net (or who&amp;#39;s dependencies require log4net) .Net will not let you redirect the two version because as far as Microsoft is concerend, they are not two different version of the same thing, they are different assemblies altogether.  However since they are different assemblies technically the work around is to rename one of the new assembly (1.2.10 in this scenerio) filename to log4net-1.2.10.dll.  Next in the NAnt.exe.config add the following within the &amp;lt;configuration&amp;gt; element&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: xml"&gt;&lt;![CDATA[&lt;runtime&gt;  &lt;assemblybinding xmlns="urn:schemas-microsoft-com:asm.v1"&gt;	&lt;probing privatePath="lib" /&gt;	&lt;dependentassembly&gt;	  &lt;assemblyidentity name="log4net" publicKeyToken="b32731d11ce58905" culture="neutral" /&gt;	  &lt;codebase version="1.2.9.0" href="log4net.dll"/&gt;	&lt;/dependentAssembly&gt;	&lt;dependentassembly&gt;	  &lt;assemblyidentity name="log4net" publicKeyToken="1b44e1d426115821" culture="neutral" /&gt;	  &lt;codebase version="1.2.10.0" href="log4net-1.2.10.dll"/&gt;	&lt;/dependentAssembly&gt;  &lt;/assemblyBinding&gt;&lt;/runtime&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;div&gt;This will force .Net to load the new assembly alongside the old one thus avoiding any compatibility issues, bypassing DLL hell for good.&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-7319926448618033695?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/7319926448618033695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=7319926448618033695' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7319926448618033695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7319926448618033695'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/08/working-around-dll-hell-in-net.html' title='Working Around DLL Hell in .Net'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-4089596302136192594</id><published>2009-08-18T09:39:00.001-05:00</published><updated>2009-08-18T09:39:26.715-05:00</updated><title type='text'>.Net Programmer Toolbox Summer '09</title><content type='html'>So for the Summer of 2009 this is the software that is in this .Net programmer&amp;#39;s toolbox:&lt;br&gt;&lt;i&gt;($ denotes how expensive it is. FOSS - free open source software)&lt;/i&gt;&lt;br&gt;&lt;ol&gt;&lt;li&gt;Visual Studio 2008 with SP1 - $$$&lt;br&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="https://sourceforge.net/projects/nhibernate/"&gt;NHibernate 2.1&lt;/a&gt; - ORM framework - FOSS&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.springframework.net/download.html"&gt;Spring Framework 1.3&lt;/a&gt; - IoC/DI framework - FOSS&lt;br&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://nant.sourceforge.net/"&gt;NAnt 0.86&lt;/a&gt; - .Net build tool - FOSS&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://nunit.org/index.php?p=download"&gt;NUnit 2.5&lt;/a&gt; - .Net Unit Testing framework - FOSS&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.telerik.com/products/aspnet-ajax.aspx"&gt;Telerik AJAX Controls 2009&lt;/a&gt; - great inexpensive web controls for .Net.  They also have a fairly liberal license. - $$&lt;br&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.jetbrains.com/resharper/download/"&gt;Resharper&lt;/a&gt; - inexpensive Visual Studio add-on for refactoring and overall enhancing your IDE - $&lt;/li&gt;&lt;li&gt;&lt;a href="https://sourceforge.net/projects/sqlite-dotnet2/"&gt;Sqlite ADO.Net Provider&lt;/a&gt; - lightweight database great for Unit Testing or client-side database - FOSS&lt;/li&gt; &lt;li&gt;&lt;a href="http://code.msdn.microsoft.com/sourceanalysis"&gt;StyleCop&lt;/a&gt; &amp;amp; &lt;a href="http://code.google.com/p/stylecopext/downloads/list"&gt;StyleCopExt&lt;/a&gt; - Microsoft&amp;#39;s source code analysis tool &amp;amp; my extentions - free&lt;/li&gt; &lt;li&gt;&lt;a href="https://sourceforge.net/projects/mygeneration/"&gt;MyGeneration 1.3&lt;/a&gt; - .Net code generation tool - FOSS&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/nbuilder/"&gt;NBuilder&lt;/a&gt; - tired of writing hundreds of lines of code to create objects in memory for unit testing? This is for you - FOSS&lt;/li&gt; &lt;li&gt;&lt;a href="http://ayende.com/projects/rhino-mocks/downloads.aspx"&gt;Rhino Mocks&lt;/a&gt; - best mocking framework for .Net. Supports generics - FOSS&lt;br&gt;&lt;/li&gt;&lt;/ol&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-4089596302136192594?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/4089596302136192594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=4089596302136192594' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/4089596302136192594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/4089596302136192594'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/08/net-programmer-toolbox-summer-09.html' title='.Net Programmer Toolbox Summer &apos;09'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-2652167272458780164</id><published>2009-08-17T13:12:00.003-05:00</published><updated>2009-11-21T18:00:13.761-06:00</updated><title type='text'>Centering a DIV within HTML</title><content type='html'>I&amp;#39;m by far from an HTML or DIV expert but I try to stay compliant.  One of the change to HTML 4.01 standard requires that tables no longer be used for layouts but instead only be used for grid type data.  Putting that debate aside working with DIVs is a little tricky if you have grown accustom to HTML tables.  Until recently, what has long evaded me has been centering content within HTML without a TABLE or the deprecated CENTER tag until now.&lt;br /&gt;&lt;br /&gt;There is a trick using negative margins that does it nicely and seems to work well in FireFox &amp;amp; IE.  First you will need to figure out a fixed size for your DIV (a good size that you content will fit within).  Let say your DIV is 300 pixels wide, next you multiply it times -.5 which will give you your left margin of -150 pixels.  You will always position this centered DIV using 50% left.  This will center your HTML content inside the DIV horizontally.  Perform the same technique with height &amp;amp; top margin in order to center vertically.&lt;br /&gt;&lt;br /&gt;This will look like the following:&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: html"&gt;&lt;![CDATA[&lt;body&gt;  &lt;div style="position: absolute; width: 300px; margin-left: -150px; left: 50%; height: 100px; margin-top: -50px; top: 50%; border: solid 1px; text-align: center;"&gt;    &lt;h1&gt;Hello World&lt;/h1&gt;    &lt;p&gt;This should be centered.&lt;/p&gt;  &lt;/div&gt;&lt;/body&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;div&gt;&lt;font size="2"&gt;&lt;b&gt;See Also:&lt;/b&gt; &lt;a href="http://www.w3.org/TR/1999/REC-html401-19991224/struct/tables.html#h-11.1"&gt;W3C Standard on HTML 4.01 Tables&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Tables should not be used purely as a means to layout document content as this may present problems when rendering to non-visual media. Additionally, when used with graphics, these tables may force users to scroll horizontally to view a table designed on a system with a larger display. To minimize these problems, authors should use &lt;a href="http://www.w3.org/TR/1999/REC-html401-19991224/present/styles.html"&gt;style sheets&lt;/a&gt; to control layout rather than tables.&lt;/i&gt;&lt;/font&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-2652167272458780164?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/2652167272458780164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=2652167272458780164' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/2652167272458780164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/2652167272458780164'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/08/centering-div-within-html.html' title='Centering a DIV within HTML'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-636666029141040795</id><published>2009-08-04T15:47:00.003-05:00</published><updated>2009-11-22T22:41:30.164-06:00</updated><title type='text'>Using Spring.Net Proxy Factory with NHibernate</title><content type='html'>The latest version of NHibernate (2.1) discouples the framework from the dependency of relying on Castle (think DynamicProxy) therefore allowing you to plug in any framework for you are proxying.&lt;br /&gt;&lt;br /&gt;Overview: NHibernate uses proxies to facilitate lazy loading, this proxy mechanism allows NHibernate to intercept the calls to your properties and classes thus delaying a call to the database that may not be needed (Lazy Loading).&lt;br /&gt;&lt;br /&gt;After you have downloaded NHibernate 2.1 and extracted the contents you will notice a new folder titled "Required_For_LazyLoading".  Inside this folder are 3 separate folders containing binaries for the following proxies: &lt;b&gt;Castle: LinFu &amp;amp; Spring&lt;/b&gt;.  Since I'm using Spring framework in the rest of my project this allows me to have one less dependency (which is a good thing).  &lt;i&gt;As I understand it LinFu is the fastest proxy of the bunch so if you aren't using Castle or Spring already you may want to consider it.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;The problem is that the NHibernate is distributed with an older verison of Spring so we want to tell the .Net framework that it's okay to use the new version.  To do so were are going to use Assembly Redirection in our App.config or Web.config.  The section below belongs inside your &amp;lt;configuration&amp;gt; section:&lt;br /&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: xml"&gt;&lt;![CDATA[&lt;!-- Assembly Redirection for NHibernate.ByteCode.Spring.dll to use current Spring Assemblies --&gt;&lt;runtime&gt;	&lt;assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"&gt;		&lt;dependentAssembly&gt;			&lt;assemblyIdentity name="Spring.Aop" publicKeyToken="65e474d141e25e07" culture="neutral"/&gt;			&lt;bindingRedirect oldVersion="0.0.0.20110" newVersion="1.3.0.20214"/&gt;		&lt;/dependentAssembly&gt;		&lt;dependentAssembly&gt;			&lt;assemblyIdentity name="Spring.Core" publicKeyToken="65e474d141e25e07" culture="neutral"/&gt;			&lt;bindingRedirect oldVersion="0.0.0.20110" newVersion="1.3.0.20214"/&gt;		&lt;/dependentAssembly&gt;	&lt;/assemblyBinding&gt;&lt;/runtime&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-636666029141040795?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/636666029141040795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=636666029141040795' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/636666029141040795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/636666029141040795'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/08/using-springnet-proxy-factory-with.html' title='Using Spring.Net Proxy Factory with NHibernate'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-3297588845338980514</id><published>2009-06-15T10:20:00.001-05:00</published><updated>2009-06-15T10:20:28.641-05:00</updated><title type='text'>NHibernate 101 Materials</title><content type='html'>I had the opportunity to speak at CINNUG&amp;#39;s &lt;a href="http://cinnug.org/specialevents.aspx"&gt;ORM Firestarter&lt;/a&gt; and present the topic on NHibernate 101.  The presentation is an overview of the NHibernate framework.  The sample app forward engineers a database based on the Hibernate mapping files.  There is also a sample web app which uses Open Session in View (OSIV) using NHibernate Session Scopes.&lt;br&gt; &lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://docs.google.com/Presentation?id=dg4wtx9r_20d22tmkgd"&gt;NHibernate 101 Presentation&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://files.me.com/scott.w.white/ioi5zx"&gt;NHibernate 101 Sample&lt;/a&gt;&lt;/div&gt; &lt;div&gt;&lt;br&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-3297588845338980514?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/3297588845338980514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=3297588845338980514' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/3297588845338980514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/3297588845338980514'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/06/nhibernate-101-materials.html' title='NHibernate 101 Materials'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-2560098774820313307</id><published>2009-06-09T13:53:00.007-05:00</published><updated>2009-06-09T14:25:22.905-05:00</updated><title type='text'>Unit Testing NHIbernate with SessionScopes</title><content type='html'>Ayende has a great article on &lt;a href="http://ayende.com/Blog/archive/2009/04/28/nhibernate-unit-testing.aspx" target="_blank"&gt;Unit Testing NHibernate&lt;/a&gt;.  However if are you using NHibernate Session Scopes you need to adapt it.  I wanted to keep my tests simple, I want to test my DAOs and inject into them an ISessionFactory since this is where it's getting it's Session from.  SessionScopes are a nice way in NHibernate not have to worry about managing your sessions, you want to control the behavior.  You may end up doing this with AOP or in your web request however that's not pertinent to my test since the design of my DAOs have the Session Factory Injected.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We are reusing DAOs within Web code to integration code and the session management behavior is different in each one.  I am also using the Spring.Net however this should work anywhere that you are injecting ISessionFactory and you are using SessionFactory.&lt;wbr&gt;GetCurrentSession() to get your session.&lt;/div&gt; &lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Basically we're using the same code as in his example except we are using Rhino Mock to actually mock the SessionFactory.  In addition we are exposing the SessionFactory so that you can inject it into your DAOs.  We are still exposing the Session for use in your test fixture.&lt;/div&gt; &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0px 0px 0px 0.8ex; padding-left: 1ex;"&gt; &lt;span style="font-family:Verdana;"&gt;&lt;pre   style="color: black; background-color: rgb(255, 255, 255);font-family:Consolas,'Courier New',Courier,monospace;font-size:small;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; InMemoryDatabaseTest : IDisposable&lt;br /&gt;  {&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; Configuration Configuration;&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; MockRepository _mocks;&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; ISessionFactory _realSessionFactory;&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; ISession _session;&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; ISessionFactory _sessionFactory;&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;protected&lt;/span&gt; ISession Session&lt;br /&gt;      {&lt;br /&gt;          get { &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; _sessionFactory.&lt;wbr&gt;GetCurrentSession(); } &lt;span style="color: rgb(0, 128, 0);"&gt;// simulates how DAOs are getting their Sessions&lt;/span&gt;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: rgb(0, 128, 0);"&gt;/// &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: rgb(0, 128, 0);"&gt;/// Gets the SessionFactory&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: rgb(0, 128, 0);"&gt;/// &lt;/span&gt;&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; ISessionFactory SessionFactory&lt;br /&gt;      {&lt;br /&gt;          get { &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; _sessionFactory; }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; InMemoryDatabaseTest(Assembly assemblyContainingMapping)&lt;br /&gt;      {&lt;br /&gt;          _mocks = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; MockRepository();&lt;br /&gt;&lt;br /&gt;          &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (Configuration == &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;)&lt;br /&gt;          {&lt;br /&gt;              Configuration = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; Configuration()&lt;br /&gt;                  .SetProperty(NHibernate.Cfg.&lt;wbr&gt;Environment.&lt;wbr&gt;ReleaseConnections, &lt;span style="color: rgb(0, 96, 128);"&gt;"on_close"&lt;/span&gt;)&lt;br /&gt;                  .SetProperty(NHibernate.Cfg.&lt;wbr&gt;Environment.Dialect, &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(SQLiteDialect).&lt;wbr&gt;AssemblyQualifiedName)&lt;br /&gt;                  .SetProperty(NHibernate.Cfg.&lt;wbr&gt;Environment.ConnectionDriver, &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(SQLite20Driver).&lt;wbr&gt;AssemblyQualifiedName)&lt;br /&gt;                  .SetProperty(NHibernate.Cfg.&lt;wbr&gt;Environment.ConnectionString, &lt;span style="color: rgb(0, 96, 128);"&gt;"data source=:memory:"&lt;/span&gt;)&lt;br /&gt;                  .SetProperty(NHibernate.Cfg.&lt;wbr&gt;Environment.&lt;wbr&gt;ProxyFactoryFactoryClass, &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(&lt;wbr&gt;DefaultProxyFactoryFactory).&lt;wbr&gt;AssemblyQualifiedName)&lt;br /&gt;                  .AddAssembly(&lt;wbr&gt;assemblyContainingMapping);&lt;br /&gt;              _realSessionFactory = Configuration.&lt;wbr&gt;BuildSessionFactory();&lt;br /&gt;          }&lt;br /&gt;&lt;br /&gt;          &lt;span style="color: rgb(0, 128, 0);"&gt;// Here we are mocking the Session Factory because we are using Session Scopes.&lt;/span&gt;&lt;br /&gt;          &lt;span style="color: rgb(0, 128, 0);"&gt;// However we want to return the same session every time&lt;/span&gt;&lt;br /&gt;          _sessionFactory = _mocks.CreateMock&lt;&lt;wbr&gt;ISessionFactory&gt;();&lt;br /&gt;          _session = _realSessionFactory.&lt;wbr&gt;OpenSession();&lt;br /&gt;          Expect.Call(_sessionFactory.&lt;wbr&gt;GetCurrentSession()).&lt;wbr&gt;IgnoreArguments().Return(_&lt;wbr&gt;session).Repeat.Any();&lt;br /&gt;          _mocks.ReplayAll();&lt;br /&gt;&lt;br /&gt;          &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; SchemaExport(Configuration).&lt;wbr&gt;Execute(&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;false&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;, _session.Connection, Console.Out);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Dispose()&lt;br /&gt;      {&lt;br /&gt;          Session.Dispose();&lt;br /&gt;      }&lt;br /&gt;  }&lt;/pre&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;The Mock is the glue that makes this work so that you can adhere to the restrictions of your DAO implementation.  Then you can execute the test much like Ayende does in his own, regardless of how your perform transaction management in your actual application.&lt;/div&gt; &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0px 0px 0px 0.8ex; padding-left: 1ex;"&gt; &lt;span style="font-family:Verdana;"&gt;&lt;pre   style="color: black; background-color: rgb(255, 255, 255);font-family:Consolas,'Courier New',Courier,monospace;font-size:small;"&gt;    [TestFixture]&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; FelineDao_Tests : InMemoryDatabaseTest&lt;br /&gt;  {&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; FelineDao_Tests() : &lt;span style="color: rgb(0, 0, 255);"&gt;base&lt;/span&gt;(&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(Feline).Assembly) { }&lt;br /&gt;&lt;br /&gt;      [TestFixtureSetUp]&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Initialize()&lt;br /&gt;      {&lt;br /&gt;          &lt;span style="color: rgb(0, 128, 0);"&gt;// Insert Test data&lt;/span&gt;&lt;br /&gt;          &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; (ITransaction tx = Session.BeginTransaction())&lt;br /&gt;          {&lt;br /&gt;              Session.Save(GetSnowLeopard())&lt;wbr&gt;;&lt;br /&gt;              Session.Save(GetDomesticCat())&lt;wbr&gt;;&lt;br /&gt;              tx.Commit();&lt;br /&gt;          }&lt;br /&gt;&lt;br /&gt;          Session.Clear();&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      [Test]&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; FindAll_Retrieval()&lt;br /&gt;      {&lt;br /&gt;          &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; (ITransaction tx = Session.BeginTransaction())&lt;br /&gt;          {&lt;br /&gt;              Dao&lt;feline&gt; dao = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; Dao&lt;feline&gt;();&lt;br /&gt;              dao.SessionFactory = SessionFactory;&lt;br /&gt;              IList&lt;feline&gt; list = dao.FindAll();&lt;br /&gt;              Assert.AreEqual(2, list.Count);&lt;br /&gt;              tx.Commit();&lt;br /&gt;          }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      [Test]&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; FindById_Retrieval_InValid_Id(&lt;wbr&gt;)&lt;br /&gt;      {&lt;br /&gt;          &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; (ITransaction tx = Session.BeginTransaction())&lt;br /&gt;          {&lt;br /&gt;              Dao&lt;feline&gt; dao = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; Dao&lt;feline&gt;();&lt;br /&gt;              dao.SessionFactory = SessionFactory;&lt;br /&gt;              Feline o = dao.FindById(3);&lt;br /&gt;              Assert.IsNull(o);&lt;br /&gt;              tx.Commit();&lt;br /&gt;          }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      [Test]&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; FindById_Retrieval_Valid_Id()&lt;br /&gt;      {&lt;br /&gt;          &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; (ITransaction tx = Session.BeginTransaction())&lt;br /&gt;          {&lt;br /&gt;              Dao&lt;feline&gt; dao = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; Dao&lt;feline&gt;();&lt;br /&gt;              dao.SessionFactory = SessionFactory;&lt;br /&gt;              Feline o = dao.FindById(1);&lt;br /&gt;              Assert.IsNotNull(o);&lt;br /&gt;              tx.Commit();&lt;br /&gt;          }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; Feline GetSnowLeopard()&lt;br /&gt;      {&lt;br /&gt;          Feline feline = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; Feline();&lt;br /&gt;          feline.Name = &lt;span style="color: rgb(0, 96, 128);"&gt;"Snow Leopard"&lt;/span&gt;;&lt;br /&gt;          feline.Length = 74;&lt;br /&gt;          &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; feline;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; Feline GetDomesticCat()&lt;br /&gt;      {&lt;br /&gt;          Feline feline = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; Feline();&lt;br /&gt;          feline.Name = &lt;span style="color: rgb(0, 96, 128);"&gt;"Domestic Cat"&lt;/span&gt;;&lt;br /&gt;          feline.Length = 24;&lt;br /&gt;          &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; feline;&lt;br /&gt;      }&lt;br /&gt;  }&lt;/feline&gt;&lt;/feline&gt;&lt;/feline&gt;&lt;/feline&gt;&lt;/feline&gt;&lt;/feline&gt;&lt;/feline&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Props to &lt;a href="http://ayende.com/Blog/Default.aspx" target="_blank"&gt;Ayende &lt;/a&gt;for the original implementation of this and for his work on Rhino Mocks.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-2560098774820313307?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/2560098774820313307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=2560098774820313307' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/2560098774820313307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/2560098774820313307'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/06/unit-testing-nhibernate-with.html' title='Unit Testing NHIbernate with SessionScopes'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-5975233639964519400</id><published>2009-04-30T11:00:00.001-05:00</published><updated>2009-04-30T11:00:38.957-05:00</updated><title type='text'>Deriving a Date Range for a Day</title><content type='html'>Many times the database will contain data with different times and we need to get all data for one day.  In .Net this is done by:&lt;div&gt; &lt;/div&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; Console.WriteLine(&amp;quot;Start Date: {0}&amp;quot;, DateTime.Now.Date); &lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; Console.WriteLine(&amp;quot;End Date: {0}&amp;quot;, DateTime.Now.AddDays(1).Date.AddMilliseconds(-1)); &lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;This would output: &lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; Start Date: 4/30/2009 12:00:00 AM&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; End Date: 4/30/2009 11:59:59 PM&lt;br&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt; Let&amp;#39;s say in NHibernate we want a criteria expression to retrieve all objects with a DateTime that falls within an entire date (regardless of time)&lt;/div&gt; &lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; return Session.CreateCriteria(typeof(Person))&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;     .Add(Expression.Between(&amp;quot;DateOfBirth&amp;quot;, dateOfBirth.Date, dateOfBirth.AddDays(1).Date.AddMilliseconds(-1)))&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;     .List&amp;lt; Person &amp;gt;();&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;This would return all People that were born on the same day (regardless of the time of birth) since the Time portion of the Date are usually stored in the database.&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-5975233639964519400?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/5975233639964519400/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=5975233639964519400' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/5975233639964519400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/5975233639964519400'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/04/deriving-date-range-for-day.html' title='Deriving a Date Range for a Day'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-8639959696639908575</id><published>2009-04-28T23:26:00.001-05:00</published><updated>2009-04-28T23:26:54.331-05:00</updated><title type='text'>Don't Blame NHibernate When It's ADO.Net</title><content type='html'>I can&amp;#39;t count the number of times I have troubleshot an &amp;#39;NHibernate&amp;#39; problem when it was either a severe design flaw or a logic bug.  From trying to write to views without indexes, working with tables without primary keys or simply causing ADO.Net to execute a query that gives an OutOfMemory exception before NHibernate gets the data.  NHibernate is a very flexible ORM, partially because there are a lot of poorly written databases out there and an ORM gives you a lot once you have taken the upfront cost in time to design.&lt;div&gt; &lt;br&gt;&lt;/div&gt;&lt;div&gt;When troubleshooting query issues, one of the first things I will do is enable &amp;#39;show_sql&amp;#39; or look at the logs, then I will execute this same statement through a query tool.  If query analyzer or Toad cannot execute a query then it&amp;#39;s not an NHibernate problem.  You can even go the next step and execute the query in ADO.Net itself to prove your point but that is usually not necessary unless you are dealing with a more persistent individual.&lt;div&gt; &lt;br&gt;&lt;/div&gt;&lt;div&gt;Some common exceptions with large results or complex queries will be ADO throwing query timeout exceptions or maybe an out of memory exception.  The first just means that the query took a long time to run, the fix for this could be optimizing your query or increasing the query timeout.  The later may be fixed by narrowing your results or the columns you are selecting if the table has a lot of columns.&lt;/div&gt; &lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;But neither of them are NHibernate&amp;#39;s fault.  More analysis and thought should be done before we just blame the first non-Microsoft product.  NHibernate has a lot of features for those situations that when even good design fails, this is why it&amp;#39;s the premier ORM for .Net.&lt;/div&gt; &lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-8639959696639908575?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/8639959696639908575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=8639959696639908575' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/8639959696639908575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/8639959696639908575'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/04/dont-blame-nhibernate-when-its-adonet.html' title='Don&apos;t Blame NHibernate When It&apos;s ADO.Net'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-3521641647267172993</id><published>2009-04-16T22:59:00.001-05:00</published><updated>2009-04-16T22:59:49.500-05:00</updated><title type='text'>NHibernate Performance Tuning</title><content type='html'>OR/M as a central part of your application architecture will require tuning over time.  Below are some tweaks which can have incremental to significant performance effects on your code.&lt;div&gt;&lt;ol&gt;&lt;li&gt;Enable 2nd level cache and have a strategy for using it for some of your classes. &lt;a href="http://nhforge.org/doc/nh/en/index.html#performance-cache"&gt;reference&lt;/a&gt; &lt;/li&gt; &lt;li&gt;Enable batch processing for persistence of objects.  This will allow NHibernate to send batches of your transactions (Inserts, Updates and Deletes) to the server in a batch. &lt;a href="http://nhforge.org/doc/nh/en/index.html#performance-batch-updates"&gt;reference&lt;/a&gt; &lt;/li&gt; &lt;li&gt;Have a good strategy for flushing and transaction management.  Remember that if you commit a transaction that you do not need to flush the object.  &lt;a href="http://nhforge.org/doc/nh/en/index.html#manipulatingdata-endingsession-flushing"&gt;reference&lt;/a&gt; &lt;/li&gt; &lt;li&gt;Make read-only classes immutable. &lt;a href="http://nhforge.org/doc/nh/en/index.html#mapping-declaration-class"&gt;reference&lt;/a&gt; &lt;/li&gt;&lt;li&gt;Understand lazy loading and use effectively, for instance when you may but not always need an associated object(s) &lt;a href="http://nhforge.org/doc/nh/en/index.html#performance-fetching-lazy"&gt;reference&lt;/a&gt; &lt;/li&gt; &lt;li&gt;To bypass lazy loading understand eager fetching and use when you know you need associated object(s) and want to bypass lazy loading. &lt;a href="http://nhforge.org/doc/nh/en/index.html#querycriteria-dynamicfetching"&gt;reference&lt;/a&gt; &lt;/li&gt; &lt;li&gt;Remove any columns and properties that you will never or should never need or use.&lt;/li&gt;&lt;li&gt;Using value type objects for your properties and components as opposed to reference types, when you have a choice, this will lower memory footprint.&lt;/li&gt; &lt;li&gt;Avoid composite keys (exception legacy databases).  Composite keys are problematic for database design as well as OR/M therefore avoid them.  &lt;a href="http://nhforge.org/doc/nh/en/index.html#mapping-declaration-compositeid"&gt;reference&lt;/a&gt; &lt;/li&gt; &lt;li&gt;Consider your logging strategy for production (less verbose) and usually disable show_sql in production.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Orin&amp;#39;s &lt;a href="http://nhprof.com/"&gt;NHib Profiler&lt;/a&gt; can also help you find improvements you can make to your configuration of NHibernate.&lt;/div&gt; &lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-3521641647267172993?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/3521641647267172993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=3521641647267172993' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/3521641647267172993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/3521641647267172993'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/04/nhibernate-performance-tuning.html' title='NHibernate Performance Tuning'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-7211940479502651303</id><published>2009-04-01T17:08:00.001-05:00</published><updated>2009-04-01T17:08:24.228-05:00</updated><title type='text'>StyleCop Extensions Project</title><content type='html'>I&amp;#39;ve started a small project on &lt;a href="http://code.google.com/"&gt;Google Code&lt;/a&gt; for creating common &lt;a href="http://code.msdn.microsoft.com/sourceanalysis"&gt;StyleCop&lt;/a&gt; extensions.  Currently it enforces one rule that requires underscores to prefix instance variables.  If you have an idea for a new rule then create an Issue for it as an Enhancement. &lt;a href="http://code.google.com/p/stylecopext/"&gt;StyleCop Extension Project Home&lt;/a&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-7211940479502651303?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/7211940479502651303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=7211940479502651303' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7211940479502651303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7211940479502651303'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/04/stylecop-extensions-project.html' title='StyleCop Extensions Project'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-3066379941869768893</id><published>2009-02-26T10:03:00.001-06:00</published><updated>2009-02-26T10:03:16.680-06:00</updated><title type='text'>Alt.Net Open Spaces Houston Conference</title><content type='html'>&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;April 3rd - April 5th, 2009&lt;/span&gt;&lt;br&gt;&lt;/div&gt;Grassroots in our area have planned the first ever Open Spaces conference in Houston.  This is a very affordable ($25) and flexible conference for people to be able to attend since it starts on Friday and runs through the weekend.&lt;div&gt; &lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;What is Open Spaces?&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; Open space is guided by a few simple but powerful principles:&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; Whoever shows up is the right group. Whatever happens is the only thing that could have. Whenever it starts is the right time. When it&amp;#39;s over, it&amp;#39;s over.&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; An Open Space conference&amp;#39;s agenda is decided upon by the conference participants during the opening of the event.&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; You can identify an issue relating to the theme of the conference for which you have a genuine passion and for which you will take real responsibility.&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; Think of powerful ideas that really grab you to the point that you will take personal responsibility to make sure that something gets done at the conference.&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; You may lead sessions, you may participate as an attendee, you may take responsibility for capturing proceedings, or you may just hang out in the halls and talk with interesting people.&lt;br&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt; &lt;div&gt;Registration is now Open&lt;/div&gt;&lt;div&gt;&lt;a href="http://houston.altnetconf.com/home"&gt;http://houston.altnetconf.com/home&lt;/a&gt;&lt;br&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-3066379941869768893?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/3066379941869768893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=3066379941869768893' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/3066379941869768893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/3066379941869768893'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/02/altnet-open-spaces-houston-conference.html' title='Alt.Net Open Spaces Houston Conference'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-4555945098416800108</id><published>2009-02-10T16:35:00.001-06:00</published><updated>2009-02-10T16:35:44.146-06:00</updated><title type='text'>Concatenating Date and Time in T-SQL</title><content type='html'>Sometimes you just want to concatenate the date section from a DateTime and the time section from another DateTime. &amp;nbsp;These could even be the new SQL Server Date or Time data types. &amp;nbsp;The easiest way I&amp;#39;ve found to do this is by combining DATEPART with DATEADD. &amp;nbsp;You get rid of the parts of each DateTime that you don&amp;#39;t want and then add based on the lowest common denominator this being millisecond.&lt;div&gt; &lt;br&gt;&lt;/div&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&amp;#39;ProcessedDate&amp;#39; = DATEADD(ms, DATEDIFF(ms, 0, [ProcessingTime]), DATEADD(dd, 0, DATEDIFF(dd, 0, [ProcessingDate])))&lt;/span&gt;&lt;/blockquote&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-4555945098416800108?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/4555945098416800108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=4555945098416800108' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/4555945098416800108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/4555945098416800108'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/02/concatenating-date-and-time-in-t-sql.html' title='Concatenating Date and Time in T-SQL'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-7537864624209356744</id><published>2009-02-09T10:21:00.001-06:00</published><updated>2009-02-09T10:21:48.391-06:00</updated><title type='text'>Generating Seed Data Through Select Statements</title><content type='html'>Often times you will need to generate seed data for a table such as a cross reference table when the data for this already exists in the database already. &amp;nbsp;Sometimes this is done when you decide to refactor your table design to include a cross reference table (many to many) where a one to many relationship existed previously. &amp;nbsp;If you have the seed data in your table already you can generate a host of SQL statements (usually INSERTS) for your database.&lt;div&gt; &lt;br&gt;&lt;/div&gt;&lt;div&gt;By issuing a SQL Statement like below, you need to understand the SQL Statement that you desire. &amp;nbsp;In this instance if you have a cross reference table that you need to generate between Customers and Orders you would have a desired INSERTS like below:&lt;/div&gt; &lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; INSERT INTO customer_orders_xref VALUES (1, 1)&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; INSERT INTO customer_orders_xref VALUES (1, 2)&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; INSERT INTO customer_orders_xref VALUES (3, 1)&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;In instances where you can have dozens or hundreds of desired SQL statements this can be tedious and error prone. &amp;nbsp;Instead if the data exists in some form in the database you can have it outputted with a simple SQL statement like the one below:&lt;/div&gt; &lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; SELECT &amp;#39;INSERT INTO customer_orders_xref VALUES (&amp;#39; + CAST(c.order_id AS VARCHAR(10)) + CAST(c.customer_id AS VARCHAR(10)) + &amp;#39;)&amp;#39;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; FROM orders o&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; INNER JOIN customer c ON o.customer_id = c.customer_id&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; WHERE &lt;a href="http://c.name"&gt;c.name&lt;/a&gt; LIKE &amp;#39;%Williams%&amp;#39;&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;If the first parameter was a fixed value you would just hard code it in your SQL.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; SELECT &amp;#39;INSERT INTO customer_orders_xref VALUES (2, &amp;#39; + CAST(c.customer_id AS VARCHAR(10)) + &amp;#39;)&amp;#39;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; FROM orders o&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; INNER JOIN customer c ON o.customer_id = c.customer_id&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; WHERE &lt;a href="http://c.name"&gt;c.name&lt;/a&gt; LIKE &amp;#39;%Williams%&amp;#39;&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;You could use techniques like this to generate all sorts of SQL Statements. &amp;nbsp;Let&amp;#39;s say we added an Account Alias column (acct_alias) to the Account table and now we need to change them all to some sort of&amp;nbsp;intelligible&amp;nbsp;name.&lt;/div&gt; &lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; SELECT &amp;#39;UPDATE account SET acct_alias = &amp;#39;&amp;#39;Account# &amp;#39; + &lt;a href="http://c.name"&gt;c.name&lt;/a&gt; + &amp;#39;&amp;#39;&amp;#39;) WHERE account_id = &amp;#39; + c.account_id FROM customer&amp;nbsp;&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;For more complicated SQL generation you can use a code generation tool such as &lt;a href="http://www.mygenerationsoftware.com/"&gt;MyGeneration&lt;/a&gt;&amp;nbsp;(free Open Source).&lt;/div&gt; &lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-7537864624209356744?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/7537864624209356744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=7537864624209356744' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7537864624209356744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7537864624209356744'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/02/generating-seed-data-through-select.html' title='Generating Seed Data Through Select Statements'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-8923613871160624561</id><published>2009-01-16T10:39:00.001-06:00</published><updated>2009-01-16T10:39:52.855-06:00</updated><title type='text'>Getting started with NAnt Scripts (Automating Builds)</title><content type='html'>It doesn&amp;#39;t take much work to setup a project to use NAnt scripts however the inevitable question is &amp;quot;Where do I start&amp;quot;. &amp;nbsp;I would recommend starting by downloading the latest release 0.86 or the daily build from &lt;a href="http://nant.sourceforge.net/"&gt;NAnt&amp;#39;s website&lt;/a&gt;. &amp;nbsp;Next it&amp;#39;s good to have a basic script for your assemblies and one for your ASP.Net website that you can copy and paste.&lt;div&gt; &lt;br&gt;&lt;/div&gt;&lt;div&gt;Basic .Net Assembly Build Script:&lt;/div&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;lt;project xmlns=&amp;quot;&lt;a href="http://nant.sf.net/release/0.86-beta1/nant.xsd"&gt;http://nant.sf.net/release/0.86-beta1/nant.xsd&lt;/a&gt;&amp;quot; name=&amp;quot;Company.Portal.Domain&amp;quot; default=&amp;quot;build&amp;quot;&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;debug&amp;quot; value=&amp;quot;false&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;optimize&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;bin_name&amp;quot; value=&amp;quot;${project::get-name()}.dll&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;nant.settings.currentframework&amp;quot; value=&amp;quot;net-2.0&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;output_bin&amp;quot; value=&amp;quot;build\${bin_name} &amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;build_path&amp;quot; value=&amp;quot;..\build\&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;build_bin&amp;quot; value=&amp;quot;${build_path}${bin_name}&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;target name=&amp;quot;clean&amp;quot; description=&amp;quot;Cleans the build folder which forces a rebuild.&amp;quot;&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;delete dir=&amp;quot;build&amp;quot; &amp;nbsp;if=&amp;quot;${directory::exists(&amp;#39;build&amp;#39;)}&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;/target&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;target name=&amp;quot;debug&amp;quot; description=&amp;quot;Specifies assembly to be compiled with debug symbols.&amp;quot;&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;property name=&amp;quot;debug&amp;quot; value=&amp;quot;true&amp;quot; overwrite=&amp;quot;true&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;call target=&amp;quot;build&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;copy file=&amp;quot;build\${project::get-name()}.pdb&amp;quot; todir=&amp;quot;${build_path}&amp;quot; overwrite=&amp;quot;true&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;/target&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;target name=&amp;quot;build&amp;quot; description=&amp;quot;Compiles assembly.&amp;quot;&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;mkdir dir=&amp;quot;build&amp;quot; if=&amp;quot;${not directory::exists(&amp;#39;build&amp;#39;)}&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;csc target=&amp;quot;library&amp;quot; output=&amp;quot;${output_bin}&amp;quot; debug=&amp;quot;${debug}&amp;quot; optimize=&amp;quot;${optimize}&amp;quot; &amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;sources&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;**\*.cs&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/sources&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;references&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;..\lib\*.dll&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;${build_path}*.dll&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;exclude name=&amp;quot;${build_bin}&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/references&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;resources dynamicprefix=&amp;quot;true&amp;quot; prefix=&amp;quot;${project::get-name()}&amp;quot;&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;**\*.hbm.xml&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/resources&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/csc&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;mkdir dir=&amp;quot;${build_path}&amp;quot; if=&amp;quot;${not directory::exists(build_path)}&amp;quot; &amp;nbsp;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;copy file=&amp;quot;${output_bin}&amp;quot; todir=&amp;quot;${build_path}&amp;quot; overwrite=&amp;quot;true&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;copy file=&amp;quot;${output_bin}&amp;quot; todir=&amp;quot;..\bin&amp;quot; overwrite=&amp;quot;true&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;/target&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;lt;/project&amp;gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;Basic ASP.Net NAnt Script&lt;/div&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;lt;project xmlns=&amp;quot;&lt;a href="http://nant.sf.net/release/0.86-beta1/nant.xsd"&gt;http://nant.sf.net/release/0.86-beta1/nant.xsd&lt;/a&gt;&amp;quot; name=&amp;quot;Company.Portal.Web&amp;quot; default=&amp;quot;build&amp;quot;&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;debug&amp;quot; value=&amp;quot;false&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;optimize&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;bin_name&amp;quot; value=&amp;quot;${project::get-name()}.dll&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;output_bin&amp;quot; value=&amp;quot;build\${bin_name} &amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;build_path&amp;quot; value=&amp;quot;..\build\&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;build_bin&amp;quot; value=&amp;quot;${build_path}${bin_name}&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;nant.settings.currentframework&amp;quot; value=&amp;quot;net-2.0&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;web_path&amp;quot; value=&amp;quot;..\web\&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;property name=&amp;quot;web_bin_path&amp;quot; value=&amp;quot;${web_path}bin&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;target name=&amp;quot;clean&amp;quot; description=&amp;quot;Cleans the build folder which forces a rebuild.&amp;quot;&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;delete dir=&amp;quot;build&amp;quot; &amp;nbsp;if=&amp;quot;${directory::exists(&amp;#39;build&amp;#39;)}&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;delete dir=&amp;quot;${web_path}&amp;quot; &amp;nbsp;if=&amp;quot;${directory::exists(web_path)}&amp;quot; failonerror=&amp;quot;false&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;/target&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;target name=&amp;quot;debug&amp;quot; description=&amp;quot;Specifies assembly to be compiled with debug symbols.&amp;quot;&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;property name=&amp;quot;debug&amp;quot; value=&amp;quot;true&amp;quot; overwrite=&amp;quot;true&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;call target=&amp;quot;build&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;copy file=&amp;quot;build\${project::get-name()}.pdb&amp;quot; todir=&amp;quot;${build_path}&amp;quot; overwrite=&amp;quot;true&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;/target&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;target name=&amp;quot;build&amp;quot; description=&amp;quot;Compiles assembly.&amp;quot;&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;mkdir dir=&amp;quot;build&amp;quot; if=&amp;quot;${not directory::exists(&amp;#39;build&amp;#39;)}&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;csc target=&amp;quot;library&amp;quot; output=&amp;quot;${output_bin}&amp;quot; debug=&amp;quot;${debug}&amp;quot; optimize=&amp;quot;${optimize}&amp;quot; &amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;sources&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;**\*.cs&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;**\*.resx&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/sources&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;references&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;..\lib\*.dll&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;${build_path}*.dll&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;exclude name=&amp;quot;${build_bin}&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/references&amp;gt;&amp;nbsp;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/csc&amp;gt;&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;copy file=&amp;quot;${output_bin}&amp;quot; todir=&amp;quot;${build_path}&amp;quot; overwrite=&amp;quot;true&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;copy file=&amp;quot;${output_bin}&amp;quot; todir=&amp;quot;..\bin&amp;quot; overwrite=&amp;quot;true&amp;quot; /&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;!-- Setup Web Site --&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;mkdir dir=&amp;quot;${build_path}&amp;quot; if=&amp;quot;${not directory::exists(build_path)}&amp;quot; &amp;nbsp;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;mkdir dir=&amp;quot;${web_path}&amp;quot; if=&amp;quot;${not directory::exists(web_path)}&amp;quot; &amp;nbsp;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;mkdir dir=&amp;quot;${web_bin_path}&amp;quot; if=&amp;quot;${not directory::exists(web_bin_path)}&amp;quot; &amp;nbsp;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;copy todir=&amp;quot;${web_bin_path}&amp;quot; overwrite=&amp;quot;true&amp;quot;&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;fileset basedir=&amp;quot;${build_path}&amp;quot;&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;*.dll&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/fileset&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/copy&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;copy todir=&amp;quot;${web_bin_path}&amp;quot; overwrite=&amp;quot;true&amp;quot;&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;fileset basedir=&amp;quot;..\lib\&amp;quot;&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;*.dll&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/fileset&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/copy&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;copy todir=&amp;quot;${web_path}&amp;quot; overwrite=&amp;quot;true&amp;quot;&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;fileset&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;**.ascx&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;**.aspx&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;**.master&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;**.config&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;Config\**&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;IMG\**&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;include name=&amp;quot;App_Themes\**&amp;quot;/&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/fileset&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/copy&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;nbsp;&amp;nbsp;&amp;lt;/target&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;lt;/project&amp;gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Setup:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Install NAnt (your bin dir will likely be&amp;nbsp;C:\Program Files\nant-0.86\bin)&lt;/li&gt;&lt;li&gt;&amp;nbsp;Add NAnt bin directory to your path environmental variable so you can use nant from command-line interface anywhere&lt;br&gt; &lt;/li&gt;&lt;ol&gt;&lt;li&gt;Right-click &amp;quot;My Computer&amp;quot; then click &amp;quot;Properties&amp;quot;&lt;/li&gt;&lt;li&gt;Click the &amp;quot;Advanced&amp;quot; tab then the &amp;quot;Environmental Variables&amp;quot; button&lt;/li&gt;&lt;li&gt;Under the &amp;quot;System Variables&amp;quot; list find the item named &amp;quot;Path&amp;quot; then click &amp;quot;Edit&amp;quot;&lt;/li&gt; &lt;li&gt;Add to the end of the &amp;quot;Variable value &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&amp;quot;;C:\Program Files\nant-0.86\bin&amp;quot;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Click OK, OK, OK&lt;/li&gt;&lt;li&gt;Now test it by clicking &amp;quot;Start&amp;quot; -&amp;gt; &amp;quot;Run&amp;quot;&lt;/li&gt; &lt;li&gt;Type &amp;quot;cmd&amp;quot; then hit enter&lt;/li&gt;&lt;li&gt;In the command prompt type &amp;quot;nant&amp;quot; then hit enter. &amp;nbsp;If it outputs a few lines and says BUILD FAILED then your path variables are correct&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;In your solution directory create a folder called &amp;quot;lib&amp;quot; and put your libraries (anything 3rd party or not included with the target CLR version)&lt;/li&gt; &lt;li&gt;Create your NAnt script in the target project directory naming your NAnt script: &amp;quot;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;default.build&lt;/span&gt;&amp;quot;&lt;/li&gt;&lt;li&gt;Navigate to this location through command prompt and run one of the following commands&lt;/li&gt; &lt;ol&gt;&lt;li&gt;nant - will do a build&lt;/li&gt;&lt;li&gt;nant clean - will clean the build&lt;/li&gt;&lt;li&gt;nant clean build - will clean the build and rebuild (recommended)&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Optionally you can create a make file at the solution directory which simply executes nant for each of the projects in the solution. &amp;nbsp;I call mine &amp;quot;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;make.cmd&lt;/span&gt;&amp;quot; and put it in your solution directory (one directory above your project directories assuming all project directories are siblings)&lt;/li&gt; &lt;/ol&gt;&lt;div&gt;Sample Make File (make.cmd):&lt;/div&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; nant -buildfile:Company.Domain.Common\default.build %*&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; nant -buildfile:Company.Portal.Web\default.build %*&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Usage: &amp;quot;make clean build&amp;quot;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Now you have NAnt scripts so that you can setup continuous integration for your project using something like &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET"&gt;CruiseControl.Net&lt;/a&gt;&amp;nbsp;.&lt;/div&gt; &lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-8923613871160624561?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/8923613871160624561/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=8923613871160624561' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/8923613871160624561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/8923613871160624561'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2009/01/getting-started-with-nant-scripts.html' title='Getting started with NAnt Scripts (Automating Builds)'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-2672563599847324187</id><published>2008-11-25T22:28:00.004-06:00</published><updated>2008-11-26T11:50:35.246-06:00</updated><title type='text'>Creating Custom StyleCop Rules in C#</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_qZcJ0BAqrdY/SSzWeVq0yMI/AAAAAAAAABs/TqkK0GVpqc0/s1600-h/StyleCopConfig.PNG"&gt;&lt;/a&gt;Microsoft has released a new free static code analysis tool called &lt;a href="http://code.msdn.microsoft.com/sourceanalysis/Release/ProjectReleases.aspx?ReleaseId=1425"&gt;StyleCop&lt;/a&gt;.  Named after the similar FxCop, this product is aimed to be more focused for cosmetic code consistency which can increase readability and maintainability.  StyleCop has built-in rules, which you can turn off, many of which are:&lt;div&gt; &lt;ul&gt;&lt;li&gt;Ordering of members in a class from most visible to least visible&lt;/li&gt;&lt;li&gt;Order of Usings in alphabetical order, with System namespaces on top&lt;/li&gt;&lt;li&gt;Proper camel casing and pascal casing&lt;/li&gt;&lt;li&gt;Proper whitespace&lt;/li&gt; &lt;/ul&gt;&lt;div&gt;I like about 3/4 of these rules so I think it's definitely worth considering using, even consider integrating into your automated build process using NAnt, CruiseControl or TFS.  That being said many will likely want to extend these rules to create your own.  Doing so is fairly simple but not documented very well at this time.  I created the following rule to make sure that all instance variables (private &amp;amp; protected class level variables) are prefixed with an underscore.  I realize not everybody follows this convention, but I like it because it's more concise than prefixing your instance variables with 'm_' or 'this' which is often needed to prevent name collisions.&lt;/div&gt; &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First I created a C# Class assembly project and referenced "Microsoft.StyleCop" and "Microsoft.StyleCop.CSharp".  Next I added the following class, which implements my custom rule:&lt;/div&gt; &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; using Microsoft.StyleCop;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; using Microsoft.StyleCop.CSharp;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; namespace DotNetExtensions.StyleCop.Rules&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; {&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;     /// &amp;lt;summary&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;     /// This StyleCop Rule makes sure that instance variables are prefixed with an underscore.&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;     /// &amp;lt;/summary&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;     [SourceAnalyzer(typeof(CsParser))]&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;     public class InstanceVariablesUnderscorePrefix : SourceAnalyzer&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;     {&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;         &lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;         public override void AnalyzeDocument(CodeDocument document)&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;         {&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;             CsDocument csdocument  = (CsDocument) document;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;             if (csdocument.RootElement != null &amp;amp;&amp;amp; !csdocument.RootElement.Generated)&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;                 csdocument.WalkDocument(new CodeWalkerElementVisitor&amp;lt;object&amp;gt;(this.VisitElement), null, null);&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;         }&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;         private bool VisitElement(CsElement element, CsElement parentElement, object context)&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;         {&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;             // Flag a violation if the instance variables are not prefixed with an underscore.&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;            if (!element.Generated &amp;amp;&amp;amp; element.ElementType == ElementType.Field &amp;amp;&amp;amp; element.ActualAccess != AccessModifierType.Public &amp;amp;&amp;amp; &lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;                element.ActualAccess != AccessModifierType.Internal &amp;amp;&amp;amp; element.Declaration.Name.ToCharArray()[0] != '_')&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;            {&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;                 AddViolation(element, "InstanceVariablesUnderscorePrefix");&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;             }&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;             return true;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;         }&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;     }&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; }&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The VisitElement function handles the main logic for this rule.  First it makes sure that the member isn't Generated code, which you have no control over so no sense in applying rules to.  Secondly it's making sure that the member's visibility isn't Public or Internal.  Finally we make sure that the instance variable starts with an underscore prefix..&lt;/div&gt; &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next we need to provide metadata so that StyleCop can categorize and describe our rule.  Add an XML file to your project, then change it's Build Action to 'Embedded Resource'&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;lt;?xml version="1.0" encoding="utf-8" ?&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;lt;SourceAnalyzer Name="Extensions"&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;   &amp;lt;Description&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;     These custom rules provide extensions to the ones provided with StyleCop.&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;   &amp;lt;/Description&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;   &amp;lt;Rules&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;     &amp;lt;Rule Name="InstanceVariablesUnderscorePrefix" CheckId="EX1001"&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;       &amp;lt;Context&amp;gt;Instance variables should be prefixed by underscore.&amp;lt;/Context&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;       &amp;lt;Description&amp;gt;Instance variables are easier to distinguish when prefixed with an underscore.&amp;lt;/Description&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;     &amp;lt;/Rule&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt;   &amp;lt;/Rules&amp;gt;&lt;/blockquote&gt;&lt;blockquote class="gmail_quote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex; "&gt; &amp;lt;/SourceAnalyzer&amp;gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;At the root level you are naming the main category for the rules in this file.  Next you describe your suite of rules.  Then in the Rules section you can add all the rules (note: you can use RuleGroup element to further categorize your rules).  Finally you name your rule and give it a unique CheckId.  The CheckId is what you can search for your rule by in the StyleCop Project Settings.  &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Important: for StyleCop to correlate your class to your metadata your class and xml file need to be named exactly the same.&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Finally build your project and drop your new assembly's dll into the StyleCop directory (C:\Program Files\Microsoft StyleCop 4.3).  Now double-click your Settings.StyleCop to see your rule in the list.  It should look something like the following:&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238); text-decoration: underline;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238); "&gt;&lt;img src="http://4.bp.blogspot.com/_qZcJ0BAqrdY/SSzWeVq0yMI/AAAAAAAAABs/TqkK0GVpqc0/s400/StyleCopConfig.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5272825080445192386" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 400px; height: 259px; " /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now you can open your solutions/projects in Visual Studio and click Tools -&amp;gt; Run StyleCop and you should see warnings for your new rule.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;StyleCop is a nice little accent to any C# project.  I'd like to see Microsoft make the following changes:&lt;/div&gt; &lt;div&gt;&lt;ul&gt;&lt;li&gt;StyleCop should be OSS (open source software) - why not Microsoft, there really can't be any proprietary business technology in an application that is basically is performing string  parsing&lt;/li&gt;&lt;li&gt;StyleCop's documentation needs to be improved - Microsoft provides to help documents for StyleCop, a user manual and an SDK manual.  Both of them lack details and some of the examples simply do not even compile.  For instance the CodeWalkerElementVisitor delegate in a boolean, in their samples they do not even return a boolean value which will not allow their samples to compile.  They do not even document the purpose of this boolean.  Through trial and error I think that if you return a false that it will stop walking (parsing) the document for this rule.&lt;/li&gt; &lt;li&gt;Custom rules should be able to be categorized within the existing main ones: Naming Rules, Ordering Rules, etc.&lt;/li&gt;&lt;li&gt;Easier to create custom rules by using regex within an XML file.  This would eliminate having to create custom assemblies and classes.&lt;/li&gt; &lt;li&gt;Command-line interface should be available for testing or scripting purposes.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-2672563599847324187?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/2672563599847324187/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=2672563599847324187' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/2672563599847324187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/2672563599847324187'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2008/11/creating-custom-stylecop-rules-in-c.html' title='Creating Custom StyleCop Rules in C#'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_qZcJ0BAqrdY/SSzWeVq0yMI/AAAAAAAAABs/TqkK0GVpqc0/s72-c/StyleCopConfig.PNG' height='72' width='72'/><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-7196540994837967088</id><published>2008-11-10T15:40:00.001-06:00</published><updated>2008-11-10T15:40:25.137-06:00</updated><title type='text'>Visual Studio Complaints and Moanings</title><content type='html'>Visual Studio 2008 has become unbearably slow for me, so I&amp;#39;ve decided to take some measures. &amp;nbsp;My first steps was going to include removing the features of Visual Studio that I do not currently use. &amp;nbsp;Upon attempting to add/remove for Visual Studio I received the following error:&amp;nbsp;&lt;div&gt;  &lt;br&gt;&lt;blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204, 204, 204);border-left-style:solid;padding-left:1ex"&gt; &lt;span style="font-size:11px;white-space:pre"&gt;a problem has been encountered while loading the setup components&lt;/span&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;So as I research this issue, which seems &lt;a href="http://www.google.com/search?client=safari&amp;amp;rls=en&amp;amp;q=visual%20studio%202008%20%22a%20problem%20has%20been%20encountered%20while%20loading%20the%20setup%20components%22&amp;amp;ie=UTF-8&amp;amp;oe=UTF-8" target="_blank"&gt;very common&lt;/a&gt;, it seems to be a common theme that people who have patched VS.Net 2008 are having trouble running it&amp;#39;s setup. One solution has you install Visual Studio SP1, which I proceeded to install only for it to freeze in the middle.&lt;/div&gt;  &lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Next I decided I would just remove the existing hotfixes and patches I have installed for Visual Studio 2008 and then try to add/remove programs for VS.Net 2008. &amp;nbsp;This worked, I proceeded to remove VB, C++ and database environment.&lt;/div&gt;  &lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Finally I was able to apply SP1 to VS.Net 2008, which forced me to reboot.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;For those looking to speed up VS.Net a little bit you can try the tips from the following site which seemed to slightly improve the responsiveness for me:&amp;nbsp;&lt;a href="http://dotnettipoftheday.org/tips/speedup_visual_studio.aspx" target="_blank"&gt;dotnettipoftheday.org&lt;/a&gt;&amp;nbsp;&lt;/div&gt;  &lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Next I went back into VS.Net 2008 setup to remove some components and removed the following: Enterprise Tools, Dotfuscator Community Edition, Tools for Redistributing Applications, Team Developer and Tester Tools, Team Database Edition and Microsoft SQL Server 2005 Express Edition (actually this was already unchecked).&lt;/div&gt; &lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;I then went into add/remove programs and removed:&amp;nbsp;Microsoft Visual Studio Web Authoring Component and the header files (option below I think). &amp;nbsp;Beware of this however because when I did this I was no longer able to select &amp;quot;Add or Remove Features&amp;quot; within VS.Net setup, my guess is I&amp;#39;d have to &amp;#39;repair&amp;#39; it first.&lt;/div&gt; &lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;These are some of the reasons that Java&amp;#39;s Eclipse IDE is so widely popular (in and out of the Java community) because it gives you more granular control over your environment, it&amp;#39;s plugins and updates. &amp;nbsp;This is also why many people, including myself, prefer to have our unit testing and build tools to run outside of the environment.&lt;/div&gt; &lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Heres to one day having a robust C# &amp;amp; ASP.Net plugin for Eclipse.&lt;/div&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-7196540994837967088?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/7196540994837967088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=7196540994837967088' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7196540994837967088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7196540994837967088'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2008/11/visual-studio-complaints-and-moanings.html' title='Visual Studio Complaints and Moanings'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-5783743936867645231</id><published>2008-11-04T09:26:00.001-06:00</published><updated>2008-11-04T09:26:47.903-06:00</updated><title type='text'>Alt.Net Programmer's Toolbox</title><content type='html'>&lt;div&gt;Below is my toolbox for most projects. &amp;nbsp;Just an FYI you only really need to download and install Spring.Net since it includes bins for the other NHibernate, Castle, log4net and NUnit, though you will probably want to download NUnit so you can run the nunit gui.&lt;/div&gt; &lt;ul&gt;&lt;li&gt;&lt;a href="http://www.castleproject.org/"&gt;Castle Project&lt;/a&gt;&amp;nbsp;- provides IoC, DI and MVC frameworks&lt;/li&gt;&lt;li&gt;&lt;a href="http://logging.apache.org/log4net/index.html"&gt;log4net&lt;/a&gt; - mature logging framework for .Net&lt;/li&gt;&lt;li&gt; &lt;a href="http://www.mygenerationsoftware.com/portal/default.aspx"&gt;MyGeneration&lt;/a&gt; - code generation similar to CodeSmith except open source and free&lt;/li&gt;&lt;li&gt;&lt;a href="http://nant.sourceforge.net/"&gt;NAnt&lt;/a&gt; - build program&lt;/li&gt; &lt;li&gt;&lt;a href="http://www.hibernate.org/343.html"&gt;NHibernate&lt;/a&gt; - most mature ORM framework for .Net&lt;/li&gt; &lt;li&gt;&lt;a href="http://www.nunit.org/index.php"&gt;NUnit&lt;/a&gt; - most widely used .Net unit testing framework&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.springframework.net/"&gt;Spring.Net&lt;/a&gt; - enterprise ready framework supports ORM, logging, AOP, Caching through IoC&lt;/li&gt; &lt;li&gt;&lt;a href="http://www.tortoisecvs.org/"&gt;TortoiseCVS&lt;/a&gt; - access CVS repositories via Windows Explorer. &amp;nbsp;Nice to have if you want to get latest source from any open source project&lt;/li&gt; &lt;li&gt;&lt;a href="http://tortoisesvn.tigris.org/"&gt;TortoiseSVN&lt;/a&gt;&amp;nbsp;- access SVN repositories via Windows Explorer. &amp;nbsp;Nice to have if you want to get latest source from any open source project&lt;/li&gt;&lt;/ul&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-5783743936867645231?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/5783743936867645231/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=5783743936867645231' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/5783743936867645231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/5783743936867645231'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2008/11/altnet-programmers-toolbox.html' title='Alt.Net Programmer&apos;s Toolbox'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-8248958005419923204</id><published>2008-07-21T00:11:00.002-05:00</published><updated>2008-08-04T12:58:51.793-05:00</updated><title type='text'>The State of Affairs at Microsoft</title><content type='html'>&lt;div dir="ltr"&gt;&lt;div&gt;Microsoft is the modern day Roman Empire of technology as they have dominated their sector relentlessly but lately the company has struggled with analysts questioning the companies leadership including Steve Ballmer as their stock nears 52 week lows.  Their various products such as the XBOX, Zune and MSN/Live have all failed to make profits and Microsoft is literally hemorrhaging cash.  This is not entirely bad so long as you can bring in more cash than you are hemorrhaging as they have been able to do with their highly successful products such as Windows, Office and enterprise software.  While Microsoft in the enterprise in not immediately under threat, the other two legs of their company are: Windows &amp;amp; Office.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:Arial;"&gt;&lt;a href="http://goog_1216445077814/" target="_blank"&gt;Tom Reese and Paul Rubillo&lt;/a&gt;&lt;/span&gt;&lt;a href="http://www.forbes.com/2008/07/18/microsoft-mattel-citigroup-pf-ii-in_pr_0718soapbox_inl.html?partner=yahootix" target="_blank"&gt; writes(forbes)&lt;/a&gt; "&lt;span style="font-family:Arial;"&gt;Microsoft Office division numbers were a disappointment. Operating earnings there only grew a disappointing 12% for the period."  Of their online division they write "losses for that division doubled to $488 million from $210 million."&lt;/span&gt;&lt;/div&gt;  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://finance.yahoo.com/tech-ticker/article/40608/Microsofts-Real-Problem:-The-Second-Coming-of-Apple" target="_blank"&gt;Henry Blodget at Yahoo Finance&lt;/a&gt; thinks that Microsoft's real problem is Apple as he cites "Apple &lt;span style="line-height: 18px;"&gt;shipped 1.4 million computers in the US during Q2, representing 8.5% market share and 38% year-over-year growth.&lt;b style="line-height: 1.22em;"&gt;Mac shipments grew 9 times faster than the overall U.S. PC market (4.2%) in Q2."&lt;span style="font-weight: normal; line-height: normal;"&gt;  "&lt;span style="line-height: 18px;"&gt;U.S. Mac sales grew by 386,000 computers year-over-year,&lt;i style="line-height: 1.22em;"&gt;handily beating No. 2 HP&lt;/i&gt;, which sold just 222,000 more computers in Q2 2008."  And to his point Microsoft also recently announced that they are expanding their Apple Mac group to the largest size it's ever been, expecting more demand for MS Office on the Mac.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;  &lt;div&gt;&lt;span style="line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;While an Economist Podcast compared Microsoft trying to compete with Google and Facebook akin to "watching your father try to be cool."  Additionally &lt;a href="http://www.infoworld.com/article/08/07/17/Apple_now_third_largest_PC_vendor_in_the_US_1.html" target="_blank"&gt;InfoWorld reports&lt;/a&gt; that Apple is now the 3rd largest PC vendor in the US.&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="line-height: 18px;"&gt;What does this all mean and how does it relate to IT?  Well for years Microsoft has been able to cope with struggling products (MS Money, MSN/Live, XBox, Zune) and still pump money into new enterprise products such as BizTalk and Sharepoint for years before any profits.  They were able to do all of this partially because of the tremendous amount of money made through Windows and Office.&lt;/span&gt;&lt;/div&gt;  &lt;div&gt;&lt;span style="line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="line-height: 18px;"&gt;Microsoft has also not done much to help themselves, years of making enemies in the software industry have started to haunt them.  Efforts to push their own standards in many areas have faltered (HD DVD, OpenDocument).  They have even abandoned much work they started with standards like BPEL..  Standards such as OpenDocument or even Microsoft's own OpenXML will end up losing them market share.  Productivity applications will be using shared and common formats which will let allow transparency across platforms at the same time when cloud computing solutions like &lt;a href="http://www.google.com/enterprise/"&gt;Google Enterprise&lt;/a&gt; offer their own productivity suite.&lt;/span&gt;&lt;/div&gt;  &lt;div&gt;&lt;span style="line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="line-height: 18px;"&gt;In a nutshell the next step in technology is about ubiquity.  With cloud computing now becoming a reality with things such as Google Docs, Google Enterprise and Apple's MobileMe it will no longer matter what platform you run on as Windows, Linux, Macs and mobile devices will operate on common standards.  Each of these slowly eroding the high market share Microsoft has in the desktop market and eventually in the enterprise.&lt;/span&gt;&lt;/div&gt;  &lt;div&gt;&lt;span style="line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="line-height: 18px;"&gt;Microsoft is not about to vanish but a page is being turned in the history of the company.  Bill Gates has stepped down and there is much fresh blood in Microsoft with new perspectives.  Don't expect Apple to become the next Microsoft, as I don't think Job's wants Apple to be the next Microsoft.  Microsoft's monopoly may of helped consumers in the way that it allowed technology to saturate our life.  However at this time it isn't about accessibility to a computer as computers have become passe.  The next move will be towards how easy it is to get what we were looking for in a computer anyway (usability &amp;amp; portability).&lt;/span&gt;&lt;/div&gt;  &lt;div&gt;&lt;span style="line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="line-height: 18px;"&gt;As individuals in IT it's our responsibility to lay aside vendor loyalty and assess the situation and requirements.  We will have to begin making decisions again as Microsoft has made it a little too easy for us in IT to first use what Microsoft has and later argue that it will ultimately mature.  It's our responsibility to take risks to change companies which in turn help change the world.  Two things I am certain of that will be part of this future: open source software and standards.  The enterprises should begin embracing these solutions more often throwing off the fear of the past.&lt;br /&gt;&lt;/span&gt;&lt;/div&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-8248958005419923204?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/8248958005419923204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=8248958005419923204' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/8248958005419923204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/8248958005419923204'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2008/07/state-of-affairs-at-microsoft.html' title='The State of Affairs at Microsoft'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-3238273177082285388</id><published>2008-07-14T20:24:00.001-05:00</published><updated>2008-07-14T20:24:37.822-05:00</updated><title type='text'>Programming Mantras</title><content type='html'>Best practices change over time, but Mantras remain true for decades and should be things to live by.&amp;nbsp; Not these cannot be circumvented but these generally provide direction in what is good:&lt;br&gt;&lt;ol&gt;&lt;li&gt;Less code is better&lt;/li&gt;   &lt;li&gt;Nothing is sacred&lt;br&gt;&lt;/li&gt;&lt;li&gt;No &lt;a href="http://en.wikipedia.org/wiki/Fear%2C_uncertainty_and_doubt" target="_blank"&gt;FUD&lt;/a&gt; (fear uncertainty &amp;amp; doubt);&amp;nbsp; i.e. make points or decisions based on facts and number, not by invoking emotion and fear&lt;/li&gt;   &lt;li&gt;Make it work, make it right then make it fast&lt;br&gt;&lt;/li&gt;&lt;li&gt;Refactor often&lt;/li&gt;&lt;li&gt;Release and build often&lt;/li&gt;&lt;li&gt;Understand what you are going to do before you do it&lt;/li&gt;&lt;li&gt;Separation of duties is good&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;   &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-3238273177082285388?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/3238273177082285388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=3238273177082285388' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/3238273177082285388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/3238273177082285388'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2008/07/programming-mantras.html' title='Programming Mantras'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-1898820167316657620</id><published>2008-06-26T09:14:00.001-05:00</published><updated>2008-06-26T09:14:36.668-05:00</updated><title type='text'>Stored Procedures Followup</title><content type='html'>As a follow up to my previous post that stored procedures (sprocs) aren&amp;#39;t a best practice&amp;nbsp; (&lt;a href="http://scottwhite.blogspot.com/2008/04/stored-procedures-reconsidered.html"&gt;http://scottwhite.blogspot.com/2008/04/stored-procedures-reconsidered.html&lt;/a&gt;).&amp;nbsp; I would go as far as saying that as a general rule for database stored procedures are a bad practice.&amp;nbsp; In general it&amp;#39;s hard for the brain to go from one extreme to the other, so as obvious as this may be for some, it is hard to accept for others.&amp;nbsp; The basis of my argument is to counter each of the positives of stored procedures followed up with the advantages of not using them.&lt;br&gt; &lt;br&gt;If you are a believer in sprocs as a general rule then you should still come up with some disadvantages to make an impartial decision.&amp;nbsp; Early June (&amp;#39;08) I was at TechEd and I reiterated my blog regarding stored procedures to a member of the SQL Server development team at Microsoft.&amp;nbsp; Afterwards I asked if this was correct in his opinion.&amp;nbsp; His words: &amp;quot;Yes, I tell people not to use stored procedures.&amp;quot;&lt;br&gt; &lt;br&gt;To which I responded &amp;quot;it would be nice for you to tell people this.&amp;quot;&lt;br&gt;&lt;br&gt;&amp;quot;People are going to do what they are going to do&amp;quot; was his response.&amp;nbsp; My translation is simple: the opinion of your peers do not necessarily reflect the best practices of the vendor.&amp;nbsp; Additionally times change, best practices change, performance metrics change and Microsoft doesn&amp;#39;t typically speak with solidarity when it comes to best practices or design decision.&amp;nbsp; i.e. as long as you are running on Microsoft platform with Microsoft language and tools they don&amp;#39;t care what you do.&lt;br&gt; &lt;br&gt;At one point in time it was sufficient for systems to compile into each other&amp;#39;s code shared header files but this is no longer acceptable and we require packages or assemblies that are more portable such as a DLL.&amp;nbsp; You have to accept that change is inevitable in life and prepare yourself for trends that you may be uncomfortable with or unaware of.&amp;nbsp; I&amp;#39;ll close with a comment from the creator of Hibernate.&lt;br&gt; &lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;Stored procedures are essentially a nonrelational view of a relational database ... my view, currently, is that the goal of an object-relational mapping tool should be to map between tables and objects, not between objects and &amp;quot;some other stuff.&amp;quot;&lt;/blockquote&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-1898820167316657620?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/1898820167316657620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=1898820167316657620' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/1898820167316657620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/1898820167316657620'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2008/06/stored-procedures-followup.html' title='Stored Procedures Followup'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-7381409221077860894</id><published>2008-05-08T09:14:00.002-05:00</published><updated>2008-05-08T09:16:26.981-05:00</updated><title type='text'>NUnit Best Practices</title><content type='html'>&lt;div&gt;Programming is not just an art, not just a science, but a discipline.  Part of what we all know we should be doing includes solid unit testing.  Below is my list of best practices, feel free to comment and add others I enjoy feedback.&lt;/div&gt; &lt;div&gt;&lt;ol&gt;&lt;li&gt;Create a separate assembly for your test fixtures&lt;/li&gt;&lt;ul&gt;&lt;li&gt;i.e. don't be lazy and put your test fixtures in the same assembly as the application code)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Create a bin folder per solution and place nunit.framework.dll in there&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Each project should copy their binaries to the solution bin folder.  Your Post-Build event should look like this: copy $(TargetFileName) "../../../bin/"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Categorize your test fixtures such as DAO, ETL and BusinessRules.  This will let you test pieces of your application more easily: [Category("ETL")]&lt;/li&gt; &lt;li&gt;Once you have the basic interface of a class written, it is time to write your unit test for it.  Even though it will fail it will at least serve as a place holder to go back to as well as serving as a test for when things are working&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Make sure each test is atomic.  Therefore if you are inserting data into a table and you know say CustomerName must be unique, then the second time you run your test it will fail because of uniqueness.  For this reason have your persistence tests be all inclusive, include an insert, update and delete.  Put your delete code into a finally so that it is always executed regardless of if the other tests succeed or not&lt;/li&gt; &lt;li&gt;If you notice all of your test fixtures perform certain setup every time, create a base class for this, let's say each one of your DAO classes will be instantiating a connection and opening it before starting and this connection needs to be closed at the end of testing whether it fails or succeeds&lt;/li&gt; &lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;Obviously we would never want to handle connection objects in our Unit Tests, this would be bad design, in the real world it may be a stream or nhibernate session that you  are configuring.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/ol&gt;&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;[TestFixture]&lt;br /&gt;public class DAOBaseFixture&lt;br /&gt;{&lt;br /&gt;SqlConnection cn;&lt;br /&gt;&lt;br /&gt;[SetUp]&lt;br /&gt;public void Init()&lt;br /&gt;{&lt;br /&gt;  cn = new SqlConnection();&lt;br /&gt;  cn.Open("...");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[TearDown]&lt;br /&gt;public Cleanup()&lt;br /&gt;{&lt;br /&gt;  cn.Close();&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;}&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;Now derivatives of this class won't even have to implement the [TestFixture] attribute nor take care of their setup.  They will be free to just take care of their own tests.&lt;/blockquote&gt; &lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt; public class CustomerDAOTests : DAOBaseFixture&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;{&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt; [Test]&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;[Category("DAO")]&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt; public void FindAll()&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;{...}&lt;/blockquote&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt; }&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I still recommend to people writing .Net code to use NUnit.  First it's free and you don't have to own any version of Visual Studio to support it.  Therefore if you have programmers or testers offshore who only have Visual Studio Pro they can still run it.  You don't even need a Visual Studio license to run it.  Finally it's a very mature product and it's semantics are well accepted and somewhat portable from language to language.&lt;/div&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-7381409221077860894?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/7381409221077860894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=7381409221077860894' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7381409221077860894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7381409221077860894'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2008/05/nunit-best-practices.html' title='NUnit Best Practices'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-2722938424779975842</id><published>2008-04-21T14:56:00.001-05:00</published><updated>2008-04-21T14:56:37.870-05:00</updated><title type='text'>Stored Procedures Reconsidered</title><content type='html'>For longtime Microsoft SQL Server users such as myself, one would ask: What is there to reconsider?&amp;nbsp; It&amp;#39;s long considered to be a best practice in the Microsoft world to at least have 3-4 stored procedures (sprocs) for every table usually an insert, update, delete and a simple select statement.&lt;br&gt; &lt;br&gt;It may surprise some that people outside of the SQL Server world (Oracle, DB2) do not use sprocs nearly as often and they apply them differently.&amp;nbsp; I will lay out my argument calling for the end of this &amp;#39;best practice&amp;#39;.&lt;br&gt; &lt;br&gt;First let&amp;#39;s dissect the main arguments for this best practice, they include the following: &lt;b&gt;performance, security, reusability &amp;amp; separation of duties&lt;/b&gt;.&lt;br&gt;&lt;br&gt;&lt;b&gt;Performance&lt;/b&gt; argument surrounds the assumption that stored procedures are precompiled.&amp;nbsp; However this is not always a benefit SQL Server&amp;#39;s own Books Online says:&lt;br&gt; &lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;i&gt;When SQL Server executes stored procedures, any parameter values used by the  procedure when it compiles are included as part of generating the query plan. If  these values represent the typical ones with which the procedure is called  subsequently, then the stored procedure benefits from the query plan each time  it compiles and executes. If not, performance may suffer.&lt;/i&gt;&lt;/blockquote&gt;&lt;br&gt;&amp;nbsp;If you read this you will understand that only the part of the query that does not change is precompiled and if the parameters change performance may suffer.&amp;nbsp; SQL Server stores execution plans for any query sent to it, therefore there is no advantage in this department.&amp;nbsp; If any performance difference is negligible.&amp;nbsp; Also if you are dynamically generating SQL in your sproc and executing it, you will also have no performance advantage.&amp;nbsp; Sprocs also give developers a container to write cursors which are a bad practice (in SQL Server) since they create temp tables.&amp;nbsp; Additionally the most common stored procedures are usually the most trivial SQL statements (insert, update, delete).&lt;br&gt; &lt;br&gt;&lt;b&gt;Security&lt;/b&gt; argument is based on two arguments: granular security access &amp;amp; SQL Injection attacks.&amp;nbsp; The granular security argument is that you don&amp;#39;t give users access into the table, you only give them access to execute a stored procedure.&amp;nbsp; My response to this is so what, the user&amp;#39;s still have access to insert.&amp;nbsp; Really what is the risk (odds) of a user finding out the database security credentials, understanding the database, and issuing a proper sql statement.&amp;nbsp; Odds are if the user is capable of this then they are capable of executing your sproc.&amp;nbsp; Furthermore many pieces of your security have to fail you for any of this to happen.&amp;nbsp; I call this a long shot.&lt;br&gt; &lt;br&gt;The SQL Injection is actually a misconception based on the fact people commonly issue parameterized queries as opposed to constructing a string.&amp;nbsp; You can use sprocs and still have SQL Injection vulnerability if you are doing something like this:&lt;br&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;cmd.Execute(&amp;quot;exec InsertCust 1, &amp;#39;hello&amp;#39;&amp;quot;);&lt;/blockquote&gt;&lt;br&gt;&amp;nbsp;&lt;b&gt;Reusability&lt;/b&gt; argument is only relevant if you don&amp;#39;t have proper layers in an application to allow reuse from your app tier or business objects.&amp;nbsp; Unless you are letting other applications access your database which is generally not recommended.&lt;br&gt; &lt;br&gt;&lt;b&gt;Separation of duties&lt;/b&gt; assumes that the job of your RDBMS is to be a repository for SQL code.&amp;nbsp; This wasn&amp;#39;t it&amp;#39;s vision and there&amp;#39;s a stronger argument that SQL statements fall more inline with business process and business logic therefore they belong there.&amp;nbsp; If you implement a good ORM strategy then you don&amp;#39;t even have to worry about &amp;#39;hard coding&amp;#39; SQL into your application.&amp;nbsp; Furthermore your app tier and business objects are more likely to have unit tests therefore regression testing at the object level is seamless.&lt;br&gt; &lt;br&gt;&lt;b&gt;The case against stored procedures&lt;/b&gt;&lt;br&gt;Stored procedures are procedural, not object oriented therefore their extensibility for reuse is minimal.&amp;nbsp; This is why a sproc only architecture is a failed one, it&amp;#39;s time consuming for little to no return on your investments.&amp;nbsp; It&amp;#39;s common for people to rewrite an entire sproc purely because the original one did not work exactly for their purpose or they do not understand it. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-2722938424779975842?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/2722938424779975842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=2722938424779975842' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/2722938424779975842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/2722938424779975842'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2008/04/stored-procedures-reconsidered.html' title='Stored Procedures Reconsidered'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-7694404187313707082</id><published>2008-03-24T14:25:00.003-05:00</published><updated>2008-04-11T09:44:31.960-05:00</updated><title type='text'>Spring 2008 Toolkit</title><content type='html'>Below is my complication of free (and mostly open source) development tools and other applications for Spring of '08:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.7-zip.org/download.html"&gt;7z 4.57&lt;/a&gt; - The most intensive compression tool available&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.mozilla.com/en-US/firefox/"&gt;FireFox 2.0.0.12&lt;/a&gt; - Best internet browser available especially when you install some of the great add-ons out there&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/aa480453.aspx"&gt;Microsoft Enterprise Libraries&lt;/a&gt; - Building blocks for building enterprise applications&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.mygenerationsoftware.com/portal/default.aspx"&gt;MyGeneration&lt;/a&gt; - Free/open source code generation for variety of tasks&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://nunit.org/index.php?p=download"&gt;Nunit 2.4.6&lt;/a&gt; - Unit testing for every version of .Net&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sourceforge.net/project/showfiles.php?group_id=73818&amp;amp;package_id=73969"&gt;NHibernate 1.2&lt;/a&gt; - ORM for .Net&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.springframework.net/download.html"&gt;Spring.net 1.1&lt;/a&gt; - framework for doing powerful OOP in .Net including remoting, AOP and more&lt;/li&gt;&lt;li&gt;&lt;a href="http://winmerge.org/downloads/index.php"&gt;WinMerge 2.1.14&lt;/a&gt; - clean &amp;amp; quick merging and diff application&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-7694404187313707082?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/7694404187313707082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=7694404187313707082' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7694404187313707082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/7694404187313707082'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2008/03/spring-2008-toolkit.html' title='Spring 2008 Toolkit'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-6190988262517821839</id><published>2007-05-15T09:51:00.000-05:00</published><updated>2007-05-15T10:31:37.401-05:00</updated><title type='text'>Review of SCM &amp; VCS</title><content type='html'>The basic need for both Version Control Systems (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;VCS&lt;/span&gt;) &amp; Software Configuration Management (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;SCM&lt;/span&gt;) have been needed since the beginning of programming.  However in recent years more mature products have hit the market and are worth considering.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;CVS&lt;/span&gt; - old school basic &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;VCS&lt;/span&gt;.  Not much to delve into here, a quality product.  It is a client-server system which is a plus, has no &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;SCM&lt;/span&gt; capabilities &amp;amp; is known to have encoding issues from different platforms, basic security implementation.  Overall a descent &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;VCS&lt;/span&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;SVN&lt;/span&gt; (subversion) - seen as the successor to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;CVS&lt;/span&gt;.  Architecture is also client-server, can use HTTP through Apache.  No &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;SCM&lt;/span&gt; &amp; basic security implementation. A quality &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;VCS&lt;/span&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;VSS&lt;/span&gt; (Visual &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;SourceSafe&lt;/span&gt;) - basic &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;VCS&lt;/span&gt;, some basic security, flawed design requires users read/write access to directories, leaving repository open to tampering.  Architecture is client based.  Probably the worst of all offerings, however good integration into Visual Studio is cheap and is better than &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;nother&lt;/span&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;StarTeam&lt;/span&gt; - my personal favorite, works with Eclipse, Visual Studio, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;Togethersoft&lt;/span&gt; &amp;amp; many other &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;IDEs&lt;/span&gt;.  Provides full &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;VCS&lt;/span&gt; &amp; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;SCM&lt;/span&gt;.  This is a very mature product.  Integration is seamless &amp;amp; is more intuitive than MS &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;TFS&lt;/span&gt; (Team Foundation Server)&lt;/li&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;TFS&lt;/span&gt; (Team Foundation Server) - I really wanted to like this one but I didn't.  The integration into Visual Studio seems cumbersome, not as &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;seemless&lt;/span&gt; as &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;VSS&lt;/span&gt; or &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;StarTeam&lt;/span&gt; &amp; the bug tracking was horrible.  As for the other features if I cannot get passed the bug tracking then cannot be seriously considered a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;SCM&lt;/span&gt; product.  This is a version 1 Microsoft product, hopefully it will become more mature over the years.  Our &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;QA&lt;/span&gt; personnel at the time also despised the product, installing Visual Studio on a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;QA&lt;/span&gt; persons laptop seems backwards.&lt;/li&gt;&lt;/ol&gt;There are many other products out there, but I think I covered the main ones.  I would be more than happy to review any others that are recommended.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Results&lt;br /&gt;&lt;/span&gt;The winner here is &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;Borland's&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;StarTeam&lt;/span&gt;, it is a mature product has good integration into a wide variety of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;IDEs&lt;/span&gt; and is both a quality &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;SCM&lt;/span&gt; &amp; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;VCS&lt;/span&gt;.  Whether you are a heads down coder, PM or &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;QA&lt;/span&gt; guy you cannot go wrong here.  I also want to give a plug to another great product from &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;Borland&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;Togethersoft&lt;/span&gt;.  It integrates into the major &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;IDEs&lt;/span&gt; &amp; provides object modeling, data modeling as well as code &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;refactoring&lt;/span&gt; and generation.  I cannot say enough about this product.&lt;br /&gt;&lt;br /&gt;For basic &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;VCS&lt;/span&gt; needs &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;CVS&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;SVN&lt;/span&gt; or &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;VSS&lt;/span&gt; all fit the bill and is better than nothing and cost nothing.  Just make sure that you still have a backup plan regardless of which product you decide to deploy.&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-6190988262517821839?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/6190988262517821839/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=6190988262517821839' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/6190988262517821839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/6190988262517821839'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2007/05/review-of-scm-vcs.html' title='Review of SCM &amp; VCS'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-117163928634943354</id><published>2007-02-16T09:12:00.000-06:00</published><updated>2007-02-27T14:41:57.064-06:00</updated><title type='text'>Regex vs string.replace()  Python vs PHP</title><content type='html'>RegEx or regular expressions have become popular now in every programming language.  It involves a special string which identifies ways to match other strings.  It's wonderful for performing a match with a sequences of strings especially if the logic for the match is somewhat complex. RegEx can greatly increase the performance of an app or slow it down &amp; obfuscate it.&lt;br /&gt;&lt;br /&gt;Before deciding to use a RegEx, first figure out what you want to do.  Lets take two common &amp;amp; basic tasks: input validation of email &amp; replacing a matching string.&lt;br /&gt;&lt;br /&gt;First, since the rules for email can be somewhat complicated (for string matching) this would make a good candidate for RegEx, especially if the validation is taking place on the client (who cares about client CPU cycles?).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Benchmark results of 10K operations (smaller number is better)&lt;/span&gt;&lt;br /&gt;Large String Length: 65181 chars&lt;br /&gt;Small String Length: 97 chars&lt;br /&gt;Simple String: 45 chars&lt;br /&gt;Complex RegEx: email validation is a RegEx 60 chars&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Python:&lt;/span&gt;&lt;br /&gt;Testing 100K Loop&lt;br /&gt;0:00:00.025730&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Small simple replacement&lt;/span&gt;&lt;br /&gt;string.replace()&lt;br /&gt;0:00:00.032380&lt;br /&gt;&lt;br /&gt;RegEx (compiled)&lt;br /&gt;0:00:00.055416&lt;br /&gt;&lt;br /&gt;RegEx (uncompiled)&lt;br /&gt;0:00:00.054967&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Large simple replacement&lt;/span&gt;&lt;br /&gt;string.replace()&lt;br /&gt;0:00:04.781832&lt;br /&gt;&lt;br /&gt;RegEx (compiled)&lt;br /&gt;0:00:03.997719&lt;br /&gt;&lt;br /&gt;RegEx (uncompiled)&lt;br /&gt;0:00:03.141389&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Complicated RegEx&lt;/span&gt;&lt;br /&gt;compiled&lt;br /&gt;0:00:00.034440&lt;br /&gt;&lt;br /&gt;uncompiled&lt;br /&gt;0:00:00.080525&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;PHP&lt;/span&gt;&lt;br /&gt;Testing 100K Loop:&lt;br /&gt;0.0390350818634&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Small simple replacement&lt;/span&gt;&lt;br /&gt;string replace()&lt;br /&gt;0.0481541156769&lt;br /&gt;&lt;br /&gt;RegEx&lt;br /&gt;0.0470488071442&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Large simple replacement&lt;/span&gt;&lt;br /&gt;string replace()&lt;br /&gt;1.68269109726&lt;br /&gt;&lt;br /&gt;RegEx (uncompiled)&lt;br /&gt;1.76776599884&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Complicated RegEx&lt;/span&gt;&lt;br /&gt;0.0417048931122&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Overall&lt;/span&gt;&lt;br /&gt;Comparing language to language Python is faster in all categories except where the replace expression is simple &amp; the target string is large, here PHP whooped up very nicely.  As you can see there is no one size fits all rule, I would expect every language to have sorted results.  In preliminary results with C# (.Net 2.0) the RegEx seemed very ineffecient, I hope to post results later.&lt;br /&gt;&lt;br /&gt;As to precompiling Reg Ex, it only makes a difference if your expression is complicated, the more complicated your Reg Ex is the bigger boost in performance you get.  As these tests show, precompiling your Reg Ex is not always faster.&lt;br /&gt;&lt;br /&gt;Note: PHP doesn't support Unicode strings or precompiled RegEx, Python supports both of these, however Unicode RegEx results seemed fairly slow.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;In Python&lt;/span&gt;&lt;br /&gt;if the target string small &amp; your matching expression is simple use string.replace(), if the target string is much larger then use RegEx uncompiled.  With complicated Reg Ex use RegEx compiled.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;In PHP&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;for small target strings with simple matching expression RegEx is slightly faster, differences are negligible.  For larger target strings with simple matching string.replace is a bit faster.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-117163928634943354?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/117163928634943354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=117163928634943354' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/117163928634943354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/117163928634943354'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2007/02/judicial-use-of-regex.html' title='Regex vs string.replace()  Python vs PHP'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-115569579495780529</id><published>2006-08-15T20:54:00.000-05:00</published><updated>2006-08-15T21:36:35.383-05:00</updated><title type='text'>Ubuntu Linux 6.06 Review</title><content type='html'>Ubuntu Linux is the biggest Linux distribution to hit the open source software (OSS) community since , well forever.  Ubuntu's motto is "Linux for Human Beings."  For many its the usability or ease of use, for others it's the power and flexibility, regardless of what you want it's here.&lt;br /&gt;&lt;br /&gt;For the Windows-only users, yes Ubuntu has GUI and rich GUI.  OOB it has media, instant messaging, networking, internet browsing (FireFox), Bit Torrenting and Open Office technology.  When you want to install Ubuntu it is very straight forward, you boot off of a CD and boot directly to Ubuntu.  You can try it out and/or install it now, just double-click the "Install" on your desktop.&lt;br /&gt;&lt;br /&gt;Feel free to browse the internet or instant message will this is going on.  If you have Windows installed you can either erase it or resize that partition and install alongside it.  After it installs you will reboot and that's it&lt;br /&gt;&lt;br /&gt;Where to go from here?  Browse the &lt;a href="http://ubuntuguide.org/wiki/Dapper"&gt;Ubuntu Guide wiki&lt;/a&gt; which is your best source for most everything you want to do on Ubuntu.&lt;br /&gt;&lt;br /&gt;Ubuntu 6.06 also has a server version, this one is commandline only and has an optional LAMP configuration.  So next time you want to setup a Linux server consider Ubuntu.&lt;br /&gt;&lt;br /&gt;Ubuntu uses a Debian core with Gnome and lots of other nice add-ons.  Some commercially based packages to not come included (such as mp3 support) because of legal reasons.  Other negatives are nice haves such wireless management GUI needs to be installed (thoguh WiFi itself is supported OOB).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ubuntu.com/download"&gt;Download Ubuntu&lt;/a&gt; (.iso or torrent)&lt;br /&gt;Rating 8/10 (Great)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-115569579495780529?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.ubuntu.com/' title='Ubuntu Linux 6.06 Review'/><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/115569579495780529/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=115569579495780529' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/115569579495780529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/115569579495780529'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2006/08/ubuntu-linux-606-review.html' title='Ubuntu Linux 6.06 Review'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-115262842307864396</id><published>2006-07-11T09:15:00.000-05:00</published><updated>2006-07-11T09:49:53.280-05:00</updated><title type='text'>Coffee</title><content type='html'>The drug of choice for many of us who choose to go without Ritalin.  This upper, served hot normally delivering over 100MG of caffeine per cup.&lt;br /&gt;&lt;br /&gt;Unfortunately something goes wrong when people make it.  Whether it's chewing on coffee grinds, tastes like cigarette butts or as weak as hot tea at Denny's.  Apparently we need help.  This covers basic coffee brewing and where to find good coffee.&lt;br /&gt;&lt;br /&gt;I'm going to cover two main brewing techniques: Drip &amp; French Press.  Most companies employ the drip coffee machine, which is fine.  Chose a metal filter over a paper filter, or a natural paper filter over a bleached white paper filter, you get the idea.  If using paper filters just use ONE, more than that will over filter the coffee.&lt;br /&gt;&lt;br /&gt;Now fill the filter up about 3/4 of the way, I don't like to measure for this because it takes too long and every machine is different, use some trial and error.  Always brew coffee on the stronger side, because you can easily make it weaker adding hot water, you can't make it stronger.&lt;br /&gt;&lt;br /&gt;Next fill your coffee up with water, if there's not a direct water feed.  Do not neglect this step, use filtered or bottle water, I really don't recommend using tap water for this for taste reasons.  Finally start the machine, then wholla.&lt;br /&gt;&lt;br /&gt;Lastly if your company doesn't have the proper tools for good coffee (i.e. good coffee, machine, filter, water), then use this technique.  Buy a Brita water filter pitcher keep a good amount of water in this at all times.  Next buy yourself a French Press, whole bean coffee and a grinder.  You can however grind the coffee at the store but I recommend fresh grinding before use.&lt;br /&gt;&lt;br /&gt;Grind your beans coarsely, then fill your French press with the appropriate amount and fill the glass container with hot boiled filtered water and stir.  Let the steep for ~5 min, plunge and serve.&lt;br /&gt;&lt;br /&gt;The best way to ruin a good cup of coffee is by taking CoffeeMate (or other artificial creamers) and dumping it into your expensive Java.  At this point just pick up some coffee at McDonald's or something, YOU RUINED IT!!!  Use a dairy product, preferably Half &amp;amp; Half or Whole milk, but any milk product will be better than coffee mate.&lt;br /&gt;&lt;br /&gt;However if you do like CoffeeMate, you can substitute it with some Karo (corn syrup) and then have your coworker spit in it, wholla!!&lt;br /&gt;&lt;br /&gt;Lastly, there is the coffee bean itself, the most expensive product to coffee making.  Regardless of what commercials tell you, the worst part of waking up is Folgers in your cup, therefore get some good coffee.  Starbucks is a good high quality brand so are many local roasters.  Smelling the coffee is a good indicator of it's flavor and quality.  Whole Foods, Central Market and Costco all sell great coffee, and I don't mean the smelly stuff in the tin cans.&lt;br /&gt;&lt;br /&gt;With these tips your can be a better coworker, team member and never ruin someone's morning again.... well not with coffee...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-115262842307864396?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/115262842307864396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=115262842307864396' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/115262842307864396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/115262842307864396'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2006/07/coffee.html' title='Coffee'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-114468165202632474</id><published>2006-04-10T09:56:00.000-05:00</published><updated>2006-04-10T10:52:09.613-05:00</updated><title type='text'>Visual Studio 2005 Settings</title><content type='html'>Visual Studio 2005 is definitely one of the richest development environments I've ever experienced.  This can be a good or bad thing.  If you are new to programming a language within Visual Studio 2005 it can be helpful for learning.  However if you are an experienced programmer you probably liken it to being babysat.  Below are my Visual Studio 2005 Advanced Programmers settings.&lt;br /&gt;&lt;br /&gt;TV: Treeview&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Within Visual Studio 2005 open Options&lt;/li&gt;&lt;ol&gt;&lt;li&gt;If I have to tell you where this is then you probably don't need these settings&lt;/li&gt;  &lt;/ol&gt;  &lt;li&gt;Stop showing Start Page at IDE startup&lt;br /&gt;&lt;/li&gt;  &lt;ol&gt;&lt;li&gt;TV: Environment -&gt; Startup -&gt; change At startup to Show empty environment&lt;/li&gt;  &lt;/ol&gt;  &lt;li&gt;Show line numbers&lt;br /&gt;&lt;/li&gt;  &lt;ol&gt;    &lt;li&gt;TV: Text Editor -&gt; All Languages -&gt; check Line numbers&lt;/li&gt;  &lt;/ol&gt;  &lt;li&gt;Change indenting to use Tabs&lt;/li&gt;&lt;ol&gt;&lt;li&gt;TV: Text Editor -&gt; All Languages -&gt; Tabs -&gt; click Keep tabs&lt;/li&gt;  &lt;/ol&gt;  &lt;li&gt;Turn off paranoid autocomplete&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Text Editor -&gt; C# -&gt; IntelliSense -&gt; uncheck Show completion list after a character is typed&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-114468165202632474?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/114468165202632474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=114468165202632474' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/114468165202632474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/114468165202632474'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2006/04/visual-studio-2005-settings.html' title='Visual Studio 2005 Settings'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-114416722192205636</id><published>2006-04-04T11:10:00.000-05:00</published><updated>2006-04-04T11:13:41.943-05:00</updated><title type='text'>Archiving &amp; Compression Utilities</title><content type='html'>&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-size: 10pt; font-family: Arial;"&gt;We’ve all been using archiving &amp;  compression utilities forever, whether our first one was tar &amp;amp; bz or PKZip.   As compression algorithms have evolved newer archiving utilities have come out  that promise new functionality and better compression.  Two of them are Rar  (WinRar) and 7z.  A few months ago I switched from WinRAR to  7z.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-size: 10pt; font-family: Arial;"&gt;7z promises better compression and  is free/open source.  Upon first using it I encountered little difference from  other archiving/compression utilities and it supports all the right-click  actions you would expect.  Up until now I haven’t had a chance to compare RAR  compression to 7z since I haven’t compressed anything large and assorted with  it.&lt;o:p&gt; &lt;/o:p&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-size: 10pt; font-family: Arial;"&gt;I needed to zip up BizTalk 2006 Developers edition CD,  which is 450MB.  This is my first test.&lt;o:p&gt;&lt;br /&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;u&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-weight: bold; font-size: 10pt; font-family: Arial;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;u&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-weight: bold; font-size: 10pt; font-family: Arial;"&gt;Results:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-size: 10pt; font-family: Arial;"&gt;RAR (Best) compression –  123MB&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;7z (Ultra) compression –  92MB&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-weight: bold; font-size: 10pt; font-family: Arial;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-weight: bold; font-size: 10pt; font-family: Arial;"&gt;Conclusion&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-size: 10pt; font-family: Arial;"&gt;7z offers better compression with  best compression than RAR and is FREE.  Worried about switching to 7z?  It can  compress 7z &amp; ZIP files as well as extract RAR  archives.&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-size: 10pt; font-family: Arial;"&gt;&lt;a title="http://sourceforge.net/projects/sevenzip/" href="http://sourceforge.net/projects/sevenzip/"&gt;http://sourceforge.net/projects/sevenzip/&lt;/a&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-size: 10pt; font-family: Arial;"&gt;See also: &lt;a title="http://www.maximumcompression.com/" href="http://www.maximumcompression.com/"&gt;http://www.maximumcompression.com/&lt;/a&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-114416722192205636?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/114416722192205636/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=114416722192205636' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/114416722192205636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/114416722192205636'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2006/04/archiving-compression-utilities.html' title='Archiving &amp; Compression Utilities'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-113833510345636205</id><published>2006-01-26T21:34:00.000-06:00</published><updated>2006-01-26T22:18:43.516-06:00</updated><title type='text'>Microsoft Enterprise Library &amp; The Gac</title><content type='html'>For a while we have been installing a few of the assemblies from the Microsoft Enterprise Library to the GAC.  The time came when I broke down and decided to install them all into the GAC.&lt;br /&gt;&lt;br /&gt;There are many reasons to install the Enterprise Library into the GAC, they include:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Component reuse, less duplicity and more consistency&lt;/li&gt;&lt;li&gt;Performance benefits&lt;/li&gt;&lt;li&gt;Allows use in other systems such as BizTalk&lt;/li&gt;&lt;li&gt;Allows you to consistently manage changes throughout your organization&lt;/li&gt;&lt;/ol&gt;First step is creating strong name keys for all of the assemblies.  From a command prompt (see earlier post regarding setting environmental variables):&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;sn -k Microsoft.Practices.EnterpriseLibrary.Data.snk&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;That will do the Data blocks.&lt;br /&gt;&lt;br /&gt;Next you must modify the AssemblyInfo.cs file:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;[assembly: AssemblyKeyFile("..\\..\\Microsoft.Practices.EnterpriseLibrary.Data.snk")]&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Lastly you have to figure out how you want to distribute your assemblies.  While you can create an installer to do it, you will need to create Installer classes to do this as you need to install them into the GAC.  I think the most pragmatic approach is a batch file.  You can create one batch file to install all the assemblies you choose into the GAC.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;gacutil -i Microsoft.Practices.EnterpriseLibrary.Data.dll&lt;br /&gt;pause&lt;/blockquote&gt;This installs the data blocks into the GAC and the pauses so that you can see the results if you want to double-click the file from Windows explorer.&lt;br /&gt;&lt;br /&gt;In order to install all of the assemblies into the GAC you can manually do this to all of them or you can script it.  I have written a small command line application that I will post later that will recursively setup assemblies to be installed into the GAC and includes all of these steps.  If you do this installation manually NOTE: you do not want to install into the GAC any assemblies that end in .Design or any of the tools.&lt;br /&gt;&lt;br /&gt;Tom Hollander has also blogged about this subject, you might want to see his comments.  He is the Product Manager for Microsoft Patterns &amp;amp; Practices.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-113833510345636205?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/113833510345636205/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=113833510345636205' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/113833510345636205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/113833510345636205'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2006/01/microsoft-enterprise-library-gac.html' title='Microsoft Enterprise Library &amp; The Gac'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-112794663222546819</id><published>2005-09-28T17:23:00.000-05:00</published><updated>2005-09-28T17:30:32.230-05:00</updated><title type='text'>Using Development Tools via command line</title><content type='html'>In order to access many handy .Net tools or BizTalk for that matter, you must navigate to the proper directory first, not an option, or launch Visual Studio .NET 2003 Command Prompt.&lt;br /&gt;&lt;br /&gt;A way around this is to add Paths to your system Path Environment variables.  To do this, do the following:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Right-click My Computer, click Properties&lt;/li&gt;   &lt;li&gt;Click the Advanced tab, then the Environment Variables button&lt;/li&gt;   &lt;li&gt;Under System variables select Path, then click Edit&lt;/li&gt;   &lt;li&gt;Add the following to the end of the Variable value field:&lt;/li&gt;   &lt;li&gt;;C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\;C:\Program Files\Microsoft BizTalk Server 2004\&lt;/li&gt; &lt;/ol&gt; Now you can perform the following utilities (and more) from any command prompt: installment, gacutil, ilasm &amp;amp; btsdeploy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-112794663222546819?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/112794663222546819/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=112794663222546819' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112794663222546819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112794663222546819'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/09/using-development-tools-via-command.html' title='Using Development Tools via command line'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-112612584564157871</id><published>2005-09-07T15:41:00.000-05:00</published><updated>2005-09-07T15:44:05.643-05:00</updated><title type='text'>Best Practices</title><content type='html'>I've been working on a best practices document containing sections for C#, .Net, BizTalk 2004, SQL Server, and IIS.  Below is the best practices for each of the following technologies, according to me (Scott White).&lt;br /&gt;&lt;br /&gt;Feel free to comment, challenge or add to the respected lists.  If change makes sense, I'm more than welcome to make it.&lt;br /&gt;&lt;br /&gt;Thanks!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-112612584564157871?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/112612584564157871/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=112612584564157871' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112612584564157871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112612584564157871'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/09/best-practices.html' title='Best Practices'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-112612560652610933</id><published>2005-09-07T15:38:00.000-05:00</published><updated>2005-09-07T15:50:51.086-05:00</updated><title type='text'>Best Practices: C# &amp; .Net</title><content type='html'>&lt;ol&gt;   &lt;li&gt;Private and class-level variables should be written using camel casing&lt;/li&gt;   &lt;li&gt;Public members should be named using Pascal casing&lt;/li&gt;   &lt;li&gt;Use proper namespacing within all your .Net classes &amp;amp; projects such as: [CompanyName].[BusinessUnit].[ProjectName].[VSNetProjectName]&lt;br /&gt;Example:&lt;br /&gt;Microsoft.Office.HelloWorld.Ui&lt;br /&gt;Microsoft.Office.HelloWorld.Data&lt;/li&gt;   &lt;li&gt;Create separate projects and namespaces for your UI, Data and Business layers&lt;/li&gt;   &lt;li&gt;Use DataSet when retrieving results from database and the data needs to be reread, serialized, cached or multiple sets of data need to be related and joined&lt;/li&gt;   &lt;li&gt;Use DataReader when retrieving results from database and the data needs to be read once and displayed quickly&lt;/li&gt;   &lt;li&gt;Use XPathDocument when reading XML and needing to extract elements (use XPath, etc) out of the XML document&lt;/li&gt;   &lt;li&gt;Use XmlDocument when needing to perform two or more of the following: read, write or serialize.&lt;/li&gt;   &lt;li&gt;Use Command objects to execute SQL code or stored procedures&lt;/li&gt;   &lt;li&gt;Use EnterpriseLibrary (Application Blocks) in your application where possible, as they are a collection of best practices in working with .Net&lt;/li&gt;   &lt;li&gt;Use StringBuilder object to construct strings instead of using plus (+) sign to concatenate&lt;/li&gt;   &lt;li&gt;Use regular ‘for’ loop instead of ‘for each’ loop where possible, as traditional ‘for’ loop is faster and more efficient&lt;/li&gt;   &lt;li&gt;Avoid using DataAdapter objects&lt;/li&gt;   &lt;li&gt;Avoid using the DataGrid for inline editing, especially the more complex the process and logic is, as this creates something resembling spaghetti code&lt;/li&gt;   &lt;li&gt;Add attributes to web service classes and their public exposable members by using [WebService] and [WebMethod]. Properly namespace your web service and document the web service and your web methods this way&lt;/li&gt;   &lt;li&gt;Add XML Comments to all private and public members&lt;/li&gt;   &lt;li&gt;Use source code control&lt;/li&gt; &lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-112612560652610933?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/112612560652610933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=112612560652610933' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112612560652610933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112612560652610933'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/09/best-practices-c-net.html' title='Best Practices: C# &amp; .Net'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-112612539454689843</id><published>2005-09-07T15:34:00.000-05:00</published><updated>2005-09-07T15:45:54.493-05:00</updated><title type='text'>Best Practices: BizTalk 2004</title><content type='html'>&lt;ol&gt;   &lt;li&gt;Although simple mappings can be performed using BizTalk Mapper, use XSLT to perform mappings if they get to long and/or complex&lt;/li&gt;   &lt;li&gt;Do not use Human Workflow Services (HWS) or even install it, as it is not a good Human Workflow engine and Microsoft is going to deprecate it&lt;/li&gt;   &lt;li&gt;Fix all SQL Server jobs that are created when you install BizTalk, most of them will not successfully run when BizTalk is initially installed&lt;/li&gt;   &lt;li&gt;After installation of BizTalk (assuming you installed Enterprise Single-Sign On), make sure you backup and document your master secret&lt;/li&gt;   &lt;li&gt;Use separate Active Directory Users for each BizTalk service and Groups for BizTalk Hosts. This will keep BizTalk more secure by granted minimum access needed as well as making your BizTalk environment easier to scale out.&lt;/li&gt;   &lt;li&gt;Create separate BizTalk Hosts for each solution deployed&lt;/li&gt;   &lt;li&gt;Create separate BizTalk projects and namespaces for Orchestrations, Schemas and Pipelines&lt;/li&gt;   &lt;li&gt;Following:&lt;/li&gt;   &lt;li&gt;[CompanyName].[BusinessUnit].[ProjectName].[VSNetProjectName]&lt;br /&gt;Example:&lt;br /&gt;Microsoft.Office.HelloWorld.Orchestrations&lt;br /&gt;Microsoft.Office.HelloWorld.Pipelines&lt;br /&gt;Microsoft.Office.HelloWorld.Schemas&lt;/li&gt;   &lt;li&gt;Use Enterprise Library Configuration blocks within your Orchestrations to avoid hard coding information in them&lt;/li&gt;   &lt;li&gt;To avoid manual deployment with BizTalk, script it (using batch files) or create an MSI package to install it&lt;/li&gt;   &lt;li&gt;Use late binding for send/receive ports&lt;/li&gt;   &lt;li&gt;Name your send/receive ports after your solution’s namespace, using Pascal casing&lt;/li&gt;   &lt;li&gt;Use source code control&lt;/li&gt; &lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-112612539454689843?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/112612539454689843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=112612539454689843' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112612539454689843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112612539454689843'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/09/best-practices-biztalk-2004.html' title='Best Practices: BizTalk 2004'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-112612526221017652</id><published>2005-09-07T15:33:00.000-05:00</published><updated>2005-09-07T15:34:22.210-05:00</updated><title type='text'>Best Practices: SQL Server</title><content type='html'>&lt;ol&gt;   &lt;li&gt;Casing for SQL Server objects should be similar to that of .Net: Public members (tables, sprocs, views, columns) Pascal cased &amp;amp; Private members camel cased&lt;/li&gt;   &lt;li&gt;Use Store Procedures everywhere possible&lt;/li&gt;   &lt;li&gt;Document and model all security access to database objects that need to be granted, then write the script for this &lt;/li&gt;   &lt;li&gt;Write scripts by hand using a text editor (Query Analyzer, UltraEdit, TextPad, VisualStudio.Net) or an intelligent tool such as Erwin&lt;/li&gt;   &lt;li&gt;Avoid triggers and give much thought to how you write them if you write them as they can have bad side effects&lt;/li&gt;   &lt;li&gt;Avoid using cursors within your stored procedures as logical code such as this should normally be performed in your application (middle) tier not your database tier&lt;/li&gt;   &lt;li&gt;Use source code control&lt;/li&gt; &lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-112612526221017652?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/112612526221017652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=112612526221017652' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112612526221017652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112612526221017652'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/09/best-practices-sql-server.html' title='Best Practices: SQL Server'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-112612513165870642</id><published>2005-09-07T15:29:00.000-05:00</published><updated>2005-09-07T15:33:08.543-05:00</updated><title type='text'>Best Practices: IIS</title><content type='html'>&lt;ol&gt;   &lt;li&gt;Create entirely separate web sites for each ‘Solution’ or ‘Project’ that is deployed to your web server. Do not put all web sites beneath the ‘Default Web Site’ and ‘wwwroot’&lt;/li&gt;   &lt;li&gt;Document and then modify the NTFS permissions of your web root directories as needed by your web site&lt;/li&gt;   &lt;li&gt;Use HTTP Header to host multiple web sites on one server/environment&lt;/li&gt;   &lt;li&gt;Do not install Front Page extensions on a web server&lt;/li&gt; &lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-112612513165870642?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/112612513165870642/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=112612513165870642' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112612513165870642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112612513165870642'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/09/best-practices-iis.html' title='Best Practices: IIS'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-112567961624264892</id><published>2005-09-02T11:22:00.000-05:00</published><updated>2005-09-02T12:12:40.253-05:00</updated><title type='text'>Overloading Web Service Methods in .Net</title><content type='html'>A largely misunderstood issue in .Net web services is the capability of overloading web service methods.  Overloading web service methods is possible and very easy but it helps to have some understanding of SOAP first.&lt;br /&gt;&lt;br /&gt;If you navigate to your web service and click the link "Service Description", or just add ?WSDL onto the end of your web service within your browser, example:&lt;br /&gt;&lt;br /&gt;http://localhost/MyWebServices/WebService1.asmx?WSDL&lt;br /&gt;&lt;br /&gt;You will see the Web Service Description Layer (WSDL).  Inside your WSDL you will see your web service methods represented as operations such as:&lt;br /&gt;&lt;br /&gt;&amp;lt;wsdl:operation name="Add"&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;&amp;lt;/wsdl:operation&amp;gt;&lt;br /&gt;&lt;br /&gt;Now if you go into your Add method inside .Net and add try to overload it, the problem you have is that method names within .Net map to both operations and message elements within your WSDL and you cannot have two message names that are the same, example:&lt;br /&gt;&lt;br /&gt;&amp;lt;wsdl:message name="AddSoapIn"&amp;gt;&lt;br /&gt;&amp;lt;wsdl:message name="AddSoapIn"&amp;gt;&lt;br /&gt;&lt;br /&gt;Cannot exist twice.  The fix is simple, add a WebMethod attribute to both methods and make sure they have distinct names between them.&lt;br /&gt;&lt;br /&gt;[WebMethod(MessageName="Add_TwoNumbers")]&lt;br /&gt;public int Add(int x, int y)&lt;br /&gt;{&lt;br /&gt; return x + y;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[WebMethod(MessageName="Add_ThreeNumbers")]&lt;br /&gt;public int Add(int x, int y, int z)&lt;br /&gt;{&lt;br /&gt; return x + y + z;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Now your WSDL will have message elements with names:&lt;br /&gt;Add_TwoNumbersSoapIn&lt;br /&gt;Add_TwoNumbersSoapOut&lt;br /&gt;Add_ThreeNumbersSoapIn&lt;br /&gt;Add_ThreeNumbersSoapOut&lt;br /&gt;&lt;br /&gt;But your operations (within WSDL) will have the following:&lt;br /&gt;&amp;lt;wsdl:operation name="Add"&amp;gt;&lt;br /&gt;&amp;lt;wsdl:operation name="Add"&amp;gt;&lt;br /&gt;&lt;br /&gt;Thus when you generate your proxy class for your web service (IE: Web Reference, or WSDL.exe) then you can open your proxy class and see how it maps overloaded methods to the operations properly.&lt;br /&gt;&lt;br /&gt;While it's not necessary to rewrite the WSDL yourself, understanding how to manipulate the WSDL through attributes within your .Net web service is invaluable.&lt;br /&gt;&lt;br /&gt;See Also: &lt;a href="http://www.w3.org/TR/wsdl"&gt;WSDL spec from the W3C&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-112567961624264892?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/112567961624264892/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=112567961624264892' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112567961624264892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112567961624264892'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/09/overloading-web-service-methods-in-net.html' title='Overloading Web Service Methods in .Net'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-112249367309777996</id><published>2005-07-27T14:12:00.000-05:00</published><updated>2005-07-27T14:57:03.993-05:00</updated><title type='text'>Run NUnit Tests on Compilation</title><content type='html'>Test driven development is an approach to programming where you write your unit testing code to test for the functionality &amp; requirements first.  Then code is written to write the unit of code (class, etc).&lt;br /&gt;&lt;br /&gt;For .Net programmers, the tool of choice for unit testing is NUnit.  For more information about NUnit, see toolkit below.&lt;br /&gt;&lt;br /&gt;I recommend creating a project for your unit testing, &lt;YourNamespace&gt;.UnitTesting will suffice.  To automate the process of testing, it is helpful to have unit testing performed upon compilation, thus every time your code changes you can rerun your unit tests and not have to manually rerun NUnit.&lt;br /&gt;&lt;br /&gt;To do this, you need to run NUnit's commandline utility, located in NUnit's Program Files folder \bin.&lt;br /&gt;&lt;br /&gt;Create your testing class and methods:&lt;br /&gt;&lt;br /&gt;[TestFixture]&lt;br /&gt;Class1&lt;br /&gt;{&lt;br /&gt;[Test]&lt;br /&gt;public void Test1()&lt;br /&gt;{&lt;br /&gt;  Project1.MyUnit1 minute = new Project1.MyUnit1(); &lt;br /&gt;  Assert.AreEqual(myUnit.Add(1,2), 3);  // assert an exception if 1 + 2 &lt;&gt; 3&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Next, go to the project properties for your NUnit project, click Build Events on the left-hand side.  In the Post-build Event Command Line field paste the following:&lt;br /&gt;&lt;br /&gt;"%programfiles%\NUnit 2.2\bin\nunit-console" "$(SolutionDir)\Project1.nunit" &gt; "$(SolutionDir)\Project1.nunit.log"&lt;br /&gt;&lt;br /&gt;This assumes your .nunit file is in the root of your solution.  Variables above might need to be changed to work with your project.  Once you build this logic into your solutions, unit testing can become seamless.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-112249367309777996?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/112249367309777996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=112249367309777996' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112249367309777996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112249367309777996'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/07/run-nunit-tests-on-compilation.html' title='Run NUnit Tests on Compilation'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-112118173781384842</id><published>2005-07-12T10:13:00.000-05:00</published><updated>2005-09-07T15:52:43.903-05:00</updated><title type='text'>XSLT Date/Time &amp; Upper Case functions in .Net Framework</title><content type='html'>Due to Microsoft's lack of support for XPath 2.0, as well as their dropped support for most of the own extended fuctions, all that remain accessible now is customizable script support in XSLT, for those who need functionality outside of the scope of XSLT 1.0.&lt;br /&gt;&lt;br /&gt;To perform many useful functions such as upper case, date/time formatting, etc, you must write custom script. Below is an example of date/time formatting I'm performing within my XSLT document for a BizTalk project, although this will work for any .Net application.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;First: Add the following namespaces to your XSLT declaration&lt;/b&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;xmlns:msxsl="urn:schemas-microsoft-com:xslt"&lt;br /&gt;xmlns:user="http://www.tempuri.org/User"&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Second: Write Custom functions&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;msxsl:script implements-prefix="user" language="C#"&amp;gt;&lt;br /&gt; &amp;lt;![CDATA[&lt;br /&gt; public string FormatDate(XPathNodeIterator node, string xpathExpr, string format)&lt;br /&gt; {&lt;br /&gt;  XPathNavigator nav = node.Current;&lt;br /&gt;  if(nav.MoveToAttribute(xpathExpr, ""))&lt;br /&gt;  {&lt;br /&gt;   DateTime dt = DateTime.Parse(nav.Value);&lt;br /&gt;   return dt.ToString(format);&lt;br /&gt;  }&lt;br /&gt;  else&lt;br /&gt;  {&lt;br /&gt;   throw new ApplicationException("Cannot transform document, specified XPath expression is not valid.");&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public string ToUpper(XPathNodeIterator node, string xpathExpr)&lt;br /&gt; {&lt;br /&gt;  XPathNavigator nav = node.Current;&lt;br /&gt;  if(nav.MoveToAttribute(xpathExpr, ""))&lt;br /&gt;  {&lt;br /&gt;   string fullName = nav.Value;&lt;br /&gt;   return fullName.ToUpper();&lt;br /&gt;  }&lt;br /&gt;  else&lt;br /&gt;  {&lt;br /&gt;   throw new ApplicationException("Cannot transform document, specified XPath expression is not valid.");&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; ]]&amp;gt;&lt;br /&gt;&amp;lt;/msxsl:script&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Finally: Call your custom XSLT function, inline within your XSLT&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&amp;lt;xsl:value-of select="user:FormatDate(., 'Value', 'M/d/yyyy h:mm:ss tt')"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:value-of select="user:ToUpper(., 'Value')"/&amp;gt;&lt;br /&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-112118173781384842?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/112118173781384842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=112118173781384842' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112118173781384842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112118173781384842'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/07/xslt-datetime-upper-case-functions-in.html' title='XSLT Date/Time &amp; Upper Case functions in .Net Framework'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-112016588440992405</id><published>2005-06-30T15:48:00.000-05:00</published><updated>2005-06-30T16:11:24.413-05:00</updated><title type='text'>Test Driven Development - NUnit</title><content type='html'>NUnit Pocket Reference by Bill Hamilton, published by O'Reilly is a good overview and reference of test driven development and the usage of the &lt;a href="http://www.nunit.org/"&gt;NUnit&lt;/a&gt; tool for .Net software development.&lt;br /&gt;&lt;br /&gt;Google Print has a section of this book for free and is a good place to start learning test driven development.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-112016588440992405?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://print.google.com/print?id=PJ_xyEg3dDIC&amp;lpg=8&amp;prev=http://print.google.com/print&amp;pg=6&amp;sig=x1PIn48pL2fkO0BqhGCBuwWBD7s' title='Test Driven Development - NUnit'/><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/112016588440992405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=112016588440992405' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112016588440992405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/112016588440992405'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/06/test-driven-development-nunit.html' title='Test Driven Development - NUnit'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-111999276737731659</id><published>2005-06-28T14:49:00.000-05:00</published><updated>2005-06-29T14:36:25.393-05:00</updated><title type='text'>Scott's Toolbox - 2nd Quarter 2005</title><content type='html'>Quarterly I will begin posting a toolbox, common tools, utilities and service packs that I tend to keep downloaded and usually recommend developers to install when they get a new box.  This quarters toolbox is listed below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.altova.com/products_ide.html"&gt;Altova XML Spy&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=A8F5654F-088E-40B2-BBDB-A83353618B38&amp;displaylang=en"&gt;Microsoft .Net Framework 1.1 SP1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=f4a5ab9e-d599-4cc8-abdf-ae6ae68bac3d"&gt;Microsoft BizTalk Server 2004 SP1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=CDD47461-F4E2-4BC6-B5C2-2018AFF2823D&amp;displaylang=en"&gt;Microsoft BizTalk Server 2004 Product Documentation Refresh - 3/28/2005&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=8A1CA3AF-790C-4261-838A-9F0661C72887&amp;displaylang=en"&gt;Microsoft BizTalk Server 2004 SDK Refresh - 4/1/2004&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=78cac895-efc2-4f8e-a9e0-3a1afbd5922e&amp;displaylang=en&amp;Hash=HCCL6D8"&gt;Microsoft MDAC 2.8 SP1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=51d4a154-8e23-47d2-a033-764259cfb53b&amp;DisplayLang=en"&gt;Microsoft SqlXml 3.0 SP3&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=4A3AD088-A893-4F0B-A932-5E024E74519F&amp;displaylang=en"&gt;Microsoft XML Parser 3.0 SP5&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=3144b72b-b4f2-46da-b4b6-c5d7485f2b42&amp;displaylang=en"&gt;Microsoft XML Parser 4.0 SP2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=1ba1f631-c3e7-420a-bc1e-ef18bab66122&amp;displaylang=en"&gt;Microsoft Web Service Enhancements 2.0 (WSE) SP3&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://prdownloads.sourceforge.net/ndoc/NDoc-v1.3.1.msi?download"&gt;NDoc&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.nunit.org/download.html"&gt;NUnit 2.2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ultraedit.com"&gt;UltraEdit 11&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-111999276737731659?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/111999276737731659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=111999276737731659' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/111999276737731659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/111999276737731659'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/06/scotts-toolbox-2nd-quarter-2005.html' title='Scott&apos;s Toolbox - 2nd Quarter 2005'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-111781335807065261</id><published>2005-06-03T10:09:00.000-05:00</published><updated>2005-06-03T10:42:40.093-05:00</updated><title type='text'>Microsoft removes XQuery from .Net framework 2.0</title><content type='html'>Microsoft has unfortunately decided to remove support for XQuery (XML Query) language from the .Net Framework 2.0.  XQuery was planned to be in Microsoft's next version of the framework and was even somewhat implemented in previous beta versions.&lt;br /&gt;&lt;br /&gt;Microsoft has also chosen to not implement XSLT 2.0 standard (4.0 working draft) in .Net framework 2.0.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-111781335807065261?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://msdn.microsoft.com/XML/XQueryStatus/default.aspx' title='Microsoft removes XQuery from .Net framework 2.0'/><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/111781335807065261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=111781335807065261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/111781335807065261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/111781335807065261'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/06/microsoft-removes-xquery-from-net.html' title='Microsoft removes XQuery from .Net framework 2.0'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-111653704323118702</id><published>2005-05-19T16:06:00.000-05:00</published><updated>2005-05-19T16:10:43.236-05:00</updated><title type='text'>Mozilla: Thunderbird 1.0.2 Download &amp; Review</title><content type='html'>I downloaded and installed Mozilla Thunderbird in the past and tried it out.  It's a free, user friendly and highly tweakable Email client (replacement for Outlook Express for most of us).  I personally replaced Microsoft Outlook with it at home.&lt;br /&gt;&lt;br /&gt;Review:&lt;br /&gt;This is a very good product and will only get better.  The spam filtering is excellent, it learns very quickly and hotkeys make marking (and unmarking) spam easy.  No note taking functionality is built-in, however many great note taking extensions exist.  If you love FireFox, you will love Thunderbird.  The product is not fully mature yet, but is a good product that will continue to get better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-111653704323118702?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.mozilla.org/' title='Mozilla: Thunderbird 1.0.2 Download &amp; Review'/><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/111653704323118702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=111653704323118702' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/111653704323118702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/111653704323118702'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/05/mozilla-thunderbird-102-download.html' title='Mozilla: Thunderbird 1.0.2 Download &amp; Review'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-111653670352773597</id><published>2005-05-19T16:04:00.000-05:00</published><updated>2005-05-19T16:05:03.526-05:00</updated><title type='text'>FireFox 1.0.4</title><content type='html'>FireFox 1.0.4 has been released.  It's awesome as always, just some bug fixes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-111653670352773597?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.mozilla.org/' title='FireFox 1.0.4'/><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/111653670352773597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=111653670352773597' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/111653670352773597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/111653670352773597'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/05/firefox-104.html' title='FireFox 1.0.4'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-111653657217608987</id><published>2005-05-19T15:57:00.000-05:00</published><updated>2005-05-19T16:02:52.180-05:00</updated><title type='text'>MDAC 2.8 SP1</title><content type='html'>MDAC 2.8 SP1 has been released.  For a full list of bug fixes &amp; enhancements &lt;a href="http://support.microsoft.com/kb/899456"&gt;click here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-111653657217608987?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.microsoft.com/downloads/details.aspx?FamilyID=78cac895-efc2-4f8e-a9e0-3a1afbd5922e&amp;displaylang=en&amp;Hash=SDCRPBD' title='MDAC 2.8 SP1'/><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/111653657217608987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=111653657217608987' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/111653657217608987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/111653657217608987'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/05/mdac-28-sp1.html' title='MDAC 2.8 SP1'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-111652121271481054</id><published>2005-05-19T11:41:00.000-05:00</published><updated>2005-05-19T11:46:52.720-05:00</updated><title type='text'>SQL Server 2000 SP4</title><content type='html'>SQL Server 2000 Service Pack 4.0 has been released.  This is a recommended download as it fixes several previous bugs.  Note though you might not want to install this on your server yet, from Microsoft:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;"Microsoft has found an issue with the final build of SP4 that impacts customers who run SQL Server with AWE support enabled. This issue only impacts machines with more than 2GB of memory where AWE has been explicitly enabled. Customers with this configuration should not install SP4. Microsoft is currently working on the problem and will issue an update soon."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This should be a safe install for developers though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-111652121271481054?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.microsoft.com/downloads/details.aspx?FamilyId=8E2DFC8D-C20E-4446-99A9-B7F0213F8BC5&amp;displaylang=en' title='SQL Server 2000 SP4'/><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/111652121271481054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=111652121271481054' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/111652121271481054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/111652121271481054'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2005/05/sql-server-2000-sp4.html' title='SQL Server 2000 SP4'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-110295295877695089</id><published>2004-12-13T09:45:00.000-06:00</published><updated>2004-12-13T09:49:18.776-06:00</updated><title type='text'>Free .Net Deployment Tool - Unleash It!</title><content type='html'>Upon looking for a good cheap deployment tool, I was referred to a free and very useful deployment tool called Unleash It! (formerly WebDeploy).  It allows FTP &amp; network deployments, as well as different profiles for deployments.&lt;br /&gt;&lt;br /&gt; I've tested this out on a web service that I've written, pusing it to our DEV box and worked great and fast.  I'd highly recommend this product if your looking for a cheap, quick and easy web deployment tool.  It also integrates within Visual Studio .Net.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-110295295877695089?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eworldui.net/UnleashIt/Default.aspx' title='Free .Net Deployment Tool - Unleash It!'/><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/110295295877695089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=110295295877695089' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/110295295877695089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/110295295877695089'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2004/12/free-net-deployment-tool-unleash-it.html' title='Free .Net Deployment Tool - Unleash It!'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-110295270287557569</id><published>2004-12-13T09:40:00.000-06:00</published><updated>2004-12-13T09:45:02.876-06:00</updated><title type='text'>.Net 2005 Beta &amp; Longhorn</title><content type='html'>Over a month ago I attempted an installation of .Net 2005 Beta on a Longhorn Virtual Machine image on my laptop.    Burn, Burn Burn....&lt;br /&gt;&lt;br /&gt;That virtual machine image went down and never came back up again.  I now have a .Net 2005 Beta instance on an XP VM and I will have a review shortly.&lt;br /&gt;&lt;br /&gt;Just an FYI for those considering putting the two on the same image.... I would recommend against it.&lt;br /&gt;&lt;br /&gt;Happy trails!&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-110295270287557569?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/110295270287557569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=110295270287557569' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/110295270287557569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/110295270287557569'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2004/12/net-2005-beta-longhorn.html' title='.Net 2005 Beta &amp; Longhorn'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-109845766490268102</id><published>2004-09-16T09:52:00.000-05:00</published><updated>2004-10-22T10:11:23.813-05:00</updated><title type='text'>FireFox Preview Release 1.0</title><content type='html'>FireFox (next generation verison of Mozilla) has been released...well sorta. A Preview Release has been published, which is something between Release Candidate and RTM. Oh well.&lt;br /&gt;&lt;br /&gt;Anyway, my review in this product is that it is an Excellent browser. In almost ever fashion it is better than Internet Explorer 6.0. The internal pop-up blocker for FireFox actually works all the time, whereas Internet Explorer's conveniently doesn't work, at places like MSN.&lt;br /&gt;&lt;br /&gt;FireFox also starts up very fast and loads web pages faster than IE. It also keeps track of your downloads in case you ever forget where you downloaded stuff to.&lt;br /&gt;&lt;br /&gt;Another great feature of this browser is the capability of "Extensions". These work like Internet Explorer add-ins do, except there is a more existent community programming Extension for FireFox than add-ins for IE. There are many downloadable add-ins for FireFox, among them are: AdBlocking software, Image zooming, Web Develeoper extensions and much more.&lt;br /&gt;&lt;br /&gt;Of course, you'll still need to use Internet Explorer for many websites that either don't run well in FireFox or use ActiveX Controls, however FireFox is a great browser and worth the download.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-109845766490268102?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.mozilla.org/products/firefox/' title='FireFox Preview Release 1.0'/><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/109845766490268102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=109845766490268102' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/109845766490268102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/109845766490268102'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2004/09/firefox-preview-release-10.html' title='FireFox Preview Release 1.0'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-109327191470130725</id><published>2004-08-23T09:00:00.000-05:00</published><updated>2004-08-23T14:56:56.076-05:00</updated><title type='text'>Windows XP SP2 </title><content type='html'>Well after downloading Windows XP SP2 a couple of weeks back and burning it, I've finally had a chance to install and review this major update for Windows XP. First the size is very large so if you plan on downloading it you better have broadband since it weighs in at almost 500 MB (or under 300MB compressed).&lt;br /&gt;&lt;br /&gt;You can download this service pack from MSDN if you have an MSDN subscription, otherwise Microsoft &lt;span style="font-style: italic;"&gt;prefers&lt;/span&gt; that you use Windows Update to install this or you can download this at Microsoft.com &lt;a href="http://www.download.com/Windows-XP-Service-Pack-2/3000-2098-10308947.html?tag=lst-0-1"&gt;&lt;/a&gt;(&lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=049C9DBE-3B8E-4F30-8245-9E368D3CDB5A"&gt;Click Here&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Personally for me the installation went very smooth. The largest improvement this service pack provides is an enhanced client firewall. I really like this feature and recommend leaving it on even if you have a hardware firewall. The next biggest improvement is for Internet Explorer and it now contains a pop-up blocker, FINALLY!!!&lt;br /&gt;&lt;br /&gt;Some people have reported problems however and had to reinstall Windows entirely so I'd backup you first, although admittedly I didn't.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-109327191470130725?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/109327191470130725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=109327191470130725' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/109327191470130725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/109327191470130725'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2004/08/windows-xp-sp2.html' title='Windows XP SP2 '/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-109225992958331690</id><published>2004-08-11T16:25:00.000-05:00</published><updated>2004-10-27T13:05:29.063-05:00</updated><title type='text'>BugTracker Status Aug '04</title><content type='html'>Progress is going well on BugTracker. Base security for it is written, 90% of the database complete. Much web GUI still needs to be fleshed out however, I still need graphics. I have finished writing a basic cascading stylesheet for the system though.&lt;br /&gt;&lt;br /&gt;Only major issue I've faced is a Cookie-Session based problem. PHP isn't storing my state how I want it to and I believe it has to do with the lifecycle of a PHP script and thus my Cookie-Headers are not being passed to the client, thus session id not being stored. I feel I am close to a resolution on this issue.&lt;br /&gt;&lt;br /&gt;Email me if you'd like to help me on this project.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-109225992958331690?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/109225992958331690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=109225992958331690' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/109225992958331690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/109225992958331690'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2004/08/bugtracker-status-aug-04.html' title='BugTracker Status Aug &apos;04'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-109226071314287154</id><published>2004-08-04T16:36:00.000-05:00</published><updated>2004-08-11T16:46:26.563-05:00</updated><title type='text'>PHP 5.0 Released</title><content type='html'>Major PHP release is final.... so.... what's the verdict? I don't know. Doesn't work on Windows yet. Although setup and compressed archives are available for PHP 5.0, I encountered several parsing problems, particularly with the PEAR &amp;amp; PEAR DB libraries that I use.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;FYI: PEAR DB is a PHP database abstraction layer. &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;I'll wait for a fix for PHP 5.0 or a version of PEAR that works with the new version before I test drive the new engine.&lt;br /&gt;&lt;br /&gt;Among the new features on PHP 5.0 are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Zend Engine II with a new object model and dozens of new features&lt;/li&gt;&lt;li&gt;XML support has been rewritten&lt;/li&gt;&lt;li&gt;New SimpleXml extensions&lt;/li&gt;&lt;li&gt;New built-in SOAP extensions (for interop with web services)&lt;/li&gt;&lt;li&gt;New MySql extensions&lt;/li&gt;&lt;li&gt;SQLite is bundled with this version of PHP&lt;/li&gt;&lt;li&gt;Improvements to streams&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;and reportedly more...&lt;/p&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-109226071314287154?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/109226071314287154/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=109226071314287154' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/109226071314287154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/109226071314287154'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2004/08/php-50-released.html' title='PHP 5.0 Released'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-109225937249245943</id><published>2004-07-15T16:20:00.000-05:00</published><updated>2004-08-11T16:23:41.760-05:00</updated><title type='text'>BugTracker in Development</title><content type='html'>I'm presently working on a BugTracking tool that I began working on here in July. I'm writing it in PHP with a MySql backend. All is going well with both technologies, I think PHP &amp;amp; MySql is a good fit for a BugTracking tool. Both technologies are truely multiplatform and free.&lt;br /&gt;&lt;br /&gt;I'll post updates of my progress in the future. I need some help in the graphics area if your interested in helping me feel free to email me.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-109225937249245943?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/109225937249245943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=109225937249245943' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/109225937249245943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/109225937249245943'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2004/07/bugtracker-in-development.html' title='BugTracker in Development'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-108929724183806089</id><published>2004-07-08T09:16:00.000-05:00</published><updated>2004-08-11T16:35:14.080-05:00</updated><title type='text'>Microsoft Programmer's Toolkit (July '04)</title><content type='html'>Monthly I'd like to post links to download all the latest tools a Microsoft programmer will need to do their job. I'll link to updates of common tools and utilities as they come out.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.blogger.com/app/"&gt;.NET Framework SDK&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.blogger.com/app/"&gt;.NET Framework SDK SP2&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.blogger.com/app/"&gt;Jet 4.0 SP3&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.blogger.com/app/"&gt;MDAC 2.8&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.blogger.com/app/"&gt;MS XML Core Service 4.0 SP2&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.blogger.com/app/"&gt;SQL Server 2000 SP3&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-108929724183806089?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/108929724183806089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=108929724183806089' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/108929724183806089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/108929724183806089'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2004/07/microsoft-programmers-toolkit-july-04.html' title='Microsoft Programmer&apos;s Toolkit (July &apos;04)'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-108929593255908662</id><published>2004-07-08T08:51:00.000-05:00</published><updated>2004-07-08T09:13:41.016-05:00</updated><title type='text'>Good MSDN Article: Integrating Analysis Services with Reporting Services</title><content type='html'>Sean Boon has written a good article explaining how to use Microsoft's SQL Server Reporting Services to report on data within SQL Servers Analysis Service (Microsoft's OLAP solution).  He also has written a helpful example which is a Reporting Services project that consumes the data in the Analysis Service example Foodmart, which is installed with Analysis Services by default.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-108929593255908662?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://msdn.microsoft.com/sql/default.aspx?pull=/library/en-us/dnsql2k/html/olapasandrs.asp' title='Good MSDN Article: Integrating Analysis Services with Reporting Services'/><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/108929593255908662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=108929593255908662' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/108929593255908662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/108929593255908662'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2004/07/good-msdn-article-integrating-analysis.html' title='Good MSDN Article: Integrating Analysis Services with Reporting Services'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7455565.post-108836862131129664</id><published>2004-06-27T15:35:00.000-05:00</published><updated>2004-06-27T15:37:01.310-05:00</updated><title type='text'>Blog Now open</title><content type='html'>No need to hold thou breath any longer.  My Blog is now open, I will be sure to fill it all sorts of knowledge and ideas as time goes on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7455565-108836862131129664?l=scottwhite.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scottwhite.blogspot.com/feeds/108836862131129664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7455565&amp;postID=108836862131129664' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/108836862131129664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7455565/posts/default/108836862131129664'/><link rel='alternate' type='text/html' href='http://scottwhite.blogspot.com/2004/06/blog-now-open.html' title='Blog Now open'/><author><name>Scott White</name><uri>http://www.blogger.com/profile/15458997690728285402</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/-oP0XKnSP8wU/TrWHrjzGPgI/AAAAAAAAAG4/8TIWzTTJKCM/s220/Scott-Cacti-Square.jpg'/></author><thr:total>0</thr:total></entry></feed>
