This project is read-only.

Jolt.NET Coding Standard

The following guidelines present the coding standard for the Jolt.NET libraries. It is permissible to deviate from these guidelines as long the reason is justifiable.

Table of Contents

  1. Solutions, Projects, and Namespaces
  2. Type Definitions
  3. Interfaces, Classes, and Structs
  4. Miscellaneous

Solutions, Projects, and Namespaces

  • Place all projects in the Jolt.NET solution
  • Place test code and production code in separate projects
  • Keep the project folder structure as flat as possible, where each project folder is contained directly in the solution folder (see example below)
  • Follow the .NET convention of naming a project/assembly with the primary namespace it defines
  • The namespace of a test project/assembly is the namespace of the corresponding production-code project/assembly, followed by ".Test"
  • Follow the Visual Studio IDE convention of creating a folder within a project for any sub-namespace defined by that project

Solution.PNG Folders.PNG


Types Definitions

  • One type definition per file
  • Each file should contain a header describing its contents
  • Use XML doc comments to descibe the purpose and public/private contract of any new type

// ----------------------------------------------------------------------------
// XmlComparisonFlags.cs
//
// Contains the definition of the XmlComparisonFlags enumeration.
// Copyright 2009 Steve Guidi.
//
// File created: 6/1/2009 17:53:54
// ----------------------------------------------------------------------------

using System;

namespace Jolt.Testing.Assertions
{
    /// <summary>
    /// Controls the level of equivalency strictness when applied to the
    /// <see cref="XmlEquivalencyAssertion"/> class.
    /// </summary>
    [Flags]
    public enum XmlComparisonFlags
    {
        Strict = 0x00,
        IgnoreElementNamespaces = 0x01,
        IgnoreAttributeNamespaces = 0x02,
        IgnoreAttributes = 0x04,
        IgnoreElementValues = 0x08,
        IgnoreSequenceOrder = 0x10
    }
}


Interfaces, Classes and Structs

  • Use regions to separate members in the following manner, omitting empty regions

namespace Jolt.CodingStandard.Examples
{
    internal sealed class Regions
    {
        #region constructors --------------------------------------------------------------------------
        
        // ... and any finalizers too.
        // Access modifiers are ordered as follows: public, internal, protected, private, static
        
        #endregion

        #region base-type-name members ----------------------------------------------------------------
        #endregion

        #region implemented-interface-name members ----------------------------------------------------
        #endregion

        // Access modifiers are ordered as follows; public, internal, protected, private.

        #region access-modifier-name methods ----------------------------------------------------------
        #endregion

        #region access-modifier-name properties -------------------------------------------------------
        #endregion

        #region access-modifier-name events -----------------------------------------------------------
        #endregion

        #region access-modifier-name fields -----------------------------------------------------------
        #endregion
    }
}
  • Within each region, group static and instance members
  • When only one type of member is present in the entire class/struct, using a region is optional

namespace Jolt.CodingStandard.Examples
{
    internal sealed class MemberGrouping
    {
        #region constructors ----------------------------------------------------------------------

        public MemberGrouping() : this("member", "grouping") { }

        internal MemberGrouping(string memberText, string groupingText)
        {
            m_member = memberText;
            m_grouping = groupingText;
        }

        static MemberGrouping()
        {
            ReaderSettings = new XmlReaderSettings();
            ReaderSettings.ValidationType = ValidationTpe.Auto;
        }

        #endregion

        #region private fields --------------------------------------------------------------------

        private readonly string m_member;
        private readonly string m_grouping;

        private static readonly XmlReaderSettings ReaderSettings;

        #endregion
    }
}
  • When possible, adopt the "principle of least priviledge", adding visibility/access to members when required
    • Interfaces are implemented explicitly
    • New classes are internal and sealed
    • Methods are non-virtual
    • Fields are private and read-only

namespace Jolt.CodingStandard.Examples
{
    public sealed class TypeAccessibility : IEquatable<TypeAccessibility>, IDisposable
    {
        #region constructors ----------------------------------------------------------------------

        public TypeAccessibility()
        {
            m_callCounter = 0;
            m_readerSettings = new XmlReaderSettings();
            // ...
        }

        #endregion

        #region IEquatable<TypeAccessibility> members ---------------------------------------------

        public bool Equals(TypeAccessiblity rhs)
        {
            return m_dependentType.Equals(rhs.m_dependentType);
        }

        #endregion

        #region IDisposable members ---------------------------------------------------------------

        void IDisposable.Dispose()
        {
            m_dependentType.Dispose();
        }

        #endregion

        #region public methods --------------------------------------------------------------------

        public void DoWork()
        {
            ++m_callCounter;
        }

        #endregion

        #region public properties -----------------------------------------------------------------

        public int CallCount
        {
            get { return m_callCount; }
        }

        #endregion

        #region internal properties ---------------------------------------------------------------

        internal XmlReaderSettings Settings
        {
            get { return m_readerSettings; }
        }

        #endregion

        #region private fields --------------------------------------------------------------------

        private int m_callCounter;
        private readonly XmlReaderSettings m_readerSettings;

        private static readonly string Text = "HelloWorld!";

        #endregion
    }
}

Miscellaneous

  • Place any text which may be read by the caller of the library in a localizable embedded resource
    • Good examples: log messages, exception strings, console output
    • Bad examples: application configuration strings, XPath expressions, string constants (literals)

Last edited Dec 8, 2009 at 11:07 PM by SteveGuidi, version 3

Comments

No comments yet.