Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Sergio Pereira

There are no half-solutions because there isn't half a problem

June 2008 - Posts

  • Smaller Lies

    Mentoring is something that is in my DNA. When I was in college I remember not just trying to learn what the teacher was presenting, but I'd also pay attention to how the teachers conducted their lectures. In some cases I'd think to myself that if I were at the podium, I'd present this subject differently.

    I have never formally taught any class (although that is definitely in my list of things to do one day) but now I frequently find myself serving as a mentor to a less senior developer or a new team mate. It's not the same thing, but it has enough in common with teaching to make my college memories useful.

    Back to my college days, in that brain-draining BSEE curriculum, one of the clearest demonstrations of teaching skills was given to me in a way that I will never forget.

    One of those semesters I was attending the Cryptography class and I just couldn't stand the way the teacher was presenting her material. Incredibly boring projector presentations, mostly reading from them and making no effort to keep the class awake. After I got my horrible results in the first round of exams, I was considering getting out of that class and coming back next semester. People kept telling me to not do that because the new teacher for the next semester was rumored to be tough and very serious about his classes.

    After a little hesitation, I decided to get out of that class and I was back in the following semester, new teacher and all. That was the best decision I made in the entire course.

    Mr. Campello was the best teacher I ever had. That guy had passion for Electrical Engineering, Cryptography, and for teaching.

    Differently from the previous semester, his classes were packed. Students would not want to miss a second of each class. He would deliver never ending nuggets of wisdom, incredible stories about how cryptography has been important throughout history. War stories. Ancient history. You name it. They guy knew it all. Cryptography became one of my favorite subjects, even though it's mostly advanced discrete arithmetic, which is as boring as it gets.

    During one of those classes Mr. Campello dropped a monster bomb of a quote. I don't know if that quote is his original, or if he was quoting somebody else. I don't even remember the context in which this quote came about. He said:

    "Teaching is like telling a smaller lie everyday"

    I won't bother explaining the power of that statement. I'll leave for your own analysis. I don't think there's any other thing that somebody told me that had similar impact that this quote.

    Replace teaching with mentoring, parenting, modeling, etc and you've got yourself a lot to think about.

  • Beginning Continuous Improvement, A Case Study

    by: Glenn Goodrich

    This post is the winner of The Great Devlicio.us Giveaway.

    The story you are about to read is true. The names and identities of the innocent have been changed to protect them and my job. No animals were harmed in the writing of this story.

    Roughly three to five years ago I was an intermediate ASP.NET Webforms developer. I had produced several applications for various clients that were in different stages of test/production/maintenance /graveyard. Some of these applications were loved by my clients, others were tolerated, and still others were abhorred. The aspects all of these applications did have in common were a high level of difficulty to maintain and an almost violent resistance to change. Most of my clients tend to generate requirements in a management bubble so during the first round of testing, (if it existed) or the first weeks stumbling through production deployment, the user feedback was very large. Of course, the client always desired make changes accommodating this feedback, which is often where my real troubles began.

    There had to be a better way. So, I started combing the web, hoping to find people that solved issues like mine. Googling phrases like “extensibility”, “webforms pain”, and “easy asp.net deployment”. If memory serves, the first fish on the line was Rails. I did the Rails “Hello World” and was amazed at how fast you could get going, how easy you could add views, and how much of my nerd life I had wasted. Realizing that my clients were not quite ready for Rails (“Ruby on what??? Where’s the msi?”) I started looking for MVC in .NET. This, as you’ve probably guessed, landed me at the Castle Project. Monorail was just what I needed. I could shoehorn it past my clients’ open source/never-heard-of-that worries, because it was .NET. But this was just the beginning.

    The Castle Project also had the Windsor Inversion of Control (IoC) container, which led me to things like “separation of concerns”, “single responsibility”, and the “open-closed principle”. It really started me down the path of Test Driven Development (TDD) which was probably the single biggest positive change to my coding practices. It was a little bumpy at first, but once I saw that I could get all my code working before I even had a web site application AND I could really test it, I was hooked.

    I started reading the Castle Forums as well as Hammet’s blog and Ayende’s blog. Figuring they weren’t the only really smart people out there, I started reading tons of blogs (CodeBetter, Martin Fowler’s Bliki, etc.) which showed me the endless world of better design practices. I started reading books that weren’t from Microsoft Press (nothing against them, but there are a lot of good books out there) including Head First Design Patterns, which was another huge A-HA! moment for my development career. I now read blogs everyday and have at least two books going at any moment in time. I read about Continuous Integration and CI Factory, as well as NHibernate and other OR/M frameworks. This was my first steps into Continuous Improvement.

    So, where is this going? Is there a success story in our future? Before you object to the relevance of my opening statement, we have finally arrived at my success. We were handed a very large client from a business partner, partially because that partner could not satisfy the needs of the client. The client (who I will call BigCo) wanted a web-based application to put in front of their customer-facing employees to, basically, figure out if BigCo could provide any services to new clients. There were various factors that affected BigCo’s ability to provide services to a given customer, and the application would have to perform the logic that determined each of these factors. For this article, we will call the application ProviderApp. ProviderApp had to do the following:

    Collect information about the customer. Find out where the customer lived. See if BigCo had the ability to provide services to that location. If the location was good, show the employee which of BigCo’s services were available. Persist the results of this interaction.

    So, BigCo wanted a prototype. Tapping into my new approach and knowledge, I started writing tests for my (persistent ignorant!) domain model. Customer, Address, ProviderResult, and other classes were the result. All clean and responsible only for themselves and fully tested. I used separation of concerns to partition out the factors into services, being sure to use interfaces. These services were also open for extension, but closed for modification. In fact, for testing, I actually wrote test-only providers, removing the need to invoke some needed external services that would be used in production. I had all the logic for the factors written and tested, all the domain model designed and tested before I had even created a web application. Also, thanks to CI, I knew when the build was broken immediately, so bugs didn’t have a chance to get stale, causing me to have to hunt for hours or days because I didn’t know when the bug was introduced. By the time I got around to the user interface (the web application) it was simply a matter of writing my views and consuming my services. Oh, and the act of writing pure HTML views was a breath of fresh air.

    I finished the prototype a couple of days early, so we had to time to actually perform real user tests, which I don’t think I had ever seen before. The bugs found here were relatively small but made a big difference in our demonstration of the prototype. On demo day, BigCo was very happy with the prototype. They were not wowed, they were not dazzled. Their reaction is not the success story. The success story comes from the fact that I was relaxed on demo day, confident the software was solid. I had no anxiety about getting off the beaten path, which was new for me. In fact, I let the BigCo folks drive the application at the end of the meeting and told them to show it to whomever they liked later. There is no way I would have been confident enough in my previous life to let a client demo my “prototype” code.

    At the end of the meeting, the BigCo people asked me how long it would take to “make this real”, which is when my success story really sunk in. I realized, right there in front of them, that the application was done. My answer was a matter of days, as I did have to write new providers for a couple of the services, since they were using different back-ends then the prototype, but that was it. They also asked about some changes, a question that would have usually caused my ulcer to start. Each of their requests was a trivial change, taking me a few minutes to incorporate.

    I remember walking out of that meeting realizing I had taken a huge step in my career. We are still doing a lot of work with BigCo, and they are a happy client. I no longer fear change, and am still continuously improving.

    Well, I didn’t mention DDD, because I haven’t gotten to it yet (it’s on the list, which seems to get longer all the time) but I hope you’ll consider my contribution. Either way, I had a lot of fun writing this.

  • Giveaway result

    We've just finished tallying up our votes for the Great Devlicio.us Giveaway and we are pleased to announce that the winner is Glenn Goodrich. We had enough entries to make the contest worthwhile and we decided to give prizes for every story. Everyone got one of the books in the original list and the 2nd place also got Visual Studio Team System. You see? I told you that you should tell us your story.

    Some people asked if there will be a contest where they could submit horror stories instead of success stories. Well, I'm considering running a contest for that, but I'm afraid the prize will be limited to a bag of Doritos.

    Glenn runs a very nice blog and his story, which will be posted here tomorrow, shows that the quest for a better way to develop applications or, in broader terms, the constant pursuit of improvement should be in our DNA.

    I'll quote from his story:

    ... Head First Design Patterns, which was another huge A-HA! moment for my development career. I now read blogs everyday and have at least two books going at any moment in time. I read about Continuous Integration and CI Factory, as well as NHibernate and other OR/M frameworks. This was my first steps into Continuous Improvement.
    ...I was relaxed on demo day, confident the software was solid. I had no anxiety about getting off the beaten path, which was new for me.

    Congratulations to Glenn, we are very happy that the prizes are being given to such deserving hands. You make us proud, Glenn.

    Be sure to check back tomorrow with the full story.

  • Maintainable by whom

    Let's say you are hired to help build or fix an application. You contract is not for hire and you know that after 3, 6 or 12 months you will be gone to repeat the same cycle elsewhere.

    I'm sure we have all seen contractors that will do just about anything to complete the task in the allotted time span, sometimes in detriment of the code quality and maintainability. I'm also sure that if you're reading this then you probably care about this enough to avoid replicating this pattern.

    But here are some important things that might go unnoticed in the above paragraph.

    • Define The Task
    • Define Quality
    • Define Maintainability

    The Task

    In my limited experience, I'd say it would be shocking to be hired to just write code regardless of any parameters, as long as the deadline is met. I don't expect to hear from my client "I don't care if what you write is absolute garbage material but it needs to go live in 6 months."

    Even if the client is very much driven by the deadline, even if the client doesn't say it out loud, there will always be an implicit expectation that our solution will have a minimum of quality to survive the planned life time.

    Our task is never to just write code. They could have hired a high school intern if that's all they wanted.

    Quality

    I think the quality of a software product is directly related to how well the product adheres to the specifications. Oh, no, specifications. One more thing to consider.

    If we're lucky the specifications will be available and include not only the product feature list but also architectural needs, expected maintenance and upgrade pains.

    Again, we are not being given carte blanche, even if it sounds like we are. Maybe the client doesn't know how to communicate that to us, but we ought to know that our design needs to accommodate changes and lay on top of a maintainable platform.

    Maintainability

    The ease with which a software system or component can be modified to correct faults, improve performance, or other attributes, or adapt to a changed environment - IEEE Standard Computer Dictionary

    The IEEE definition above is fine but, after a discussion in the last Chicago ALT.NET meeting, there seems to be an important omission here and the main reason for this post.

    Maintainable by whom?

    The same way our proverbial consultant from the beginning of the post could deliver abominably graded solutions and run away, so can we — with all our shiny, fancy-pants design and tools.

    We have the responsibility of designing a solution that is maintainable by the client with their staff of with realistic chances of finding other contractors that can take it on (not necessarily us all the time.)

    We have to weight our design decisions and desire to apply the better tools and architecture against the existing scenario. When discussing the possible solutions with the rest of the team that's a good opportunity to assess what kind of team we have to work with (or work for.) If the scenario doesn't look good, there at least two things that can be done:

    1. Discuss the problem with the client and suggest that the staff would benefit from some training or mentoring, so that we can apply a solution that can be maintained more effectively. Training and mentoring may be strong words, sometimes a few informal sessions with the team can go a long way.
    2. If the above is not possible, then the responsible thing to do is choosing a design that the existing team will be comfortable maintaining after our departure. Knowing when to suppress your good intentions is also an important quality of a good consultant, I think.

    That's not to say that we should give up trying to raise maintainability bar of our application designs. The rising tide can lift most boats but careful with the over-dimensioned anchors.

  • Reminder: Giveaway deadline this Friday

    If you have an interesting story and did not submit yet, please submit it ASAP because we will only wait until Friday afternoon.

    How often you have a chance to put your hands on such nice prizes? Let me share a little secret, your odds are good, we have received less than 10 submissions so far.

  • UdtTypeName and .NET data types in SQL

    We are working on SQL 2008 for a new project with the intent to leverage the new data types, in this case especially the HIERARCHYID data type. One of the stored procedures we created had a parameter of type HIERARCHYID.

    The code that calls the stored procedure was something like this.

    SqlHierarchyId nodeValue = GetNodeValueFromSomewhere();
    var cmd =new SqlCommand("usp_EnableNode");
    cmd.CommandType = CommandType.StoredProcedure;
    var  nodeParam = myCommand.Parameters.Add("@Node", SqlDbType.SqlHierarchyId);
    nodeParam.Value = nodeValue; 
    var enableParam = myCommand.Parameters.Add("@Enable",  SqlDbType.SqlBit);
    enableParam.Value = true;
    cmd.ExecuteNonQuery();

    When running this code we were getting the error "UdtTypeName property must be set for UDT parameters." Since the HIERARCHYID data type is a .NET type in SQL 2008 and we had not played with .NET types in SQL 2005 yet, we scratched our heads for a few minutes.

    We tried both:

    nodeParam.UdtTypeName = typeof(SqlHierarchyId).Name; 

    And

    nodeParam.UdtTypeName = typeof(SqlHierarchyId).FullName; 

    But the solution was much simpler:

    nodeParam.UdtTypeName = "HierarchyId";

    This should be needed for the new GEOMETRY and GEOGRAPHY data types as well. Maybe this helps someone else.

  • Excel is the business format, automate it

    One thing I realized when working in large companies is that Excel is the true data exchange file format. That what the business types exchange among themselves and how they like to persist any kind of lists or anything that needs to be formatted like a table (be it tabular data or not.)

    All too often one of this documents is forwarded to me containing some form of business data that will become all sorts of things: lookup data, configuration values, updates to an existing table, etc.

    I dread these conversion tasks when I have to do them manually so I tend to automate the task as soon as it smells like a candidate for recurrence. That way I'll take a hit on the first time and reap the benefits from then on.

    For some reason I like writing these automation scripts in Ruby. I could probably almost as easily write them in VBScript, C#, PowerShell or even VBA but my experience with Ruby is that it tends to be shorter (as in more concise) and easier to develop. Of course that varies with your level of familiarity with the Ruby libraries, but the learning curve isn't bad at all.

    Consider the following hypothetical layout for an Excel file dropped in your inbox for import.

    DescriptionPriceCategory
    1DVD Player76.49Electronics
    2Rain Coat35.10Men's apparel
    3Code Complete49.99Books
    ............
    12024" Monitor499.99Computer Accessories

    My typical script to process such file would be the obvious line-by-line read, maybe processing each cell before ultimately converting the row to its final format (or skipping that row.) The skeleton of that kind of script is shown below.

    require 'win32ole'
    
    begin 
      excel_app = WIN32OLE.new('Excel.Application')
      book = excel_app.Workbooks.Open("c:\\project\\data\\datafile.xls")
      sheet = book.Worksheets(1)
      #first row contains only the headers
      row = 2 #start at the 2nd line (excel is 1-based)
    
      #stop when we find an empty row
      while sheet.Cells(row, 1).Value
        data = []
        (1..4).each {|c| data[c] = sheet.Cells(row, c).Value }
        #at this point the 'data' array contains the entire row
        #use it as desired *********
        
        row += 1
      end
      
    rescue 
      #oops...
      puts "There was an error: #{$!}"
    ensure
      #cleanup
      excel_app.DisplayAlerts = 0
      book.Close if book
      excel_app.Quit
    end

    But, no matter if you use Ruby or any other language, the value in automating these tasks can be tremendous. Taking the time to learn the basics of Excel automation is, in my opinion, very important and will let your users continue to use the tool that they like.

    In a kind of reverse example, I have had occasions when one of the business users was repeatedly requesting for some of the data in Excel format during the application development (while we didn't have a web page to show that data yet) so, after he asked for a updated report for the second time, I created a script to read the data from the database, create an Excel file, and send the file attached in an email message every Monday morning. Easy way to gain a happy user.

    Update: As noted in the comments, one nice reference for automating with Ruby is Ruby on Windows
  • The Great Devlicio.us Giveaway

    Because there's more than one kind of hero

    Update: The contest is now closed. We cannot accept any more entries. Wait for the winner announcement is a few days. Thanks for all the great submissions.

    Here's your chance to win a well-deserved prize for being a good developer — and not just any prize. Devlicio.us, with the generous support from Microsoft (via Somasegar) and Addison-Wesley, is proud to present you with a contest that will dump a truckload of goodness at your doorstep. This ultimate prize package contains the following items.

    1. Agile Principles, Patterns, and Practices in C#: Uncle Bob's must-have work. This book needs to be part of your Agile and OOD bookshelf.
    2. Domain-Driven Design: Tackling Complexity in the Heart of Software: Eric Evans describes DDD and how your software design can benefit from it.
    3. Applying Domain-Driven Design and Patterns: Armed with the DDD knowlegde, now it's time to let Jimmy Nilsson show us how to implement solid .NET code.
    4. Patterns of Enterprise Application Architecture: In this classic, Martin Fowler lays down the law on how an enterprise application needs to be designed.
    5. Working Effectively with Legacy Code: We've all been there. It's hard and Michael Feathers does a great job in guiding us through the challenges and techniques to get you out of the quicksand.
    6. Implementing Lean Software Development: This book by Tom and Mary Poppendieck distills practices to optimize the development process.
    7. The Pragmatic Programmer: From Journeyman to Master: No list of this caliber would be complete without Andy Hunt and Dave Thomas' ultimate guide to developer proficiency.
    8. Visual Studio 2008 Team Suite + MSDN Premium: No need for explanations here. A $10K+ retail value item with all you'll ever need in terms of Microsoft technology.



    The Contest

    I hope the prizes got you excited. I actually envy you because I cannot participate. The contest is pretty simple.

    1. We are looking for success stories. Submit a true story that happened to you or your team where adopting good software development practices rescued a project or even the entire organization. The stories we want to award are the ones that demonstrate a direct relation between good practices or good design (or both) and successful solutions. Examples:
      • Continuous Integration saved my job.
      • DDD made my application survive the test of time.
      • My team went from grumpy to engaged after we introduced collective design ownership.
      • etc...
    2. Submit your stories by email or using the Contact link to any of the Devlicio.us bloggers between today (June 5th 2008) and ~2 weeks from today (June 20th 2008 by 5 PM ET GMT-4:00).
    3. The winner will be chosen by voting among the Devlicio.us bloggers. This might take up to 1 week.
    4. The winner story will be announced on Devlicio.us on or before June 20th and it will become a guest blog post on the blog to which it was submitted (so remember to protect the innocent in your story.)
    5. Shortly after that, the winner will be contacted for mailing address information and the prize will be shipped.
    6. Other stories might be selected to feature as blog posts as well - with or without any prizes.

    Restrictions

    The stories need to be of your own personal experience, within your team or your organization. Since the story has a chance of being posted in Devlicio.us, make sure the people and organizations mentioned in the story are OK with that or replace their names.

    We think we can ship the prize anywhere but if you're not in the U.S. and there's some form of export or import regulation that prohibits the shipment of software or even the books, then we may not be able to send it to you.

    Get to the writing already

    We are anxious to hear your stories. Prizes like these don't come by often and we really want to reward someone for doing the right thing.

  • Chicago ALT.NET Meeting on June 11th

    The Chicago ALT.NET crowd will be meeting on June 11th. This time we have a new location with the space graciously offered by ThoughtWorks. You can register and get more information about the event at the link below.

    If you haven't been to one of our meetings yet, you should know that this is not your average user group meeting. The talks are not formal presentations and there's a lot of participation from the attendance. Bring your questions and, most importantly, your opinions.

    After the talk, you're welcome to stick around and socialize at a nearby restaurant. Food and drinks make for great fuel for more tech and non-tech talk.

    Resharper versus CodeRush

    6:00 pm
    Pizza and networking time

    6:30 pm
    Join us and watch while Ryan Rinaldi and Adam Tybor demonstrate how those invaluable addins can boost your productivity and help you write better code in Visual Studio.

    After the demo let's open the floor for discussions on a topic to be determined in typical Open Spaces style

  • Coding style per project

    A few months ago, when I installed Visual Studio 2008 on my system, I opened one of my projects, did the usual project conversion, edited some files, created a few others, saved, tested, and checked in source control. Another developer working on the same project, also with VS2008, later edited some of the same files I had edited.

    Then I went to do a diff to verify the changes and I saw what I always hate to see. He hadn't changed a lot of code, but he was using different style settings in VS and all the extra spaces around ifs, function arguments, etc were making it harder to find the important changes. To be fair, I was the one that forgot to adjust my default settings to be more compatible with our current coding style.

    The situation above is not all that critical, but is certainly a big annoyance. Some diff programs will allow you to ignore white space differences but it is still sickening to see your source code with mixed code formatting style in the same file, sometimes in the same method.

    That kept me thinking: why aren't code format style settings part of the project? Imagine if you work for two different clients, with different standards, or that you are a contributor to Open Source projects that also have different opinions about code format. It's too easy to forget to adjust your settings every time you switch projects, even if you export and save the appropriate VS settings to import as needed. Any IDE with so many options as VS should offer an option to save any settings that deal with the actual code be part of the project. A developer should be able to explicitly ignore or change the project settings but not by default.

    With that problem in mind, I thought it would be useful to just adopt the practice of exporting the VS settings that are relevant to the project coding style and checking that in source control too. Here's what I did.

    Fire up the the Import and Export settings wizard and choose only the settings that relate to code formatting and for the languages the project uses, for example C#, HTML, and XML. In this case we will just do the C# settings.

     

    Right here we hit a limitation in VS. There's no way to select only the code formatting settings for C#, so we will export all of them anyway. Once we do that, save the file to the project directory (like MyProject.vssettings) and add it to the project or solution. Open it in VS (it's just XML) an stare at the plethora of settings that are saved.

    <UserSettings>
    	  <ApplicationIdentity version="9.0"/>
    	  <ToolsOptions>
    	    <ToolsOptionsCategory name="TextEditor"
    	    RegisteredName="TextEditor">
    	      <ToolsOptionsSubCategory name="CSharp"
    	    RegisteredName="CSharp" PackageName="Text Management Package">
    	        <PropertyValue name="TabSize">4</PropertyValue>
    	        <PropertyValue name="AutoListMembers">true</PropertyValue>
    	        <!-- ...(snip)... -->
    	        <PropertyValue name="AutoListParams">true</PropertyValue>
    	      </ToolsOptionsSubCategory>
    	      <ToolsOptionsSubCategory name="CSharp-Specific"
    	    RegisteredName="CSharp-Specific"
    	    PackageName="Visual C# Language Service Package">
    	        <PropertyValue name="NewLines_QueryExpression_EachClause">1</PropertyValue>
    	        <PropertyValue name="Space_Normalize">0</PropertyValue>
    	        <PropertyValue name="WarnWhenMembersCauseCompilerGeneratedReferences">1</PropertyValue>
    	        <PropertyValue name="CollapseInactiveBlocksOnOpen">1</PropertyValue>
    	        <PropertyValue name="Watson_MaxExceptionsToReport">1</PropertyValue>
    	        <PropertyValue name="EditAndContinueReportEnterBreakStateFailure">1</PropertyValue>
    	        <!-- ...(snip)... -->
    	        <PropertyValue name="RemoveUnusedUsings">1</PropertyValue>
    	        <PropertyValue name="Rename_Overloads">0</PropertyValue>
    	        <PropertyValue name="EncapsulateField_SearchInComments">0</PropertyValue>
    	        <PropertyValue name="ProgressDialogDelaySeconds">2</PropertyValue>
    	      </ToolsOptionsSubCategory>
    	    </ToolsOptionsCategory>
    	  </ToolsOptions>
    	</UserSettings>

    Upon closer inspection, we can more or less recognize each settings by their names. Let's remove the ones that don't seem to be related to code formatting. This is more or less a value judgment on the importance of some of the settings. My choice was to keep TabSize, IndentStyle, and InsertTabs in the first subcategory and, for the second subcategory, I'm keeping any of the setting whose name starts with NewLines_, Indent_, or Space_ and also the item named SortUsings.(I should probably just write a macro to do that at some point)

    After all this sanitizing, my settings file is reduced to the following:

    <UserSettings>
    	  <ApplicationIdentity version="9.0"/>
    	  <ToolsOptions>
    	    <ToolsOptionsCategory name="TextEditor"
    	    RegisteredName="TextEditor">
    	      <ToolsOptionsSubCategory name="CSharp"
    	    RegisteredName="CSharp" PackageName="Text Management Package">
    	        <PropertyValue name="TabSize">4</PropertyValue>
    	        <PropertyValue name="IndentStyle">2</PropertyValue>
    	        <PropertyValue name="InsertTabs">true</PropertyValue>
    	      </ToolsOptionsSubCategory>
    	      <ToolsOptionsSubCategory name="CSharp-Specific"
    	    RegisteredName="CSharp-Specific"
    	    PackageName="Visual C# Language Service Package">
    	        <PropertyValue name="NewLines_QueryExpression_EachClause">1</PropertyValue>
    	        <PropertyValue name="Space_Normalize">0</PropertyValue>
    	        <PropertyValue name="Space_AroundBinaryOperator">1</PropertyValue>
    	        <PropertyValue name="NewLines_Braces_Method">1</PropertyValue>
    	        <PropertyValue name="Indent_CaseLabels">1</PropertyValue>
    	        <PropertyValue name="NewLines_Braces_ControlFlow">1</PropertyValue>
    	        <PropertyValue name="NewLines_Braces_AnonymousMethod">1</PropertyValue>
    	        <PropertyValue name="Space_WithinOtherParentheses">0</PropertyValue>
    	        <PropertyValue name="Space_AfterBasesColon">1</PropertyValue>
    	        <PropertyValue name="Indent_Braces">0</PropertyValue>
    	        <PropertyValue name="Space_WithinMethodCallParentheses">0</PropertyValue>
    	        <PropertyValue name="Space_AfterCast">0</PropertyValue>
    	        <PropertyValue name="NewLines_Braces_CollectionInitializer">0</PropertyValue>
    	        <PropertyValue name="NewLines_AnonymousTypeInitializer_EachMember">1</PropertyValue>
    	        <PropertyValue name="NewLines_Keywords_Catch">1</PropertyValue>
    	        <PropertyValue name="NewLines_Braces_ObjectInitializer">1</PropertyValue>
    	        <PropertyValue name="NewLines_Braces_ArrayInitializer">0</PropertyValue>
    	        <PropertyValue name="Space_WithinExpressionParentheses">0</PropertyValue>
    	        <PropertyValue name="Space_InControlFlowConstruct">0</PropertyValue>
    	        <PropertyValue name="Space_BetweenEmptyMethodDeclarationParentheses">0</PropertyValue>
    	        <PropertyValue name="Indent_UnindentLabels">1</PropertyValue>
    	        <PropertyValue name="SortUsings">1</PropertyValue>
    	        <PropertyValue name="NewLines_ObjectInitializer_EachMember">1</PropertyValue>
    	        <PropertyValue name="Space_WithinMethodDeclarationParentheses">0</PropertyValue>
    	        <PropertyValue name="Space_BetweenEmptyMethodCallParentheses">0</PropertyValue>
    	        <PropertyValue name="Space_BeforeSemicolonsInForStatement">0</PropertyValue>
    	        <PropertyValue name="Space_BeforeComma">0</PropertyValue>
    	        <PropertyValue name="Space_AfterMethodCallName">0</PropertyValue>
    	        <PropertyValue name="Space_AfterComma">1</PropertyValue>
    	        <PropertyValue name="Space_BeforeBasesColon">1</PropertyValue>
    	        <PropertyValue name="Space_AfterMethodDeclarationName">0</PropertyValue>
    	        <PropertyValue name="Space_AfterDot">0</PropertyValue>
    	        <PropertyValue name="NewLines_Braces_Type">1</PropertyValue>
    	        <PropertyValue name="Space_AfterLambdaArrow">1</PropertyValue>
    	        <PropertyValue name="NewLines_Braces_LambdaExpressionBody">1</PropertyValue>
    	        <PropertyValue name="Space_WithinSquares">0</PropertyValue>
    	        <PropertyValue name="Space_BeforeLambdaArrow">1</PropertyValue>
    	        <PropertyValue name="NewLines_Braces_AnonymousTypeInitializer">1</PropertyValue>
    	        <PropertyValue name="Space_WithinCastParentheses">0</PropertyValue>
    	        <PropertyValue name="Space_AfterSemicolonsInForStatement">1</PropertyValue>
    	        <PropertyValue name="Indent_CaseContents">1</PropertyValue>
    	        <PropertyValue name="Indent_FlushLabelsLeft">0</PropertyValue>
    	        <PropertyValue name="Space_BetweenEmptySquares">0</PropertyValue>
    	        <PropertyValue name="Space_BeforeOpenSquare">0</PropertyValue>
    	        <PropertyValue name="Space_BeforeDot">0</PropertyValue>
    	        <PropertyValue name="Indent_BlockContents">1</PropertyValue>
    	      </ToolsOptionsSubCategory>
    	    </ToolsOptionsCategory>
    	  </ToolsOptions>
    	</UserSettings>

    It sucks that I still have to remember to load the settings for each project before making changes in that project, but at least I don't have to remember which individual settings to use for each project.

    How do you handle this situation? Do you just live with the inconsistencies or is there an alternative way to deal with this issue? Are you using StyleCop (a.k.a. MS Source Analysis) or something like it to enforce some or all of the rules?

More Posts

Our Sponsors

Red-Gate!

Proudly Partnered With