Don’t Repeat Yourself (DRY) Essential Developer Principles C#

The DRY (Don’t Repeat Yourself) Principle states:

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
The principle was formulated by Andy Hunt and Dave Thomas in The Pragmatic Programmer, and underlies many other well-known software development best practices and design patterns.Inorder to explain the principle in detail lets derive the following aspects

  • Duplication is waste

Every line of code that goes into an application must be maintained, and is a potential source of future bugs. Duplication needlessly bloats the codebase, resulting in more opportunities for bugs and adding accidental complexity to the system. The bloat that duplication adds to the system also makes it more difficult for developers working with the system to fully understand the entire system, or to be certain that changes made in one location do not also need to be made in other places that duplicate the logic they are working on. DRY requires that “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”

  • Repetition in process calls for automation

Many processes in software development are repetitive and easily automated. The DRY principle applies in these contexts as well as in the source code of the application

Manual testing is slow, error-prone, and difficult to repeat, so automated test suites should be used, if possible. Integrating software can be time consuming and error-prone if done manually, so a build process should be run as frequently as possible, ideally with every check-in. Wherever painful manual processes exist that can be automated, they should be automated and standardized. The goal is to ensure there is only one way of accomplishing the task, and it is as painless as possible.

  • Repetition in logic calls for abstraction

Repetition in logic can take many forms. Copy-and-paste if-then or switch-case logic is among the easiest to detect and correct. Many design patterns have the explicit goal of reducing or eliminating duplication in logic within an application. If an object typically requires several things to happen before it can be used, this can be accomplished with an Abstract Factory or a Factory Method. If an object has many possible variations in its behavior, these behaviors can be injected using the Strategy pattern rather than large if-then structures. In fact, the formulation of design patterns themselves is an attempt to reduce the duplication of effort required to solve common problems and discuss such solutions. In addition, DRY can be applied to structures, such as database schema, resulting in normalization.

Visual Studio 2013

Announcing LightSwitch in Visual Studio 2013 Preview

The team will be rolling out detailed posts on all the new features in the coming weeks on the LightSwitch Team Blog. To recap, here are some of the biggies:

  • You no longer need to switch between Logical View and File View because all your project content is available under one view in Solution Explorer
  • LightSwitch projects work more seamlessly with the IDE, so using the scoping, search, and browse history features are all now available in your LightSwitch projects.
  • You can view multiple designers at the same time. Each screen, table, and query is now opened in its own document tab.
  • Improved team development! Each entity, screen, and query is now persisted in its own .lsml model file, dramatically reducing the likelihood of merge conflicts when multiple developers work on the same project. We’ve also improved compatibility with existing source code control providers.
  • Intrinsic database management with linked database project, providing the ability to generate reference data and make schema enhancements.
  • Improved JavaScript IntelliSense, as well as notable improvements to the core JavaScript experience such as code editor and DOM Explorer enhancements (more info here).
  • API support for refreshing data on lists and screens in the runtime app.
  • Integration with other Visual Studio features, such as Team Build and Code Analysis.

And of course there are fixes for many issues customers reported. I encourage you to test drive the VS2013 preview – LightSwitch was already a super productive development environment, and it’s gotten even better in this release!

Command Pattern

A Command Pattern allows requests to an object to exist as an object. What does that mean? It means that if you send a request for some function to an object, the command object can house that request inside the object. This is useful in the case of undoing or redoing some action, or simply storing an action in a request queue on an object. When you send the request, it is stored in the object. Then later, if you need to access that same request, or apply the request or some method on the request to an object, you can use the request object instead of calling the object’s method directly.

Continue reading Command Pattern

ReSharper and StyleCop

Configuring ReSharper

Firstly open up Visual Studio. Along the menu bar there should be a “ReSharper” heading. Go to “Options” within it.

Code Style Sharing – make sure you have “Shared across the team, per solution” selected. You’ll need to make sure your whole team have this selected. I think it is by default.

C# – Go through the C# section, and set all the rules to suit preferred style. Typically I would suggest leaving most of them as they are.

Code Cleanup – “Add” a new code cleanup profile, and again go through setting everything as you’d like it to be. I turn on as much as possible, and set it where possible to change explicit types to “var” (because I find it reads more cleanly).

UserSettings.xml

Once done, you need get your settings file. It will be located at:

“%USERPROFILE%\Application Data\JetBrains\ReSharper\v4.x\vs9.0″

Take the UserSettings.xml file and place it in source control. I placed mine at:

/trunk/build/settings/resharper/UserSettings.xml

Here’s my UserSettings.xml file as an example. Within that directory I also created an install.bat with the following inside it:

copy UserSettings.xml “%USERPROFILE%\Application Data\JetBrains\ReSharper\v4.5\vs9.0″
pause

By getting your team to run this, it will ensure you all have the same settings file. I like to enforce this by adding it to the end of go.bat. It’s a simple copy command and won’t increase the build time.

If your solution file is called MyApp.sln, you need to make sure you have a MyApp.4.x.resharper file.

MySolution.4.x.resharper

Where your solution is located, if called MySolution.sln, you should now have a resharper file called MySolution.4.x.resharper. This is your team settings file, and whenever a team member opens the solution, ReSharper will use that config.

UserSettings.xml relates to your settings, namely code cleanup. The only annoying thing of sharing a UserSettings.xml file is that team members can’t customise ReSharper themselves (do they need to?).

Here’s my older Solution.4.1.resharper file (I can’t remember if it’s compatible with v4.5) as an example.

StyleCop

If you open a solution now, you should get ReSharper suggestions regarding poorly styled code. Also the “Code Cleanup” should work quite effectively at cleaning up your code.

However, you’ll probably find ReSharper raising style errors for things you don’t see as errors. Hover over these suggestions and note down the Id. It’ll be something like “SA1004”. Spend a while going through a number of your projects and note down any rules you don’t like.

Now you need to create your Settings.StyleCop file. Right-click on any project in your solution and select “StyleCop Settings”. You can now disable any rules you don’t like (use the search, and type in the Id’s from the above step). This is my Settings.StyleCop file.

Once done go to the projects file system folder, and move the “Settings.StyleCop” file to where your solution file is. Add it to source control. If you reload Visual Studio it should now have:

  • Team .resharper settings
  • Shared UserSettings.xml file
  • StyleCop rules, and ReSharper suggestions

Enforcing Styling

The above steps set up a good framework for well styled code, but don’t enforce it. This is something that can be done using the build and NAnt.

Download StyleCopCommand, and add it to your source control. I place it in:

/trunk/tools/stylecopcommand

Using NAnt you can call StyleCopCommand using:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<project name="StyleCop" xmlns="http://nant.sf.net/release/0.86-beta1/nant.xsd" default="stylecop">
    <property name="stylecop.console" value="${source.directory}\tools\stylecopcmd\StyleCopCmd.exe" />
    <target name="stylecop">
        <exec program="${stylecop.console}">
            <arg line="-sf ${source.directory}\sln\Huddle.All.sln" />
            <arg line="-sc ${source.directory}\src\Settings.StyleCop" />
            <arg line="-of ${report.directory}\stylecop.xml" />
        </exec>
        <property name="violations.file" value="${report.directory}\stylecop.violations.count.xml" />
        <!-- Get the violation count for the previous build -->
        <property name="violations.previous" value="35000" overwrite="true" />
        <if test="${file::exists(violations.file)}">
            <xmlpeek file="${violations.file}" xpath="/Violations" property="violations.previous" failonerror="true"/>
        </if>
        <!-- Overwrite the xml, and get the violation count for the current build -->
        <style style="stylecop.xslt" in="${report.directory}\stylecop.violations.xml" out="${violations.file}.temp" />
        <xmlpeek file="${violations.file}.temp" xpath="/Violations" property="violations.current" failonerror="true" />
        <echo message="Previous style violations = ${violations.previous}" />
        <echo message="Current style violations  = ${violations.current}" />
        <fail if="${(int::parse(violations.current) > int::parse(violations.previous))}" message="More code style violations have been introduced. There are currently ${violations.current} violations. You need to reduce it by ${int::parse(violations.current) - int::parse(violations.previous)} for the build to pass." />
        <copy file="${violations.file}.temp" tofile="${violations.file}" failonerror="true" />
        <delete file="${violations.file}.temp" />
    </fail></target>
</project>

This will generate a “stylecop.xml” report along with a “stylecop.violations.xml”. You can then do a node count on the number of violations. This is tricky with NAnt so I use XSLT to do the node count, then NAnt to read the result.

1
2
3
4
5
6
7
8
9
< ?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <violations>
            <xsl:value -of select="count(//StyleCopViolations/Violation)"/>
        </violations>
    </xsl:template>
</xsl:stylesheet>

I also check the violation count of the previous build, with that of the current build. If it has increased, then I fail the build. It’s strict but we currently have 34,000 6,000 (it dropped around 25,000 in a few months) violations throughout our legacy code, so there’s plenty of code someone can clean up if they break the build.

The only annoying point, is that the violation total is kept on the build server. So there’s no easy (current) way of checking your local code has added any new violations. You only find out upon commiting. It hasn’t caused us too many problems just yet.

Conclusion

It will make some of the developers grumble, but deep down they’ll know it’s a good thing, and will improve the code you work with.

Opening a C# file that is messy and styled badly, immediately makes any developer not want to work with it, feel detached from it, and less ownership of it. It may sound a bit much for code, but it’s what we work with most of the day.

We’re now removing around 500 violations a day. This will probably slow in time, but for now it’s working very well. Maybe in the future we’ll change the build rules to be less strict.

Moving Forward

There are a number of things that can be done to improve all of the above:

  • Creating a StyleCop NAnt task to wrap up a lot of the logic shown above.
  • Defining where the current violation count lives, and allowing your local dev machine to check that count. That way you can be certain you’ve not added any styling violations.
  • The StyleCop report that is generated has all the violations. This isn’t helpful if you’ve added 3 new violations as you have no way of knowing what they were. It would be good to use CruiseControl XSLT templates to compare modifications against files that have style violations. You could then only show the violations that were introduced related to that commit.
  • Related to the above point. Rather than getting StyleCop to check every file, it would be handy to get it to check only the files that were committed. I’m not sure if this is possible, but if it is, then it would reduce build time drastically.

Structuring Projects for Team Foundation Server

My team spent some time this past week evaluating various approaches and lessons learned from various projects  We boiled it down to something that seems to be working well, and distills what’s worked for some teams.  With the caveat that we’re still evaluating, here’s what we learned …

Solution
Local File System

C:\MyApp
	\MyApp.sln
	\Source
		\MyAppWeb
		\ClassLibrary1

Source Control (Team Foundation Server)

/Main
	/Build
	/Docs
	/Source
		/MyApp
			MyApp.sln
			/Source
				/MyAppWeb
				/ClassLibrary1
			/UnitTests
				/MyAppWebTests
				/ClassLibrary1Tests
	/Tests

Key points
Here’s a few highlights about this approach:

  • On the client side, we explicitly creat our solution file up front instead of rely on defaults
  • The project folder containts one master solution.
  • The project has source and unit tests.  Loading the solution for the project, loads the source and unit tests
  • The Main folder in TFS holds the project assets (Build, Docs, Source, Tests).  Using Main lets us create other folders for potential branches (Development, Production, Maintenance … etc.)

Repro Steps
Here’s a brief walkthrough to test using a file-based Web:

  1. Create a blank solution in VSTS
  2. Create a source folder on the file system (C:\MyApp\Source)
  3. Add new Web project (C:\MyApp\Source\MyAppWeb)
  4. Add new Class Library (C:\MyApp\Source\ClassLibrary1)

Verify your folder structure on your File System:

C:\MyApp
	\MyApp.sln
	\Source
		\MyAppWeb
		\ClassLibrary1

Adding to TFS

  1. Add your solution to source control
  2. Create a Main folder
  3. Create a Source folder beneath Main

Verify your folder structure in Source Control Explorer

/Main
	/Source
		/MyApp
			/MyApp.sln
			/Source
				/MyAppWeb
				/ClassLibrary1

More Information
You should know that while I talked through the single solution scenario, there are additional patterns.  Here’s the key patterns we see:

  1. Single solution
  2. Partitioned single solution
  3. Multi-solution

TFS Best Practices

The Microsoft Patterns and Practices team, in concert with the TFS team and a panel of customer reviewer has just released a terrific document on TFS Best Practices.  This is distinct from the TFS help on MSDN in the sense that it is not “How-to” guidance but is conceptual information and recommendations for how to use TFS to fit your development process

Design Pattern

Design patterns are recurring solutions to software design problems you find again and again in real-world application development. Patterns are about design and interaction of objects, as well as providing a communication platform concerning elegant, reusable solutions to commonly encountered programming challenges.

The Gang of Four (GoF) patterns are generally considered the foundation for all other patterns. They are categorized in three groups: Creational, Structural, and Behavioral. Here you will find information on these important patterns.

To give you a head start, the C# source code is provided in 2 forms: ‘structural’ and ‘real-world’. Structural code uses type names as defined in the pattern definition and UML diagrams. Real-world code provides real-world programming situations where you may use these patterns.

A third form, ‘.NET optimized’ demonstrates design patterns that exploit built-in .NET 4.0 features, such as, generics, attributes, delegates, object and collection initializers, automatic properties, and reflection. These and much more are available in our Design Pattern Framework 4.0TM. See ourSingleton page for a .NET 4.0 Optimized code sample.

  Creational Patterns
  Abstract Factory   Creates an instance of several families of classes
  Builder   Separates object construction from its representation
  Factory Method   Creates an instance of several derived classes
  Prototype   A fully initialized instance to be copied or cloned
  Singleton   A class of which only a single instance can exist
  Structural Patterns
  Adapter   Match interfaces of different classes
  Bridge   Separates an object’s interface from its implementation
  Composite   A tree structure of simple and composite objects
  Decorator   Add responsibilities to objects dynamically
  Facade   A single class that represents an entire subsystem
  Flyweight   A fine-grained instance used for efficient sharing
  Proxy   An object representing another object
  Behavioral Patterns
  Chain of Resp.   A way of passing a request between a chain of objects
  Command   Encapsulate a command request as an object
  Interpreter   A way to include language elements in a program
  Iterator   Sequentially access the elements of a collection
  Mediator   Defines simplified communication between classes
  Memento   Capture and restore an object’s internal state
  Observer   A way of notifying change to a number of classes
  State   Alter an object’s behavior when its state changes
  Strategy   Encapsulates an algorithm inside a class
  Template Method   Defer the exact steps of an algorithm to a subclass
  Visitor   Defines a new operation to a class without change

Design Patters and SOLID Principes

 

For those who are not aware of this, SOLID is an acronym for the first 5 principles of object-oriented design:

  1. SRP The Single Responsibility Principle: — a class should have one, and only one, reason to change.
  2. OCP The Open Closed Principle: — you should be able to extend a class’s behavior, without modifying it.
  3. LSP The Liskov Substitution Principle: — derived classes must be substitutable for their base classes.
  4. ISP The Interface Segregation Principle: — make fine grained interfaces that are client specific.
  5. DIP The Dependency Inversion Principle — depend on abstractions not on concrete implementations.

You’ll find a fair amount of information on the web on these principles.

It seems to me that you need a good grasp of the SOLID principles before you’re ready to tackle Design Patterns (in more of an Architect role).  At least that is how my educational & career process evolved. Does anyone have other experiences or opinions?

I am curious to hear how other .NET developers learn and internalize Design Patterns.

HTTP Compression

You can enable HTTP compression server-wide or on a specific directory. HTTP compression improves bandwidth utilization and speeds up Web site performance. In addition, you can compress static or dynamic responses.

 

Important

You must be a member of the Administrators group on the local computer to perform the following procedure or procedures. As a security best practice, log on to your computer by using an account that is not in the Administrators group, and then use the runascommand to run IIS Manager as an administrator. At a command prompt, type runas /user:Administrative_AccountName“mmc %systemroot%\system32\inetsrv\iis.msc”.

Procedures

To enable global HTTP compression by using IIS Manager

1. In IIS Manager, double-click the local computer, right-click the Web Sites folder, and then click Properties.
2. Click theService tab, and in the HTTP compression section, select the Compress application files check box to enable compression for dynamic files.
3. Select the Compress static files check box to enable compression for static files.
4. In the Temporary directory box, type the path to a local directory or click Browse to locate a directory. Once a static file is compressed, it is cached in this temporary directory until it expires, or the content changes. The directory must be on the local drive of an NTFS–formatted partition. The directory cannot be compressed or shared, and the access control lists (ACLs) for the directory must include Full Control access to the identity of the application pool or to the IIS_WPG group.
5. Under Maximum temporary directory size, click a folder size option. If you specify a maximum size under Limited to (in megabytes) (the default setting is 95 MB), then when the limit is reached, IIS automatically cleans up the temporary directory by applying the “least recently used” rule.
6. Click Apply, and then click OK.

Important

You must be a member of the Administrators group on the local computer to run scripts and executables. As a security best practice, log on to your computer by using an account that is not in the Administrators group, and then use the runas command to run your script or executable as an administrator. At a command prompt, type runas /profile /user:MyComputer\Administratorcmd to open a command window with administrator rights and then type cscript.exeScriptName (include the script’s full path and any parameters).

To enable global HTTP compression by using Adsutil.vbs

1. Open a command prompt.
2. To enable dynamic compression, type the following at the command prompt and then press ENTER:cscript adsutil.vbs set w3svc/filters/compression/parameters/HcDoDynamicCompression true
3. To enable static compression, type the following at the command prompt and then press ENTER:cscript adsutil.vbs set w3svc/filters/compression/parameters/HcDoStaticCompression true

To enable HTTP Compression for Individual Sites and Site Elements

1. Disable global static compression by executing the following command at a command prompt:adsutil set w3svc/filters/compression/parameters/HcDoStaticCompression false
2. Enable static compression at this directory by executing the following command at a command prompt:adsutil set w3svc/1/root/Home/StyleSheets/DoStaticCompression true

To disable static compression for only a single directory, first enable global static compression (if it is disabled) and then disable static compression at that directory. For example, to enable static compression for a directory at http://www.contoso.com/Home/StyleSheets, perform the following steps:

1. Disable global static compression by executing the following command at a command prompt:adsutil set w3svc/filters/compression/parameters/HcDoStaticCompression true
2. Enable static compression at this directory by executing the following command at a command prompt:adsutil set w3svc/1/root/Home/StyleSheets/DoStaticCompression false