Explicit Interfaces for Versioning (a basic example)

by Moridin8 7. March 2007 19:55

For a few of the '##csharp' guys:

See the code for comments and implementation...

namespace ExplicitInterfacesForVersioning
{
    using System;

    public interface ISomeClass_Version2
    {
        string DoSomethingElse();
    }

    public interface ISomeClass_Version3
    {
        string Something { get; }

        string DoSomethingElse();

        string DoSomethingElseAgain();
    }

    public class SomeClass : ISomeClass_Version2,
                             ISomeClass_Version3
    {
        // 0=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=O Original O=~~~~~~~~~~~~~~~~~~~~~~~~~~~=O
        // These various members represent an original implementation.
        //        *** these of course should never be altered unless it's a bug.
        //        *** If it is no longer valid, it should be marked with the 
        //        *** ObsoleteAttribute, it's not until the ObsoleteAttribute is 
        //        *** marked so that it disallows compile should the code within be 
        //        *** COMMENTED OUT and replaced with a 
        //        ***            'throw new NotSupportedException()' 
        //        *** incase of casual late-binding or reflection access.  
        //        ***        The actual method stubs should not be removed!
        public string Something
        {
            get { return "DoSomething - Version 1"; }
        }

        public void DoSomething()
        {
            Console.WriteLine(this.DoSomethingElse());
        }

        public string DoSomethingElse()
        {
            return this.Something;
        }

        // 0=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=O Version 2 O=~~~~~~~~~~~~~~~~~~~~~~~~~~=O
        // This represents a subsequent version that requires a slightly different
        // functionality requirement from a method.  This method is only visible 
        // though the explicit interface definition used below.  this also shows that
        // the original implementation is of course still available.
        //
        //    of course, after formal release, the same no-touch philosophy applies 
        //  and any future work must be part of a version 3 interface.
        string ISomeClass_Version2.DoSomethingElse()
        {
            return this.Something.Replace('1', '2');
        }

        // 0=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=O Version 3 O=~~~~~~~~~~~~~~~~~~~~~~~~~~=O
        // This represents yet another subsequent version. This shows further 
        // requirement differences from the members within the class.
        //
        string ISomeClass_Version3.Something
        {
            get { return "DoSomething - Version 3"; }
        }

        string ISomeClass_Version3.DoSomethingElse()
        {
            // To access the newer version of the property, use this...
            return ( this as ISomeClass_Version3 ).Something;
        }

        string ISomeClass_Version3.DoSomethingElseAgain()
        {
            // this demonstrates that it is still ok to reference to previous 
            // explicitly interfaced methods... again using the interface cast.
            return ( this as ISomeClass_Version2 ).DoSomethingElse() 
                   + " Called from V3!";
        }
    }

    internal class Program
    {
        private static void Main()
        {
            SomeClass original1 = new SomeClass();

            Console.WriteLine(original1.Something);
            original1.DoSomething();
            Console.WriteLine(original1.DoSomethingElse());

            ISomeClass_Version2 iV2A = original1;

            Console.WriteLine(iV2A.DoSomethingElse());

            ISomeClass_Version3 iV3A = original1;

            Console.WriteLine(iV3A.DoSomethingElse());
            Console.WriteLine(iV3A.DoSomethingElseAgain());

            // above is same as below. It shows no difference 
            // even if individually instantiated...

            SomeClass original2 = new SomeClass();

            Console.WriteLine(original2.Something);
            original2.DoSomething();
            Console.WriteLine(original2.DoSomethingElse());

            ISomeClass_Version2 iV2B = new SomeClass();

            Console.WriteLine(iV2B.DoSomethingElse());

            ISomeClass_Version3 iV3B = new SomeClass();

            Console.WriteLine(iV3B.DoSomethingElse());
            Console.WriteLine(iV3B.DoSomethingElseAgain());

            Console.ReadLine();
        }
    }
}

Tags: , ,

Articles

Powered by BlogEngine.NET 1.5.0.7

About Matt R.Warren

MeMy name is Matt and I am the current tenant of this small corner of the internet. I mostly architect, design and prototype applications that use .NET with C# and a little C++/CLI for Enterprise although I am aware of and enjoy fully embracing Java based solutions and alternatives such as Mono/Linux.  

I have worked on projects ranging from small tools to large distributed real-time Enterprise systems ranging from EPOS and real-time/JIT stock management systems, to distributed applications for National/International Utility, Healthcare, Insurance and Finance  in the private sector in both the USA and the EU.

My LinkedIn Profile (Opens new window/tab)

“Matt is one of the brightest people I've worked with. His in-depth knowledge of the .NET frameworks has been a tremendous benefit to nVISIA and our clients. His knowledge of software architecture in general allows him to architect systems for the best fit to his client's needs.” 
Dan Christopherson , Technical Director , nVISIA

“I had the distinct pleasure of working with Matt at nVisia. Matt's understanding of the Microsoft Technical space is outstanding. He is constantly working on improving his technical skills and rapidly masters any new technology that he encounters. He is an excellent teacher and a wonderful asset for any size team.” 
Jim Harnden , Senior Technical Architect , nVISIA

“Matt Warren is a very talented developer with great capacity for self study, investigation and adapts to new languages and frameworks with ease. He has an excellent grasp of software architecture and modern development principles. He has proven himself time and time again to be a hard worker and someone who can get the job done when you're in a tight spot.” 
Andrew Jump , Partner, C# Developer , Contegra

This website represents some of my spare time.  My small presence on the web between my family and my career.  I hope over time you find many useful things here.