Wednesday, April 10, 2013

Well Designed and Maintainable Code - Points to consider


Well designed and maintainable code-base helps in reducing the cost of development (including Change Requests and code enhancements).
(A) What makes a code-base well designed and maintained?
Every software application is developed with an intention of solving a problem. The problem is specified by means of requirements (SRS). It is in the interest of all the stakeholders that the requirements are elicited to the maximum extent possible.
As explained above, if a software is developed against a set of requirements (or use cases if UML is used) then it must be possible to test each and every requirement implemented by the software, distinctly. Testability ------ (1)
Since a software implements a pre-defined set of requirements, technically, it is possible to write the entire application in one single file !!! But then is that a good approach?  (If I were to develop a library).
Hence, it is always, better to divide the entire application into smaller parts (layers/modules). So Separation of Concerns (layers) is another key---- (2)
Each module in the software should cater only to a specific functionality. Single responsibility Principle--- (3)
All the modules in the software must be loosely coupled and highly cohesive inorder to create a maintainable application. The impact of a change in one module must be minimal on other modules---------- (4)
Often developers  are faced with same kind of problems and scenarios across a multitude of applications. In such scenarios, it is often better to go for tried-and-tested solutions. i.e. Design Patterns -------- (5)
Apart from the above, sufficient documentation by means of code comments and project artefacts, adherence to consistent naming convention, principles of OOP (viz. polymorphism,  encapsulation, Inheritance must be used whereever necessary) ---- (6)

But, if somebody is taking a technical interview then simple answers are not understood by the interviewers. So explain them as follows,
A well designed and maintainable software exhibits following principles,
1) Single Responsibility Principle -  Every class must serve one responsibility
2) Open/Close Principle - A module must be open for extension but closed for modification
3) Liskov Substitution - instances of derived classes should be able to replace all the base class references without breaking the code
4) Interface Segregation - prefer client specific interfaces over one generic interface.
5) Dependency Inversion - All the modules should be based on abstractions and not concrete classes. Use dependency injection instead of creating instances of temporary 'Helper' classes.
To summarise, a maintainable software must be SOLID in design. 

(B) What underlying principles or qualities do you look for in a system of classes that tells you they are well designed and maintainable?
A software consists of modules/components that act in cohesion to produce the necessary functionality. Now, every module is implemented by means of a set of classes (in OOP languages, structural languages like 'C' do not support 'class').
Classes must be written so that it adheres to the principles of OOP. For instance, having all the data members of the class as 'public' is possible but it is a bad practice and strongly discouraged. Data Hiding  -------- (1)
Classes can be inherited from other classes to maximise the code re-use and create a hierachy of similar classes. 'Is-A' relationship, inheritance ------ (2)
If the developer has a reason for not allowing a class to be inherited then he can do so by decorating his class using 'sealed' attribute ( in C#) Usage of appropriate attributes ----(3)
As far as possible, creating 'new' objects of a class within another class must be avoided. Instead inject the dependency by means of constructor/.NET property.------- (4)
No Hardcoding of any sort in the classes ---------------- (5)
Limiting one class to one .cs file is a good practice ------ (6)
Apart from the above, code comments, naming convention and testability (unit testing) of classes still holds true and that cannot be relaxed.

Monday, February 18, 2013

Implementing POST requests in .NET

Data transfer between the client and server takes place over the sockets and in byte format. Which means that anything a client needs to send to a server must be converted into bytes either implicitly or explicitly.
POST requests differ from other HTTP requests (apart from PUT) in the concept that in POST request, the client sends data in the 'body' of the HTTP packet. Hence we should understand how to send this data on the client side and at the same time how do we extract the body from the HTTP packet on the server side for further processing. Most of the sites only speak about the GET requests which are far simpler to consume by any client. It is the POST/PUT requests which needs to be understood very well.

As mentioned earlier, the data needs to be sent as a stream of bytes hence if you need to transfer an object of a class then it must be serialized into a stream of bytes by serialization. This post relates with JSON (de)serialization.

Lets take a look at some client and server side code in .NET.

Client Side:


string endPoint = "http://localhost:20909/surveyupload"; // endpoint address to send the data on
var request = (HttpWebRequest)WebRequest.Create(endPoint);
request.Method = "POST";          

string PostData = Newtonsoft.Json.JsonConvert.SerializeObject(survey); // JSON serialization

if (!string.IsNullOrEmpty(PostData))
{                  
         byte[] byteContent = Encoding.UTF8.GetBytes(PostData);                

         using (var writeStream = request.GetRequestStream())
         {
                writeStream.Write(byteContent, 0, byteContent.Length);
          }
  }



using (var response = (HttpWebResponse)request.GetResponse())
{
      var responseValue = string.Empty;

      if (response.StatusCode != HttpStatusCode.OK)
      {
              var message = String.Format("Request failed. Received HTTP {0}", response.StatusCode);
                        throw new ApplicationException(message);
       }

       // grab the response
       using (var responseStream = response.GetResponseStream())
       {
             if (responseStream != null)
             using (var reader = new StreamReader(responseStream))
             {
                   responseValue = reader.ReadToEnd();
               }
         }
}


Server side:
The following method is your sample function implemented on the server side, that maps to the endpoint request made from client.


public string GetFile(System.IO.Stream data)
        {
            string JSONInString = string.Empty;
            using (StreamReader reader = new StreamReader(data))
            {
                JSONInString = reader.ReadToEnd();
                reader.Close();            
            }
            // Deserialize the streamed byte data into the object of known type as below
            SurveyData ReceivedData = JsonConvert.DeserializeObject<SurveyData>(JSONInString);
            if (ReceivedData != null)
                return "Success";
            else
                return "Failed";
        }

That's it. It is very easy to implement the POST requests in .NET. The above client requests can be further elaborated depending upon the requirement. This may involve adding additional headers, modifying content-types, user-agent, etc. properties of the Http request.

For details regarding the importance of REST services, please refer to, http://intelligentfactory.blogspot.co.uk/2012/09/rest-services-primer-all-about-rest.html

Wednesday, October 31, 2012

Geolocation sample in HTML5

Geolocation is an interesting feature deployed by numerous mobile applications. It allows an application to find the location of mobile/device. And based on the location the application can provide various services or advertisements.

Geolocation in HTML5?
HTML5 allows one to use to geolocation services quite easily and within few minutes one should be able to see something working.

lets see an example of how to use the geo location in HTML5.

One needs to use the geolocation object exposed by the navigator in-order to  utilize its services. The geolocation object has 2 methods which provide the location information.
1) getCurrentPosition : to be used when the location information is required just once.
2) watchPosition : to be used when one needs to monitor or track the location periodically.

Both the methods have identical signatures. The arguments for each of the functions is as below,
a) Arg1 (Mandatory) : call back function, which will be called when the function call suceeds
b) Arg2 (Optional) : call back function, which will be called when the function call fails
c) Arg3 (Optional) : PositionOptions object

The following code will show a button and on clicking the button the virtual globe should be visible. In Firefox one would see the info bar and a message box prompting the user to accept the location information.

Paste the following code in the <body> of an html file.
<p>
<button onclick="GetMap()">Show map</button>
</p>
<div id="mapDiv" style="position: relative; width: 800px; height: 600px;"></div>
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
<script>

            var map = null;
            function GetMap() {
                /* Replace YOUR_BING_MAPS_KEY with your own credentials.
                    Obtain a key by signing up for a developer account at
                    http://www.microsoft.com/maps/developers/ */
                var cred = "<Your BING KEY>";
                // Initialize map
                map = new Microsoft.Maps.Map(document.getElementById("mapDiv"),
                    { credentials: cred });
                // Check if browser supports geolocation
                if (navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition(locateSuccess, locateFail);
                }
                else {
                    alert('I\'m sorry, but Geolocation is not supported in your current browser.');
                }
            }



           // Successful geolocation
            function locateSuccess(loc) {
               // Set the user's location
               var userLocation = new Microsoft.Maps.Location(loc.coords.latitude, loc.coords.longitude);
             
               // do your operations
            }

            // Unsuccessful geolocation
            function locateFail(geoPositionError) {
                switch (geoPositionError.code) {
                    case 0: // UNKNOWN_ERROR
                        alert('An unknown error occurred, sorry');
                        break;
                    case 1: // PERMISSION_DENIED
                        alert('Permission to use Geolocation was denied');
                        break;
                    case 2: // POSITION_UNAVAILABLE
                        alert('Couldn\'t find you...');
                        break;
                    case 3: // TIMEOUT
                        alert('The Geolocation request took too long and timed out');
                        break;
                    default:
                }
            }

</script>

That's it. Plain and simple to get location information in HTML5.

Sunday, September 9, 2012

REST Services : A Primer. All About Rest Services

Today we will understand how to consume the WCF REST services on the client side.
The theory of REST can be understood from numerous resources online. This post will explain how to make the different types of requests.

Why REST?
Anyone who has worked with web-services and WCF is often confused as to why one should create RESTful services when SOAP has been easy and good to use for so long. So the short answer for using REST is less data traffic on the network. Every data packet to be sent over SOAP is packaged in a bulky header.

The main verbs in a REST implementation are GET, PUT, POST. There are other verbs as well but they are infrequently used. One can try these requests by using a popular tool like WebFetch (we will discuss using the WebFetch tool in a later post)

Lets go to some practical examples:
In many applications viz the secured ones, every client is issued a certificate so that every REST request from the client is authenticated and then authorised to perform the operation (specified by the verb)

How to use the client certificates in REST:
HttpClient client = new HttpClient( <Url on which request is to be made> );

string certLoc = <certificate location>;
string certPwd = <certificate pwd>;

X509Certificate2 cert = new X509Certificate2(certLoc, certPwd);
client.TransportSettings.ClientCertificates.Add(cert);


1) The complete sample for GET request would look as below,

using (HttpClient client = new HttpClient( <Url on which request is to be made> ))
            {
                // Initalise a response object
                HttpResponseMessage response = null;

                string certLoc = <certificate location>;
                string certPwd = <certificate pwd>;

                X509Certificate2 cert = new X509Certificate2(certLoc, certPwd);
                client.TransportSettings.ClientCertificates.Add(cert);

                string sRestAddress =  <Url on which request is to be made>;
                client.BaseAddress = new Uri(sRestAddress);

                // encoding to be used. base64_UTF16_Encode is a user-defined function
                string sBase64EncodedMembershipNumber = base64_UTF16_Encode(sMembershipNumber);

                string authrorization = "Basic" + sBase64EncodedMembershipNumber + "\r\n";
                client.DefaultHeaders.Authorization = new Microsoft.Http.Headers.Credential(authrorization);             
                client.DefaultHeaders.Accept.Add("text/xml\r\n");             

                string requestPath = <request path of the resource>;

                // Make the request and retrieve the response
                response = client.Get(sRestAddress + requestPath);
                response.Content.LoadIntoBuffer();              
                return response.Content.ReadAsByteArray();
            }


The above code snippet shows how we can make a GET request and pass the client certificate and logging credentials along with the request. Response could either be in xml or pdf format and can be specified in the header by using the Accept type in the HTTP request.

2) The PUT request would look like below,

using (HttpClient client = new HttpClient( <Url on which request is to be made> ))
            {
                // Initalise a response object
                HttpResponseMessage response = null;

                string certLoc = <certificate location>;
                string certPwd = <certificate pwd>;

                X509Certificate2 cert = new X509Certificate2(certLoc, certPwd);
                client.TransportSettings.ClientCertificates.Add(cert);

                string sRestAddress =  <Url on which request is to be made>;
                client.BaseAddress = new Uri(sRestAddress);

                // encoding to be used. base64_UTF16_Encode is a user-defined function
                string sBase64EncodedMembershipNumber = base64_UTF16_Encode(sMembershipNumber);

                string authrorization = "Basic" + sBase64EncodedMembershipNumber + "\r\n";
                client.DefaultHeaders.Authorization = new Microsoft.Http.Headers.Credential(authrorization);           
                client.DefaultHeaders.Accept.Add("text/xml\r\n");             

                string requestPath = <request path of the resource>;
             
                // XML file which contains the data to be sent
                XDocument doc = XDocument.Load(@"C:\Personal\Test.xml");

                HttpContent body = HttpContent.Create(doc.ToString(SaveOptions.DisableFormatting), Encoding.UTF8, "text/xml");

                response = client.Put(sRestAddress + requestPath, body);
                response.Content.LoadIntoBuffer();              
                return response.Content.ReadAsByteArray();
            }

The above code snippet shows how to send a PUT request to the server. PUT/POST requests are used to send data to the server. The exact type of verb to be used is decided by the author of the Server code and the requirement whether the state of server is to be changed or not.

REST is fairly easy and simple to use.

Thursday, August 2, 2012

Excel Named ranges in EPPlus

This post will explain the advantages of Named Ranges in Excel and how do we use it with EPPlus library.
This post would explain how to use the named ranges for reading/importing an excel programmatically(dynamically).

A) What are Named Ranges?
In excel, it is possible to specify an address for a cell or a range of cells. The address of this/these cells is referred as named ranges.


If you check the above image, cell A1 has a text value of "Name" and named range of it is"NameField".
Named Range in other words are user-defined addresses of cells.
Now, since named ranges are addresses, basic rules of variable names apply. Like, it cannot begin with a number, cannot have a '.' character in the name, etc. Also, within a sheet, all the named ranges must have unique names.

B) Writing named ranges using EPPlus:
Many engineering applications (software) provide feature of exporting and importing the excel file. The typical scenario will be to generate some kind of a template information in the form of an excel, exporting to the client from server.
The exported excel file can then be populated from the users and once that is done, the excel file can then be imported into the system by sending it to the server over a web.

In such scenarios, importing an excel will be extremely easy only if we were to write the user defined addresses of the cells along with its text, while exporting. So that while reading we can read only our user-defined addresses.

Assumption:
Users are aware of How to use EPPlus library and the popular APIs it exposes.

ExcelRange range = ws.Cells["A1"];           // ws is the worksheet name
ws.Cells["A1"].Value = "Name";
string sNamedRange = "NameField";
ws.Names.Add(sNamedRange, range);

That's it. A1 cell in your generated excel file must have "NameField" as its address.

Hope this post helps a lot of other developers. I had a tough time reading the excel file.



How to change the orientation of excel worksheet in EPPlus

It is very easy to change the orientation of the Excel sheet while using EPPlus library. This is often necessary when one needs to check the print preview of the generated excel file.

Suppose, your worksheet variable name is ws then,
ws.PrinterSettings.Orientation = eOrientation.Landscape.

Thats it. It is a simple one-liner.

Friday, July 27, 2012

NPOI or EPPlus? Which is better?

In my current project, I had a requirement to export and import the data to an excel file. There are plenty of free libraries available, but only NPOI and EPPlus are worth taking a look.

After initial searching and experimentation, i have come to the following conclusion.
Pls. note that these conclusions have been arrived at, only after my personal trials.

NPOI
1) The library is good and extensive, but the API's are not at all intuitive and user friendly
2) Performance in terms of time and memory, is a big disappointment.
3) The only advantage in favour of NPOI, according to me, is its ability to generate xls and xlsx files.

EPPlus
1) The library is very well written and API's are user-friendly, very much identical to Interop.excel
2) Performance is big big gain while using EPPlus. Thousands of cells can be read/written in a matter of seconds.
3) It can generate file only in xlsx format. No facility of xls. But one can always download the Microsoft Compatibility pack to overcome this problem.