Friday, 14 July 2017

Interface Parameters in C#

So I started my new job and noticed in the code I am working on has great use of Interfaces. I became a bit confused about them being passed as method parameters:
public string GetCharacteristics(IApple Apple)
{
...
}

When an object instance is passed as an interface parameter instead of an object, it brings an important benefit of polymorphism. This looser temporal coupling between objects allows you to cleanly separate the class design from its implementation. You then simply pass in any object as an interface parameter to a method and all object parameters can be accessed using the same methods and properties. However, all object class definitions have to implement the expected interface.
public interface IApple
{
        string Type { get; set; }
        string Colour { get; set; }

        int Sweetness();

        bool IsEdible(); 
}

To me this seems like a form of generics, because I can potentially write the same code to handle a variety of object inputs of differing types.
public class Blender : IFruitOperations 
    {
        private int GetDrinkSweetness(IApple Apple)
        {
            return Apple.Sweetness(); 
        }

        public string GetCharacteristics(IApple Apple)
        {
            string Result = 
                $"Apple {Apple.Type} has " +
                $"{GetDrinkSweetness(Apple)} sweetness, ";

            if (Apple is GrannySmith)
                Result += $"and bitterness {(Apple as GrannySmith).Bitterness}. ";
            else if (Apple is PinkLady)
                Result += $"and tastiness {(Apple as PinkLady).Tastiness}. ";

            return Result; 
            
        }

    }


Some example code for future reference, I designed it in such a way that we have specific properties. They are accessed by casting the interface to the specific class type, for example GrannySmith (for Bitterness) or PinkLady (for Tastiness).

We also have decoupled implementations of the interface, as methods Sweetness and IsEdible, however because we are passing interfaces as parameters, we are able to access the unique implementations generically, via GetDrinkSweetness and GetCharacteristics methods.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InterfaceTest
{

    public interface IApple
    {
        string Type { get; set; }
        string Colour { get; set; }

        int Sweetness();

        bool IsEdible(); 
    }


    public interface IFruitOperations
    {
        string GetCharacteristics(IApple Apple); 
    }


    public class GrannySmith : IApple
    {
        public string Type { get; set; }
        public string Colour { get; set; }

        public int Bitterness { get; set; } 

        public int Sweetness()
        {
            return 1; 
        }

        public bool IsEdible()
        {
            return true; 
        }

        public GrannySmith()
        {
            Type = "Granny Smith";
            Colour = "Green";
            Bitterness = 5; 
        }
    }

    public class PinkLady: IApple
    {
        public string Type { get; set; } 
        public string Colour { get; set; } 

        public int Tastiness { get; set; } 

        public int Sweetness()
        {
            return -1; 
        }

        public bool IsEdible()
        {
            return false; 
        }

        public PinkLady()
        {
            Type = "Pink Lady";
            Colour = "Pink";
            Tastiness = -5; 
        }
    }


    public class Blender : IFruitOperations 
    {
        private int GetDrinkSweetness(IApple Apple)
        {
            return Apple.Sweetness(); 
        }

        public string GetCharacteristics(IApple Apple)
        {
            string Result = 
                $"Apple {Apple.Type} has " +
                $"{GetDrinkSweetness(Apple)} sweetness, ";

            if (Apple is GrannySmith)
                Result += $"and bitterness {(Apple as GrannySmith).Bitterness}. ";
            else if (Apple is PinkLady)
                Result += $"and tastiness {(Apple as PinkLady).Tastiness}. ";

            return Result;             
        }

    }


    class Program
    {
        static void Main(string[] args)
        {

            Blender MyBlender = new Blender(); 

            IApple Apple1 = new GrannySmith();
            Console.WriteLine(MyBlender.GetCharacteristics(Apple1));
            Console.WriteLine(
                "Edible? {0}",
                Apple1.IsEdible() ? "Yes" : "No");  


            IApple Apple2 = new PinkLady();
            Console.WriteLine(MyBlender.GetCharacteristics(Apple2));
            Console.WriteLine(
                "Edible? {0}",
                Apple2.IsEdible() ? "Yes" : "No"); 

            Console.ReadLine(); 

        }
    }


}

Tuesday, 13 June 2017

Web API REST Owin + Katana


A memo to myself about Web API REST code using Owin Katana packages.


Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;



using Owin;
using Microsoft.Owin.Hosting;

using System.IO;

using System.Web.Http; 




namespace KatanaIntro
{


    // AppFunc alias. 
    using AppFunc = Func<IDictionary<string, object>, Task>; 


    class Program
    {
        static void Main(string[] args)
        {

            string Uri = "http://localhost:12345";

            using (WebApp.Start<Startup>(Uri))
            {
                Console.WriteLine("Web server started and listening ... ");
                Console.ReadKey();
                Console.WriteLine("Web server stopping ... "); 
            }


        }
    }





    public class Startup
    {


        public void Configuration(IAppBuilder App)
        {


            //// Return welcome page. 
            //App.UseWelcomePage();


            // Katana wrapper for OWIN. 
            //App.Run(
            //    // Use lambda to access the function. 
            //    ctx =>
            //    {
            //        // Access function data. 
            //        // Return a task. 
            //        // ctx.


            //        // Hello world. 
            //        return ctx.Response.WriteAsync("Hello world!");


            //    }
            //);




            // Test. 
            //App.Run(Context =>
            //{

            //    Context.Response.ContentType = "text/plain";
            //    return Context.Response.WriteAsync("Testing using content type ... ");

            //}
            //);



             


            // Dump environment. 
            //App.Use(async (ContextEnvironment, Next) =>
            //{

            //   foreach (var Item in ContextEnvironment.Environment)
            //       Console.WriteLine("{0}:{1}", Item.Key, Item.Value);

            //   await Next();


            //});



            // Dump request. 
            App.Use(async (ContextEnvironment, Next) =>
            {
                Console.WriteLine("Requesting: " + ContextEnvironment.Request.Path);
                await Next();

                //ContextEnvironment.Response.StatusCode = 404; 

                Console.WriteLine("Response: " + ContextEnvironment.Response.StatusCode); 
            });





            ConfigureWebApi(App); 



            // Use HelloWorldComponent. 
            App.Use<HelloWorldComponent>();

            // Syntactic sugar call. 
            //App.UseHelloWorld();




        }


        private void ConfigureWebApi(IAppBuilder App)
        {

            var Config = new HttpConfiguration();

            Config.Routes.MapHttpRoute(
                "DefaultApi",
                "api/{controller}/{id}",
                new { id = RouteParameter.Optional }
            );

            App.UseWebApi(Config); 

        }



    }




    // Syntactic sugar definition. 
    public static class AppBuilderExtensions
    {
        public static void UseHelloWorld(this IAppBuilder App)
        {
            App.Use<HelloWorldComponent>(); 
        }
    }




    public class HelloWorldComponent
    {

        AppFunc _NextComponent; 

        public HelloWorldComponent(AppFunc NextComponent)
        {
            _NextComponent = NextComponent;
        }


        //public Task Invoke(IDictionary<string, object> Environment)
        // public async Task Invoke(IDictionary<string, object> Environment)
        public Task Invoke(IDictionary<string, object> Environment)
        {
            //return null; 

            // await _NextComponent(Environment);  

            var Response = Environment["owin.ResponseBody"] as Stream;
            using (var Writer = new StreamWriter(Response))
                return Writer.WriteAsync("Hello using StreamWriter and owin.ResponseBody ... "); 

        }

    }



}



Models/Greeting.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KatanaIntro
{
    public class Greeting
    {
        public string Text { get; set; }
    }

}



Controllers/GreetingController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Web.Http; 


namespace KatanaIntro
{
    public class GreetingController : ApiController
    {
        [AllowAnonymous] 
        [Route("api/Greeting")] 
        public Greeting Get()
        {
            return new Greeting { Text = "Hello world!" }; 
        }

    }

}



Notes to self:
1. Dlls not copied into bin folder (causes 404s).

2. App.config not copied into Web.config (causes http error 500).
Could not load file or assembly 'Microsoft.Owin, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies.
The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)


Notes on executing: 

Check KatanaIntro properties, Output type = Class Library (dll for IIS Express) or Console App (standalone exe).

cd "C:\Users\DaviesE\Documents\MyWork\Visual Studio 2015\Projects\KatanaIntro\KatanaIntro"

IIS/Local/Debug
http://localhost:12345/api/Greeting

"c:\Program Files\IIS Express\iisexpress.exe" /path:"C:\Users\DaviesE\Documents\MyWork\Visual Studio 2015\Projects\KatanaIntro\KatanaIntro"

"c:\Program Files\IIS Express\iisexpress.exe" /path:"C:\Users\DaviesE\Documents\MyWork\Visual Studio 2015\Projects\KatanaIntro\KatanaIntro" /port:12345



References:


What are C# Generics?

So I don’t forget what C# Generics are, I created this memo + code (or memode).

Generics templatise your code maximising reuse, keeping it strongly typed and performant. Any type can be generic, but it is advised to use the new generic collection classes System.Collections.Generic inso System.Collections. You can use runtime reflection to get info about generic types.

Here is some code using generics on different types.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTest
{


    // Generic array definition. 
    public class MyGenericArray<X>
    {

        private X[] Array; 

        public MyGenericArray(int Size)
        {
            Array = new X[Size + 1];
        }

        public X GetItem(int Index)
        {
            return Array[Index];
        }

        public void SetItem(int Index, X Value)
        {
            Array[Index] = Value; 
        }

    }



    // Generic method definition. 
    public static class GenericMethod<T>
    {
        public static void Swap(ref T Left, ref T Right)
        {
            T Temp = Left;
            Left = Right;
            Right = Temp; 
        }
    }



    

    // Define test interface. 
    public interface ITest
    {
        int GetPropertyValue(); 
    } 

    // Inherit from ITest interface. 
    public class MyClassTest : ITest
    {

        private int MyProperty { get; set; }

        public MyClassTest(int InitialValue)
        {
            MyProperty = InitialValue;
        }


        // To prove our generic swap function works, 
        // we will nest a class within a class. 
        // The inner class has a method to get the property. 
        public int GetPropertyValue()
        {

            // Initialise. 
            Value MyValue = new Value(MyProperty);

            MyProperty = MyValue.GetPropertyValue();

            return MyProperty; 
            
        }


        // Finer precision of interface. 
        public interface IValue
        {
            int GetPropertyValue(); 
        }


        // Inherit from IValue interface.  
        public class Value : IValue
        {

            private int MyProperty { get; set; }

            public Value(int Value)
            {
                MyProperty = Value; 
            }

            public int GetPropertyValue()
            {
                return MyProperty; 
            }

        }

    }






    // Define test interface that contains another interface. 
    public interface ITestInterface : ITestAnotherInterface 
    {
        int MyProperty { get; set; } 
    }

    public interface ITestAnotherInterface
    {
        int MyPropertyAnother { get; set; }
    } 

    // Declare test class using multiple interfaces. 
    public class MultiInterface : ITestInterface
    {

        private int PropertyBase;
        private int PropertyAnother;

        public int MyProperty
        {
            get { return PropertyBase;  }
            set { PropertyBase = value;  }
        }

        public int MyPropertyAnother
        {
            get { return PropertyAnother;  }
            set { PropertyAnother = value;  }
        }


    } 



    // Define test interface. 
    public interface ITestOddEven {
        int GetValue(); 
    }

    // Declare test classes. 
    public class OddTest : ITestOddEven
    {
        private const int Even = 2;
        private const int Odd = 3;
        
        public int GetValue()
        {
            return Odd; 
        }

    } 

    public class EvenTest : ITestOddEven
    {
        private const int Even = 2;
        private const int Odd = 3;

        public int GetValue()
        {
            return Even;
        }
    }




    // Define test delegate. 
    public delegate int TestGetValue();





    class Program
    {



        static void Main(string[] args)
        {


            Random Generate = new Random();

            string Characters =
                "$%#@!*abcdefghijklmnopqrstuvwxyz" +
                "1234567890?;:ABCDEFGHIJKLMNOPQRSTUVWXYZ^&";



            // Create generic int array. 
            MyGenericArray<int> IntArray = new MyGenericArray<int>(5);

            // Set values. 
            for (int Index = 0; Index < 5; Index++)
                IntArray.SetItem(Index, Generate.Next(1, 9999999));

            // Get values. 
            for (int Index = 0; Index < 5; Index++)
                Console.WriteLine(IntArray.GetItem(Index));





            // Create generic char array. 
            MyGenericArray<char> CharArray = new MyGenericArray<char>(5);

            // Set values. 
            for (int Index = 0; Index < 5; Index++)
                CharArray.SetItem(Index, Characters[Generate.Next(0, Characters.Length - 1)]);

            // Get values. 
            for (int Index = 0; Index < 5; Index++)
                Console.WriteLine(CharArray.GetItem(Index));





            // Create generic string array. 
            MyGenericArray<string> StringArray = new MyGenericArray<string>(5);

            // Set values. 
            for (int Index = 0; Index < 5; Index++)
            {

                string Value = "";

                for (int StringIndex = 0; StringIndex < 10; StringIndex++)
                    Value += Characters[Generate.Next(0, Characters.Length - 1)];

                StringArray.SetItem(Index, Value);

            }

            // Get values. 
            for (int Index = 0; Index < 5; Index++)
                Console.WriteLine(StringArray.GetItem(Index));





            // Create generic double array. 
            MyGenericArray<double> DoubleArray = new MyGenericArray<double>(5);

            // Set values. 
            for (int Index = 0; Index < 5; Index++)
                DoubleArray.SetItem(Index, Math.Round(Generate.NextDouble() *
                    Generate.Next(1, 1000), 2));

            // Get values. 
            for (int Index = 0; Index < 5; Index++)
                Console.WriteLine(DoubleArray.GetItem(Index));





            // Create generic byte array. 
            MyGenericArray<byte[]> ByteArray = new MyGenericArray<byte[]>(5);

            // Set values. 
            for (int Index = 0; Index < 5; Index++)
            {
                byte[] ByteBuffer = new byte[10];
                Generate.NextBytes(ByteBuffer);
                ByteArray.SetItem(Index, ByteBuffer);
            }

            // Get values. 
            Console.WriteLine("Getting byte array values:");
            for (int Index = 0; Index < 5; Index++)
            {
                Console.WriteLine(ByteArray.GetItem(Index).GetValue(0));
            }

            // Get values. 
            Console.WriteLine("Getting byte array values:");
            for (int Index = 0; Index < 5; Index++)
            {
                Console.WriteLine(ByteArray.GetItem(Index).GetValue(9));
            }





            // Byte test. 
            Byte Test = new Byte();
            Test = 0x99;
            Console.WriteLine("Byte test = {0}", Test.ToString());





            // Generic methods. 


            int A = 1, B = 2;
            // Before. 
            Console.WriteLine("Before");
            Console.WriteLine("A = {0}, B = {1}", A, B);
            // Swap. 
            GenericMethod<int>.Swap(ref A, ref B);
            // After. 
            Console.WriteLine("After");
            Console.WriteLine("A = {0}, B = {1}", A, B);


            char X = 'x', Y = 'y';
            // Before. 
            Console.WriteLine("Before");
            Console.WriteLine("X = {0}, Y = {1}", X, Y);

            GenericMethod<char>.Swap(ref X, ref Y);
            // After. 
            Console.WriteLine("After");
            Console.WriteLine("X = {0}, Y = {1}", X, Y);




            // Generate List string array. 
            List<string> MyStringList = new List<string>(4);
            // Populate. 
            for (int ItemIndex = 0; ItemIndex < 4; ItemIndex++)
            {
                var Value = "";

                for (int Index = 0; Index < 3; Index++)
                    Value += Characters[Generate.Next(0, Characters.Length - 1)];

                MyStringList.Add(Value);
            }
            // Before. 
            Console.WriteLine("Before");
            foreach (var ListItem in MyStringList.Cast<object>().Select((x, i) => new { Item = x, Index = i }))
                Console.WriteLine("Item[{0}] = {1}", ListItem.Index, ListItem.Item);

            // Swap all items. 
            //foreach (var ListItem in MyStringList.Cast<object>().Select((x, i) => new { Item = x, Index = i })) ; 
            for (int Index = 0; Index < 4; Index++)
            {

                // End reached, nothing to swap.    
                if (Index == MyStringList.Count() - 1)
                    continue;

                var Current = MyStringList[Index];
                var Next = MyStringList[Index + 1];

                GenericMethod<string>.Swap(ref Current, ref Next);

                MyStringList[Index] = Current;
                MyStringList[Index + 1] = Next;

            }

            // After. 
            Console.WriteLine("After");
            foreach (var ListItem in MyStringList.Cast<object>().Select((x, i) => new { Item = x, Index = i }))
                Console.WriteLine("Item[{0}] = {1}", ListItem.Index, ListItem.Item);




            // Create test class instances. 
            MyClassTest TestClass1 = new MyClassTest(5);
            MyClassTest TestClass2 = new MyClassTest(10);



            // MyClassTest[] TestClasses = new MyClassTest[2];  
            //{
            //    new MyClassTest(), 
            //    new MyClassTest()
            //};
            //TestClasses[0] = TestClass1;
            //TestClasses[1] = TestClass2;


            //Console.WriteLine(nameof(TestClass1));
            //Console.WriteLine(nameof(TestClass2));


            // Before. 
            Console.WriteLine("Before");
            Console.WriteLine(
                "TestClass1.GetPropertyValue() = {0}, TestClass2.GetPropertyValue() = {1} ",
                TestClass1.GetPropertyValue(), TestClass2.GetPropertyValue());

            // Swap. 
            GenericMethod<MyClassTest>.Swap(ref TestClass1, ref TestClass2);

            // After. 
            Console.WriteLine("After");
            Console.WriteLine(
                "TestClass1.GetPropertyValue() = {0}, TestClass2.GetPropertyValue() = {1} ",
                TestClass1.GetPropertyValue(), TestClass2.GetPropertyValue());





            // Create test classes with multiple interfaces. 
            MultiInterface MultiInterfaceTest1 = new MultiInterface();
            MultiInterfaceTest1.MyProperty = 1;
            MultiInterfaceTest1.MyPropertyAnother = 2;

            MultiInterface MultiInterfaceTest2 = new MultiInterface();
            MultiInterfaceTest2.MyProperty = 3;
            MultiInterfaceTest2.MyPropertyAnother = 4;

            // Before. 
            Console.WriteLine("Before");
            Console.WriteLine("MultiInterfaceTest1.MyProperty = {0}", MultiInterfaceTest1.MyProperty);
            Console.WriteLine("MultiInterfaceTest1.MyPropertyAnother = {0}", MultiInterfaceTest1.MyPropertyAnother);
            Console.WriteLine("MultiInterfaceTest2.MyProperty = {0}", MultiInterfaceTest2.MyProperty);
            Console.WriteLine("MultiInterfaceTest2.MyPropertyAnother = {0}", MultiInterfaceTest2.MyPropertyAnother);

            // Swap interfaces. 
            GenericMethod<MultiInterface>.Swap(ref MultiInterfaceTest1, ref MultiInterfaceTest2);

            // After. 
            Console.WriteLine("After");
            Console.WriteLine("MultiInterfaceTest1.MyProperty = {0}", MultiInterfaceTest1.MyProperty);
            Console.WriteLine("MultiInterfaceTest1.MyPropertyAnother = {0}", MultiInterfaceTest1.MyPropertyAnother);
            Console.WriteLine("MultiInterfaceTest2.MyProperty = {0}", MultiInterfaceTest2.MyProperty);
            Console.WriteLine("MultiInterfaceTest2.MyPropertyAnother = {0}", MultiInterfaceTest2.MyPropertyAnother);




            // Swap values in individual interfaces. 
            Console.WriteLine("Swapping values in individual interfaces ... ");
            int BaseValue = MultiInterfaceTest1.MyProperty;
            int AnotherValue = MultiInterfaceTest1.MyPropertyAnother;
            GenericMethod<int>.Swap(ref BaseValue, ref AnotherValue);
            MultiInterfaceTest1.MyProperty = BaseValue;
            MultiInterfaceTest1.MyPropertyAnother = AnotherValue;

            BaseValue = MultiInterfaceTest2.MyProperty;
            AnotherValue = MultiInterfaceTest2.MyPropertyAnother;
            GenericMethod<int>.Swap(ref BaseValue, ref AnotherValue);
            MultiInterfaceTest2.MyProperty = BaseValue;
            MultiInterfaceTest2.MyPropertyAnother = AnotherValue;

            // After. 
            Console.WriteLine("After");
            Console.WriteLine("MultiInterfaceTest1.MyProperty = {0}", MultiInterfaceTest1.MyProperty);
            Console.WriteLine("MultiInterfaceTest1.MyPropertyAnother = {0}", MultiInterfaceTest1.MyPropertyAnother);
            Console.WriteLine("MultiInterfaceTest2.MyProperty = {0}", MultiInterfaceTest2.MyProperty);
            Console.WriteLine("MultiInterfaceTest2.MyPropertyAnother = {0}", MultiInterfaceTest2.MyPropertyAnother);




            // Create interface variables. 
            ITestOddEven TestOddEven1 = new OddTest();
            ITestOddEven TestOddEven2 = new EvenTest();

            // Before. 
            Console.WriteLine("Before");
            Console.WriteLine("TestOddEven1.GetValue() = {0}", TestOddEven1.GetValue());
            Console.WriteLine("TestOddEven1.GetValue() = {0}", TestOddEven2.GetValue());

            // Swap out the GetValue methods by interface references. 
            GenericMethod<ITestOddEven>.Swap(ref TestOddEven1, ref TestOddEven2);

            // After. 
            Console.WriteLine("After");
            Console.WriteLine("TestOddEven1.GetValue() = {0}", TestOddEven1.GetValue());
            Console.WriteLine("TestOddEven1.GetValue() = {0}", TestOddEven2.GetValue());



            // Create delegates. 
            TestGetValue TestDelegateEven = TestOddEven1.GetValue;
            TestGetValue TestDelegateOdd = TestOddEven2.GetValue;

            // Before. 
            Console.WriteLine("Before");
            Console.WriteLine("TestDelegateEven = {0}", TestDelegateEven());
            Console.WriteLine("TestDelegateOdd = {0}", TestDelegateOdd());

            // Swap around method references using delegates. 
            GenericMethod<TestGetValue>.Swap(ref TestDelegateEven, ref TestDelegateOdd);

            // After. 
            Console.WriteLine("After");
            Console.WriteLine("TestDelegateEven = {0}", TestDelegateEven());
            Console.WriteLine("TestDelegateOdd = {0}", TestDelegateOdd());






            // Create delegates to test method parameters. 
            NumberFunction<int> FunctionTestAdd = new NumberFunction<int>(Add);
            NumberFunction<int> FunctionTestMultiply = new NumberFunction<int>(Multiply);

            // Before. 
            Console.WriteLine("Before");
            Console.WriteLine("FunctionTestAdd(2) = {0}", FunctionTestAdd(2));
            Console.WriteLine("FunctionTestMultiply(4) = {0}", FunctionTestMultiply(4));

            // Swap delegate references to methods. 
            GenericMethod<NumberFunction<int>>.Swap(ref FunctionTestAdd, ref FunctionTestMultiply);
            Console.WriteLine("Swapping delegate method references ...");
            Console.WriteLine("FunctionTestAdd(3) = {0}", FunctionTestAdd(3));
            Console.WriteLine("FunctionTestMultiply(1) = {0}", FunctionTestMultiply(1)); 







            Console.ReadLine();

        }


        // Define test generic delegate. 
        public delegate T NumberFunction<T>(T Value);

        // Define test methods for the delegate.  
        private static int Total = 0;

        public static int Add(int Number)
        {
            return Total += Number;
        }

        public static int Multiply(int Number)
        {
            return Total *= Number;
        }


    }

}

How to use C# Delegates?


Writing this mostly for when I need a quick snippet, but in case someone finds this useful.

The C# delegate beast is an object which holds references to methods (think “object-like method” that can be strong typed and therefore checked, unlike C++ function pointers), so this makes them super useful to pass as method parameters or to run a bunch of methods in event callbacks. This particular example uses Reactive Extensions so you will need to install them with Nuget.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Subjects;

namespace DelegateTest
{

    // Delegate definition. 
    public delegate void ProcessDelegate();

    public class Processor {

        // Reactive observable. 
        public Subject<Task> Observable = new Subject<Task>();

        // Task to process. 
        public void Process(Task Process) {
            Process.Start();
        }

        // Delegate instance. 
        public ProcessDelegate ProcessInstance;

        // Constructor. 
        public Processor(IEnumerable<ProcessDelegate> Processes, ProcessDelegate ProcessCompleted)
        {
            // Initialise delegate instance. 

            // Add process methods. 
            foreach (var Process in Processes)
                ProcessInstance += Process;
            
            // Add process completed method. 
            ProcessInstance += ProcessCompleted; 
        }       

    }







    public class Program
    {

        static void Main(string[] args)
        {

            Console.WriteLine("Starting process test ...");

            // Create test process object. 
            Processor Test = new Processor(

                // Delegate implementations. 
                new List<ProcessDelegate>
                {
                    () => {
                        string Result = "";
                        for(int Index = 0; Index < 100; Index++)
                            Result += Index.ToString();
                        Console.WriteLine("Process 1 finished = " + Result.Substring(0, 10) + " ... ");
                    },
                    () => {
                        string Result = "";
                        for(int Index = 0; Index < 100; Index++)
                            Result += Index.ToString();
                        Console.WriteLine("Process 2 finished = " + Result.Substring(0, 10) + " ... ");
                    },
                    () => {
                        string Result = "";
                        for(int Index = 0; Index < 100; Index++)
                            Result += Index.ToString();
                        Console.WriteLine("Process 3 finished = " + Result.Substring(0, 10) + " ... ");
                    }
                }, 

                () =>
                {
                    Console.WriteLine("Processes completed ... ");
                }

            );


            // Assign processes/delegate to an observable task. 
            Test.Observable.Subscribe(
                Value => Test.Process( Value ), 
                () =>
                {
                    Console.WriteLine("Observable OnCompleted called ... ");
                }
            );

            // Run action on the observable. 
            // Assigning delegate implementations. 
            Test.Observable.OnNext(
                new Task(new Action(Test.ProcessInstance))); 

            Console.WriteLine("Carrying on with some other tasks ..."); 
            

            Console.ReadLine(); 

        }

    }

}


Handy links:


Monday, 20 February 2017

How to stay awake at work (after doing weekend work).

Over the weekend I had to do a bunch of coding and crack my brain for a solution.
Monday morning I was back at it again coding after only a few hours sleep, not to mention having to do boring administration work at work. I always like to get my good 8 hours of ole sleep, so not like I do this all the time!

I knew that I would suffer a lot, because we have to keep up a high level of concentration at work. After some googling I found some stuff that I thought would help inspire me to keep awake, but I then thought to share my own spin on it.

So my top tips are:

1. Switch up your tasks when you feel yourself drifting off.
Work on something else for a bit or something more exciting, stay away from boring stuff.

2. Play music, youtube etc.
I hit the good old tube, I find some chillout mixes to be particularly effective.

3. Take a few breaks throughout the day.
Can take some strategic toilet breaks and close your eyes to rest them.

4. Also stare into the distance/out of a window (so called "eye breaks").

5. Eat some tasty food and drink plenty of water.
Of course glug down a coffee =) Listen to your body, it doesn't have to be super healthy in my books.

6. This my favourite one, sneak a bunch of drawing in your notebook.
Drawing can open up your imagination, it helps you to create ideas, and activates your right brain. This can potentially take the load off your left brain doing all the work and therefore makes you feel less tired.


Friday, 17 February 2017

Creating XML, XSD, validating Test Instance XML and Text (Native) Files, and tips for Biztalk project issues in Visual Studio 2013/5

This is just a quick memo for myself regarding XML, XSD and creating/validating test instances of XML and Text files.

XML (Extensible Markup Language) is pretty much like a text file and can be opened as such, but with the addition of tags to describe the text information. Extensible here means that even if we make modifications to the XML text file, it is still usable by other users and software. In other words changes can be made dynamically to the XML file without it causing problems in software that uses the XML. More info here: www.w3schools.com/xml/xml_whatis.asp

XSD (XML Schema Definition) and can be used to control how exactly an XML document can appear. XML files do not need XSD files, but if you want a mechanism to check the structure and information is correct within an XML file, then an XSD file can be used. For example, an XSD file can define what tags are allowed including their nesting structure, the names of the tags and the order in which they appear in an XML file. The XSD file can also define what type of information the tags can contain, as well as their default value or an expected (fixed) value.

Creating an XSD file 
There are two ways to create an XSD file, firstly by hand, for example in Visual Studio you can use the Schema Editor and using an XML file or other reference create the structure.
  creating-new-xsd

The second method involves generating the XSD file from an XML file. This method will not give you control of what values and information the tags can contain. This can be added later using the Schema Editor, once the file is generated.

Validating / Testing the XSD 
Once you have created the XSD you can do a simple schema check in Visual Studio, right-click the XSD file and select Validate Schema.

validate-an-xsd-file

Creating a Test Instance XML/Text (Native) file 
Once your XSD has been created, you can in Visual Studio set the name of the test instance file and select type as either XML or Native Text file in the XSD properties. Then right-click the XSD and click Generate Instance.

generating-a-test-instance

Validating / Testing the Test Instance XML/Text (Native) file 
Similarly, once you have a test instance of the XML or Text (Native) file you can then test and validate it against your XSD file. Click your XSD file in Visual Studio, under Properties, go to General > Input Instance Filename and set it to the file name of the test instance or an XML file you created. Then set General > Validate Instance Input Type to XML or Native file depending on the type of file. Right-click the XSD and click Validate Instance to test your XSD file definitions against the XML or Text (Native) file.

validating-a-test-instance

Tips:

Flat File Schemas 
https://msdn.microsoft.com/en-us/library/aa561057.aspx?f=255&MSPPError=-2147217396

Unexpected data found while looking for: $Delimited$ 
https://social.msdn.microsoft.com/Forums/en-US/be46c68d-c36c-4713-b2ff-f79cda93ba7d/unexpected-data-found-while-looking-for-delimited?forum=biztalkgeneral

Postfix, prefix and infix 
 http://biztalk06.blogspot.co.uk/2008/10/postfix-infix-and-prefix.html

Early Termination with Position Flat Files
https://blogs.msdn.microsoft.com/skaufman/2004/05/07/early-termination-with-position-flat-files/

BizTalk Server: Teach me something new about Flat Files (or not) – Delimited Flat File Schema Optimizations 
https://blog.sandro-pereira.com/2015/10/23/biztalk-server-teach-me-something-new-about-flat-files-or-not-delimited-flat-file-schema-optimizations/

Viewing XSD as code 
http://stackoverflow.com/questions/3265971/viewing-xsd-as-code

Problem deploying Biztalk Application - Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) 
http://stackoverflow.com/questions/3460750/problem-deploying-biztalk-application-access-is-denied-exception-from-hresul

Wednesday, 2 November 2016

Using Sql Profiler 2014 to debug SqlCommand in C#

I found the SqlCommand C# class is tricky to debug in Visual Studio if you are using SqlParameter and you want to see the exact statement being executed on the server.

First of all, run a test query on a table in the database, you will need to run your C# application to generate the query. This will create an entry in the process list for that database, which you can filter in Sql Profiler 2014.

select * from master..sysdatabases
select * from master.sysprocesses where dbid = 11

Look for the database id (dbid) of the database you ran the query on, and then find all processes running for that database. In my case, the dbid was 11 and I ran the query to get all processes for that database.

Scroll to the program_name and copy the value.
Note: Remove any extra spaces, as the Sql field in the result will be padded with spaces.

Getting program name.jpg



Open up the Profiler, create a new trace. In my case, I only want to see the final command being executed, so I ticked SQL:BatchCompleted only, and unticked all the other events.

Click 'Column Filters...', under 'ApplicationName' paste in the value you got from the process list (program_name).

Remember to remove any extra spaces, otherwise the Profiler will not be able to match it correctly, this is a common mistake!


New trace settings.jpg 


Run your trace and execute your Sql commands either from a test query or your C# application.

Trace completed2.jpg


You should notice that the commands are easily checked in Sql Profile 2014 now and you can test your C# application by matching its program_name from master..sysprocesses.

You can filter the events neatly to only show the application you are debugging by ticking SQL:BatchCompleted event and filtering by Column item ApplicationName.


Thursday, 13 October 2016

The "Bus Factor"

I had not heard this before but a bus factor is the risk that if one of the developers in the team were to be hypothetically hit by a bus, then this reflects on how it would affect a project.

One of the obvious factors would be an immediate deficit in knowledge and experience. But it also highlights the problem of a single point of failure, where only one person is responsible for particular areas of the project.

I thought about this and it seems to me that there should be more paired programming, so that junior members are exposed to the processes of the more experienced developers. Over time and with experienced supervision, in a kind of mentor relationship, both parties will exchange important practical knowledge and experience until juniors could perform similar work as more experienced developers.

The idea is to have as many people as possible with practical knowledge about the project, so that anyone can jump in and take up the slack when the 'person hit by the bus' is not available.



Wednesday, 14 September 2016

Disappearing TabPage Title Text when adding to a SplitContainer Panel

On a project we had a problem where TabPage title text would disappear when a TabPage was added to a SplitContainer Panel. For a while I did not know how to solve this issue because it was not obvious what was causing it.

disappearing-tab-headertitle-text-in-splitcontainer

After some research, it appeared to be a known Microsoft issue as described in this post: https://bytes.com/topic/c-sharp/answers/457492-tabpage-text-disapearing

However, I was not convinced this would be an ideal solution. I wanted something quick and simple. I ran a test and noticed when adding TabPages to the test SplitContainer, that the TabPage title did not disappear. Also the test did not contain a MenuStrip control, which the client app did.

Then I suspected the menu was causing the problem, because it was overlapping the TabPage title, and the title text was not disappearing at all.

To solve it, I simply added some padding to the SplitContainer panel, to push it below the MenuStrip in the client application. Here is some code.

SplitContainer1.Panel1.Padding = new Padding(0, 27, 0, 0); 

27 represents the default height in pixels of a MenuStrip, the top padding on the SplitContainer panel should then clear the menu and the title text will show.