Top Posts & Pages
Error: Twitter did not respond. Please wait a few minutes and refresh this page.
Stephen Ritchie's offerings of ruthlessly helpful .NET practices.
A big thank you to the DC .NET Users Group for hosting my presentation on Continuous Integration at their Februrary meeting last night. I really hope that everyone enjoyed the presentation on continuous integration. The questions and conversations were very good.
Here are the slides, available through SlideShare.
So you’re getting ready to start a .NET Best Practices initiative at your organization and you’re looking to find a lot of specific best practices tips. You want to know: What are the .NET Framework best practices?
You can be assured that I’ve been down this road. In fact, a few readers of my book, Pro .NET Best Practices, expressed some disappointment that the book is not a collection of specific .NET best practices. And this is exactly why I decided to address this subject in today’s post.
For those that want to dig right in, follow this link to part 1, MSDN: .NET Framework Best Practices.
If you want some background, let me start with the question: Who wants to follow best practices, anyway?
The adoption of new and different practices is a central theme of Pro .NET Best Practices. I work with enough individuals, teams, and organizations to understand the issues involved with adopting best practices. Consider the four levels at which best practices are embraced:
In an ideal world, best practices are quickly adopted at all four levels. However, in the real world, they can be slowly adopted by the group, resisted by the organization, embraced by one individual, not by another, or ignored altogether by everyone but you. It can be a mixed bag.
There are two key readers of this blog post that I want to identify with and help:
These readers are adopting at either the individual or group level.
If you are a reader who wants to bring best practices to the organization or the software development profession then I assert that you are probably not interested in the content of this compendium. Yes, you might refer a developer or team leader to the compendium, but I doubt you will find it directly relevant.
So, given this introduction, let’s look at how a collection (I like the term compendium) of specific .NET best practices might be organized.
Since this is a blog, tags can help others find and navigate the content. Here is a quick list of tags that come to mind:
Clearly, there are a lot of ways to slice and dice the topic of best practices; however, I will try to bring things back to the topic of the Microsoft .NET Framework.
You can find the entire Best Practices category here: https://ruthlesslyhelpful.net/category/development/best-practices/
I mostly wrote Pro .NET Best Practices based on my professional experience trying to get teams and organizations to adopt .NET Framework best practices. Over the years, I have read many books, I experimented, I tried and persevered with one approach, and I tried totally new approaches. Many times I learned from others. Many times I learned by my mistakes.
Over the years and as I researched my book, I found many free, on-line sources of .NET best practices. Many are professionally written and easy to follow. In my book I was reluctant to paraphrase or repeat material, but I should have done a better job of showing people how to access the material. (The one thing I really kick myself over is that I did not use Bitly.)
So, let me start the Compendium of .NET Best Practices with some great material already available on the Internet.
For years now, Microsoft Developer Network (MSDN) has provided free online documentation to .NET developers. There is a lot of individual .NET best practices topics, which are described at the high level at this MSDN link:
MSDN: .NET Framework Best Practices
This is a great MSDN article to read and link to bookmark if you’re interested in.NET best practices.
Just take a look at all the information within the MSDN topic of Best Practices for Using Strings in the .NET Framework. I am not going to be able to duplicate all of that. If you are developing an application that has to deal with culture, globalization, and localization issues then you need to know much of this material.
Before I go any further, let me introduce you to Jon Skeet. He wrote an awesome book, C# In Depth. I think you might enjoy reading his online article on .NET Strings: http://csharpindepth.com/Articles/General/strings.aspx
Okay, let’s get back to the MSDN article. Below I have highlighted a few of the Strings best practices that I’d like to discuss.
1. Use the String.ToUpperInvariant method instead of the String.ToLowerInvariant method when you normalize strings for comparison.
In the .NET Framework, ToUpperInvariant is the standard way to normalize case. In fact, the Visual Studio Code Analysis has rule CA1308 in the Globalization category that can monitor this.
This is a really easy practice to follow once you know it.
Here is the key point I picked up from rule CA1308:
It is safe to suppress [this] warning message [CA1308] when you are not making security decision based on the result (for example, when you are displaying it in the UI).
In other words, take care to uppercase strings when the code is making a security decision based on normalized string comparison.
2. Use an overload of the String.Equals method to test whether two strings are equal.
Some of these overloads require a parameter that specifies the culture, case, and sort rules that are to be used in the comparison method. This just makes the string comparison you are using explicit.
3. Do not use an overload of the String.Compare or CompareTo method and test for a return value of zero to determine whether two strings are equal.
In the MSDN documentation for comparing Strings the guidance is quite clear:
The Compare method is primarily intended for use when ordering or sorting strings.
If you have not had a chance to take a look at the All-In-One Code Framework then please take a few minutes to look it over.
The Microsoft All-In-One Code Framework is a free, centralized code sample library driven by developers’ needs.
It is Microsoft Public License (Ms-PL), which is the least restrictive of the Microsoft open source licenses.
What’s relevant to this article is the All-In-One Code Framework Coding Standards document. You can find the download link at the top of this page: http://1code.codeplex.com/documentation
In that document, they list a very relevant and useful list of String best practices.
This post is part of my Compendium .NET Best-Practices series.
In November I traveled to Upstate New York to present at four .NET Users Group. Here’s the overview:
I realize it is belated, but I’d like to extend a very big and heartfelt thank you to the organizers of these users groups for putting together a great series of meetings.
Thank you to Stephanie Carino from Apress for connecting me with the organizers. I really appreciate all the help with all the public relations, the swag, the promotion codes, the raffle copies of my book, and for the tweets and re-tweets.
My presentations are available on SlideShare under my RuthlessHelp account, but if you are looking for something specific then here are the four presentations:
All the code samples can be found on GitHub under my RuthlessHelp account: https://github.com/ruthlesshelp/Presentations
If you attended one of these presentations, please rate me at SpeakerRate:
You can also rate me at INETA: http://ineta.org/Speakers/SearchCommunitySpeakers.aspx?SpeakerId=b7b92f6b-ac28-413f-9baf-9764ff95be79
Another great showing for the DC Alt.Net meetup last night. I hope everyone enjoyed my presentation on code analysis in .NET. There were a lot of great questions and good conversation. I really appreciate the audience participation.
Here are the code samples, available through GitHub.
Here are the slides, available through SlideShare.
With the two day Microsoft Security Development Conference starting tomorrow in DC, I am curious to hear about one thing: what is the static code analysis story in the Security Development Lifecycle?
Microsoft explains their vision of the Security Development Lifecycle and provides SDL Practice #10: Perform Static Analysis. On that page, under the heading of Tools specific to this practice, CAT.NET is recommended and download links are provided. However, the links are to CAT.NET version 1.0. What happened to CAT.NET 2.0?
On the MSDN blog a post from the SDL folks implies that security-oriented code analysis is going to be part of Visual Studio 11. I believe there is a lot of value in having a separate tool, like FxCop, to perform static code analysis across VS projects and solutions and on 3rd-party assemblies.
I would love to hear more about the tools specific to SDL Practice #10: Perform Static Analysis, and I am hopeful that this will be described in detail in one or more sessions at some future SDC.
Often I am asked variations on this question: Should I unit test private methods?
As a rule of thumb: Do not unit test private methods.
The concept of encapsulation means that a class’s internal state and behavior should remain “unpublished”. Any instance of that class is only manipulated through the exposed properties and methods.
The class “publishes” properties and methods by using the C# keywords: public, protected, and internal.
The one keyword that says “keep out” is private. Only the class itself needs to know about this property or method. Since any unit test ensures that the code works as intended, the idea of some outside code testing a private method is unconventional. A private method is not intended to be externally visible, even to test code.
However, the question goes deeper than unconventional. Is it unwise to unit test private methods?
Yes. It is unwise to unit test private methods.
When you refactor the code-under-test, and the private methods are significantly changed, then the test code testing private methods must be refactored. This inhibits the refactoring of the class-under-test.
It should be straightforward to refactor a class when no public properties or methods are impacted. Private properties and methods, because they are not intended to be directly called, should be allowed to freely and easily change. A lot of test code that directly calls private members causes headaches.
Avoid testing the internal semantics of a class. It is the published semantics that you want to test.
Some dead code is only kept alive by the test methods that call it.
If only the public interface is tested, private methods are only called thorough public-method test coverage. Any private method or branch within the private method that cannot be reached through test coverage is dead code. Private method testing short-circuits this analysis.
Yes, these are my views on what might be a hot topic to some. There are other arguments, pro and con, many of which are covered in this article: http://www.codeproject.com/Articles/9715/How-to-Test-Private-and-Protected-methods-in-NET
Unreadable code with comments is inadequate code with comments you cannot trust. Code that is well written rarely needs comments. Only comments that provide additional, necessary information are useful.
Yesterday a colleague of mine told me that he lost 10 points on a university assignment because he did not comment his code. Today I saw a photo with a list of rules for commenting attributed to Tim Ottinger.
Ottinger’s three rules make a lot of sense. These rules are straightforward. In my experience, they are correct and proper. Here are Ottinger’s Comment Rules:
Comments are for things that cannot be expressed in code.
This is common sense. But, sadly, it is not common practice. Software is written in a programming language. A reader fluent in the programming language must understand the code. The code must be readable. It must clearly express what it is that the code does.
Only add comments when some important thing must be communicated to the reader, and that thing cannot be communicated by making the code any more readable. For example, a comment with a link to the MACRS depreciation method could be important because it helps explain the source of the algorithm.
Comments which restate code must be deleted.
Any restatement of the code is unlikely to maintained over time. If the comment is maintained, then it just adds to the cost. More importantly, when comments are not maintained they either end up substantially misrepresenting the code or end up being ignored. Reading comments that misrepresent code is a waste of time, at best. At worst, they cause confusion or introduce bugs. Remove any comments that restate the code.
If the comment says what the code could say, then the code must change to make the comment redundant.
Writing readable code is all about making sure that the compiler properly implements what the developer intended and making sure any competent developer can quickly and effectively understand the code. The code needs to do both: completely, correctly, and consistently. For example, a comment explaining that the variable x represents the principal amount of a loan violates the single truth rule. The variable ought to be named loanPrincipal. In this way the compiler uses the same variable to represent the same single true meaning that the human reader understands.
Tim Ottinger and Jeff Langr present more pragmatic guideance on when to write (and not write) comments: http://agileinaflash.blogspot.com/2009/04/rules-for-commenting.html
I am a Microsoft .NET software developer. That explains why the book is about .NET best practices. That’s in my wheelhouse.
The more relevant question is, why a book about best practices?
When it comes right down to it, many best practices are the application of common sense approaches. However, there is something that blocks us from making the relatively simple changes in work habits that produce significant, positive results. I wanted to further explore that quandary. Unfortunately, common sense is not always common practice.
There is a gap between the reality that projects live with and the vision that the team members have for their processes and practices. They envision new and different practices that would likely yield better outcomes for their project. Yet, the project reality is slow to move or simply never moves toward the vision.
Many developers are discouraged by the simple fact that far too many projects compromise the vision instead of changing the reality. These two concepts are usually in tension. That tension is a source of great frustration and cynicism. I wanted to let people know that their project reality is not an immovable object, and the team members can be an irresistible force.
Part of moving your reality toward your vision is getting a handle on the barriers and objections and working to overcome them. Some of them are external to the team while others are internal to the team. I wanted to relate organizational behavior to following .NET best practices and to software development.
The team must know what to do. They need to know about the systematic approaches that help the individual and the team achieve the desired results. There are key practice areas that yield many benefits:
Of course, there is a lot of overlap in these areas. The management scientist might call that synergy. A common theme to these practice areas is the principle of automation. By acquiring knowledge in these practice areas you find ways to:
Know-how in these practice areas also raises awareness and understanding, creates an early warning system, and provides various stakeholders with a new level of visibility into the project’s progress. I wanted the reader to appreciate the significance and inter-relatedness of these key practice areas and the benefits each offers.
The team needs to know how to do it. Every new and different practice has a learning curve. Climbing that curve takes time and practice. The journey from newbie to expert has to be nurtured. There are no shortcuts that can sidestep the crawl-walk-run progression. Becoming skilled requires experience. Prototyping and building an archetype are two great ways to develop a skill. Code samples and structured walkthroughs are other ways to develop a skill. I wanted the book to offer an eclectic assortment of case studies, walkthroughs, and code samples.
Team members must want to adopt better practices. Managers need to know why the changes are for the better, in terms managers can appreciate. The bottom line, it is important to be able to quantify the benefits of following new and different practices. It is also important to understand what motivates and what doesn’t. It helps to understand human biases. Appreciate the underlying principle that software projects are materially impacted by how well individuals interact. I wanted to highlight and communicate the best practices that relate to the human factors that include persuasion, motivation, and commitment.
Here are the links to Pro .NET Best Practices:
Code-centric development using an object-relational mapping (ORM) tool has a workflow that many developers find comfortable. They feel productive using the ORM in this way, as opposed to starting with the database model. There are a number of good posts out there on the Entity Framework 4.1 code-first capabilities: MSDN, MSDN Magazine, Scott Guthrie, Channel 9, and Scott Hanselman’s Magic Unicorn Feature. It makes sense to the object-oriented developer and writing code-first comes very naturally.
This prompts the question: When would it be better to take a database-first approach?
For many legacy and Brownfield projects the answer is obvious. You have a database that’s already designed — you may even be stuck with it — therefore you choose database-first approach. This is the defining need for database-first because the database is a fixed point. And so, use database-first when the database design comes from an external requirement or is controlled outside the scope or influence of the project. Similarly, modelling the persistence layer using a model-first approach fits the bill because what you learn about the requirements is expressed in data-centric terms.
Let’s say the project is Greenfield and you have 100% control over the database design. Would a database-first approach ever make sense in that situation?
On-line Transaction Processing (OLTP) and On-line Analytical Processing (OLAP) systems are considered two ends of the the data persistence spectrum. With databases that support OLTP systems the objective is to effectively and properly support the CRUD+Q operations in support of business operations. In the databases that support OLAP systems the objective is to effectively and properly support business intelligence, such as data mining, high-speed data analytics, decision support systems, and other data warehousing goals. These are two extremely different database designs. Many systems’ databases live on a continuum between these two extremes.
I once worked on a student loan originations system. It was a start-with-a-clean-slate, object-oriented development project. Initially, the system was all about entering, reviewing and approving loan applications. We talked about borrowers, students and parents, and their multiple addresses. There was a lot about loan limits and interest rates, check disbursements, and a myriad of complicated and subtle rules and regulations related to creating a loan and making a check disbursement. The system was recording the key records and financial transactions and the database was the master repository of this data. In fulfilling these requirements, the system was a success. However, once the system was readied for parallel Beta-testing at the bank things started to go sideways.
Here is some of what we missed by taking a code-first approach:
What we failed to realize was that the really significant, make-or-break requirements of the system were all reporting or data conversion related. None of it had been seriously brought up or laid out during system development, however, not meeting those requirements took the project very close to the edge of extinction.
A major lesson learned, look very closely at the question of data persistence and retrieval. Work hard to uncover and define the reporting, conversion and other data requirements. Make any hidden or implicit database requirements explicit. Find out if the system is really all about the care and feeding of a relational database.
Adding it all up: if the database-specific requirements significantly overshadow the application-specific requirements then a database-first approach is probably your best bet.