Thursday, March 17, 2011

Regionerate and Perfecting its Config with a Test Class

Regionerate is a great tool to ensure that class members are consistently sorted in a predictable order.  Why? Believe it or not, it does make unfamiliar code easier to navigate and makes public facing members prominently placed for quick reference when consumers need more information.  It also improves the ease of merging code when multiple users are editing the same file.

In my opinion regions are a bad idea (and this seems to be a fairly common opinion). Everyone has their own take on how members should be grouped. Someone else's logic is not the same as mine and therefore the benefit of grouping by an inconsistent means is flawed.  A colleague also suggested grouping by logical program flow. This seems like a good idea at first, but with experience modern software typically doesn't follow linear patterns, most applications are asynchronous and event driven, leading to many very different lines of execution through a class.

So the best way to consistently order members in a class is by accessor and then alphabetically by member name.  (This conincides with Microsoft's Framework Guidelines book and default configuration for StyleCop). Quite often all a consumer knows is the method name, so that's what they are looking for. Also its nice to have the code ordered in the same order as the member selector dropdown on the toolbar.  To achieve this I turn to Regionerate.  As them name suggests it can be used to create regions in the code, but like all good tools its configurable, and its sorting capabilities are great.

I've been attempting to perfect my Regionerate config xml, and to do this ideally you need a test class with all manner of members.

My Test Class is at the bottom of this post.

And here's my resulting config file so far. (Check my Essential Tools page for the most up to date version of my config).

There are a couple of annoying bugs in Regionerate that creates unavoidable double line spacing between members. It also seems to change the alignment of closing braces by deleting their indenting tabs.  Both of these issues can be quickly worked around by using Visual Studio's Format Document feature (Ctrl+K Ctrl+D), and then doing a quick replace (Ctrl+H) for
\n:b*\n:b*\n 
and replace with
\n\n
Hit replace 2 or 3 times and its good to go.



namespace Foo.Service.Console
{
    using System;
    using System.Diagnostics.CodeAnalysis;
public interface IClass1
    {

        void TestMethod();
    }
public struct Struct1
    {
        public int Member1;
        public int Member2;
    }

    public class Class1
    {

        public static readonly int PublicStaticReadOnly1 = 5;
        public static readonly int PublicStaticReadOnly2 = 6;


        public const double Pi = 3.141;

        private const double Ei = 9.12335;


        private static readonly string Field1;
        private static readonly int Field2;
        private static readonly double Field3;

        private readonly string field4;
        private readonly int field5;
        private readonly double field6;

        private string field7;
        private int field8;
        private double field9;


        static Class1()
        {
            Field3 = Pi;
        }

        public Class1(int parameter)
            : this()
        {
            this.field8 = parameter;
        }

        internal Class1()
        {
            this.field7 = "Hello";
        }


        public delegate bool Invocation1(int x, int y);
        internal delegate bool Invocation2(int x, int y, string position);
        protected delegate bool Invocation3(int x, int y, string position, double offset);
        private delegate bool Invocation4(double x, double y, string position, double offset);

        public event EventHandler IsChanging;
        public event EventHandler IsMorphing;

        public enum MyEnum
        {
            Cyan,
            Magenta,
            Yellow,
            Black,
        }


        public static int Property1 { get; set; }

        public static int Property2 { get; set; }

        public static int Property3 { get; set; }

        public int Property4 { get; set; }

        public int Property5 { get; set; }

        public int Property6 { get; set; }

        internal static int Property7 { get; set; }

        internal static int Property8 { get; set; }

        internal static int Property9 { get; set; }

        internal int Property10 { get; set; }

        internal int Property11 { get; set; }

        internal int Property12 { get; set; }

        protected static int Property13 { get; set; }

        protected static int Property14 { get; set; }

        protected static int Property15 { get; set; }

        protected int Property16 { get; set; }

        protected int Property17 { get; set; }

        protected int Property18 { get; set; }

        private static int Property19 { get; set; }

        private static int Property20 { get; set; }

        private static int Property21 { get; set; }

        private int Property22 { get; set; }

        private int Property23 { get; set; }

        private int Property24 { get; set; }


        public static void StaticMethod1()
        {
        }

        public static void StaticMethod2()
        {
        }

        public static void StaticMethod2(int x, int y)
        {
        }

        public static void StaticMethod2(int x, int y, string position)
        {
        }

        public void Method1()
        {
        }

        public void Method1(int x, int y)
        {
        }

        public void Method1(int x, int y, string position)
        {
        }

        public void Method2()
        {
        }


        internal static void Method3()
        {
        }

        internal static void Method4()
        {
        }

        internal static void Method4(int x)
        {
        }

        internal void Method5()
        {
        }

        internal void Method6()
        {
        }

        internal void Method7(int x)
        {
        }


        protected internal void Method8()
        {
        }

        protected internal void Method9()
        {
        }

        protected internal void Method9(int x)
        {
        }


        protected static void Method10()
        {
        }

        protected static void Method11()
        {
        }

        protected static void Method12(int x)
        {
        }

        protected void Method13()
        {
        }

        protected void Method14()
        {
        }

        protected void Method15(int x)
        {
        }


        private static void Method16()
        {
        }

        private static void Method17()
        {
        }

        private static void Method18(int x)
        {
        }

        private void Method19()
        {
        }

        private void Method20()
        {
        }

        private Class5 Method21(int x)
        {
            return new Class5();
        }


        public class Class2
        {

        }

        public class Class3
        {

        }

        internal class Class4
        {

        }

        private class Class5
        {

        }
    }
}

Wednesday, March 16, 2011

Windows Phone Navigation Basics

Excellent walk though in the MSDN journal by Charles Petzold on Silverlight Windows Phone Navigation.

Also some excellent demo's of Silverlight culture localisation.

Thursday, March 3, 2011

Scrum Q&A with Jeff Sutherland

Insightful and compelling Q&A session with Jeff Sutherland yesterday.

The most notable questions were:
  • What place do timesheets have in Scrum?

    Basically the answer can be found on Jeff's blog here.  Succinctly, (and I paraphrase) "When I am hired as a CTO or similar the first thing I do at 8am Monday is abolish time sheets. They are a waste of time"... "Teams should only be working on one thing at a time and the CFO knows what all our salaries are, so capitalising costs is as easy as calculating number of days multiplied by salary costs".
  • With all the Scrum stats and measures measuring the team performance how do you do individual performance reviews?

    His answer was: "At 8:15am I move on to abolishing performance reviews..."  See his blog posts here and here.
    Again, its a practice he believes does more harm than good.  Feedback should be given at the time of the event, both good and bad.  Salary reviews are done when asked for by employees and they need to give evidence they deserve an increase. By showing peers externally at other software companies earn more money, or by creating positive public opinion and press. Thereby increasing the companies sales through brand-awareness. Very interesting.

Wednesday, March 2, 2011

Xml Comment Warnings from Generated Code

I am a huge fan of ensuring high quality and consistency across all software libraries produced in a project.  To that end I always elevate all warnings to errors and require that Xml Documentation is activated, requiring documentation on all public methods.  (In addition to this I always use Code Analysis on "Microsoft All Rules"). For more information on guidelines see this previous post.

There's a problem with this, generated code sometimes gets generated outside of your control and obviously you do not want to go through it every time and add comments and make it comply with all rules. Only to have your changes removed when next it gets generated.  Specifically generated WCF service proxies always create code warnings for lack of XML code documentation.

The only reasonable way I have seen to prevent this is to add a pragma tag at the top of the generated file.

#pragma warning disable 1591

Not ideal, as it will need to be re-added with each regeneration of the code, but if someone else has a better solution I'd love to hear it.