Friday, December 26, 2014

It’s harder to read code than to write it

When I started writing code for commercial projects ten years back (around 2003), I've learned an important lesson. I was assigned to write a function that serializes a data structure into XML string and send that in a SOAP body. I was very fast writing the module that mostly uses concatenation of BSTR objects in Visual C++ 6.0 in XML tags. But my mentor at that time was not happy when we were doing a review on that function. He told me to use the existing library functions (MSXML::IXMLDOMDocument2Ptr and DOMDocument6 etc) to do the job. I had no clue at that time why he was saying so. I never worked before with MSXML at that time. It was easy for me to write it with BSTR rather than reading the MSXML APIs for hours and going through all the hassles of it. I was really annoyed with this.

I am still not judging if he was right or wrong, but one thing for sure I learned from him (later when I spent more time in my profession) is that, I should have learned what MSXML is capable of and how to use that. And probably after I did so, I might actually would used that library instead of writing a new one.

Writing new code apparently sounds, looks easy. But it has a cost associated. It has to be maintained. More people need to be aware about this code. This is especially true when it comes to write something that is already released. One may get an escape re-writing something which was never shipped. But one should always think twice re-writing something that is released. It may nasty, hard to read, but it's tested, bugs were found and fixed and it has those knowledge embedded into it. Rewriting, often comes with high chances that it will reintroduce some new set of bugs that will have to be fixed and maintained. Since that early lesson learned, I have been through many situations where I felt, rewriting is the easiest solution that comes first in mind. But if the old code was released I really push myself to think and reconsider, if I really need a rewrite.

The issue sadly exists in a larger scale as well. When it comes to architect new solution, the same philosophy kicks in, it feels more comfortable to rewrite a new solution entirely rather than assemble the exisitng product modules and bring them gradually into the new platform. I think the culprit is the same in both cases. It's unwillingness to read and understand the existing product modules what drives us to think recreating the solution is the best way to go.

Fundamentally, I feel it's an issue of reading vs writing codes. I summed up all the events, I have experienced, I should rewrite, I have realized that almost in every instances, I was reluctant to read the exisitng codes. Which led me to the direction to think of a rewrite. This may feel like the right thing to do when I think as an individual, as a programmer. But it's hell wrong when I evaluate the decision from the organization perspective. It almost never gives a ROI.

I could never explain this better than the way Joel explained it before in his blog:

"Netscape 6.0 is finally going into its first public beta. There never was a version 5.0. The last major release, version 4.0, was released almost three years ago. Three years is an awfully long time in the Internet world. During this time, Netscape sat by, helplessly, as their market share plummeted. It's a bit smarmy of me to criticize them for waiting so long between releases. They didn't do it on purpose, now, did they? Well, yes. They did. They did it by making the single worst strategic mistake that any software company can make: They decided to rewrite the code from scratch."

Very recently I have had a circumstance where, I could (and honestly I felt) to rewrite the software because it's using socket IO and manual Xml based messaging on it. But I refrained myself to stop thinking in that direction that apparently looks catchy. Like Joel wrote:

We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by incremental renovation: tinkering, improving, planting flower beds.

Being in the architect position I had the privilege to set the direction. I had to convince lot of people/stakeholders that I don't feel we should rewrite this from day one. Instead we should take a pragmatic approach to seal the existing code into modules and interface that with more sophisticated technologies and gradually remove them form the stack. I am still unsure if the direction will bring success to us, but I am certain that the chances are much higher than the other way around.

Wednesday, February 5, 2014

Quick and easy self-hosted WCF services

I realized that I am not writing blogs for a long time. I feel bad about that, this post is an attempt to get out of the laziness.


I often find myself writing console applications that have a simple WCF service and a client that invokes that to check different stuffs. Most of the time, I want to have a quick service that is hosted using either NetTcpBinding or WsHttpBinding with very basic configurations. Which triggers the urge writing a bootstrap mechanism to easily write and host WCF services and consume them at ease. I am planning to extend the implementation into a more richer one gradually, but I have something already to do a decent kick off. Here's how it works.


Step 1 : Creating the contract


You need to create a class library where you can have your contract interfaces for the service you are planning to write. Something like following

    [ServiceContract(Namespace = "http://abc.com/enterpriseservices")]
    public interface IWcf
    {
        [OperationContract]
        string Greet(string name);
    }

Now you need to copy the WcfService.cs file into the same project. This file contain one big class named WcfService. That has the public methods to host services and also creating client proxies to invoke them. The class can be downloaded from this Git (https://github.com/MoimHossain/WcfServer) repository. Once you have it added into your project, go to step 2.


Step 2 : Creating Console Server project.


Create a console application that will host the service. Add a reference to the project created in step 1. Define your service implementation class as follows


    // Sample service
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class MyService : IWcf
    {
        public string Greet(string name)
        {
            return DateTime.Now.ToString() + name;
        }
    }

Finally modify the program.cs to have something like following

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // use WcfService.Tcp for NetTcp binding or WcfService.Http for WSHttpBinding

                var hosts = WcfService.DefaultFactory.CreateServers(
                    new List { typeof(MyService) },
                    (t) => { return t.Name; },
                    (t) => { return typeof(IWcf); },
                    "WcfServices",
                    8789,
                    (sender, exception) => { Trace.Write(exception); },
                    (msg) => { Trace.Write(msg); },
                    (msg) => { Trace.Write(msg); },
                    (msg) => { Trace.Write(msg); });

                Console.WriteLine("Server started....");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            Console.ReadKey();
        }
    }


At this point you should be able to hit F5 and run the server console program.


Step 3 : Creating Console client project


Create another console application and modify the program.cs to something like following


    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // use WcfService.Tcp for NetTcp binding or WcfService.Http for WSHttpBinding

                using (var wcf = 
                    WcfService.DefaultFactory.CreateChannel(Environment.MachineName, 8789, (t) => { return "MyService"; }, "WcfServices"))
                {
                    var result = wcf.Client.Greet("Moim");

                    Console.WriteLine(result);
                }
            }            
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }

You are good to go! Hope this helps somebody (at least myself).