GoSimple.Logging.Log4Net

Wouldn’t it be great if I ‘had a central place where I could keep and work on all my little nuggets of utility code I’ve written over the years. Also be able to download them from nuget would be very convenient. This is why I’ve decided to setup a new project on Github. There I just posted the first library of my personal Swiss army knife framework.

These libraries where primarily designed to build loosely-coupled applications where you can swap out particular components without affecting the rest of the application. Most of my libraries are just small layers above existing frameworks providing a common API that simplify their usage (for me at least). The libraries ease the use of these frameworks by providing standard configurations and exposing only the functionalities I found useful for me through what I saw as a “common API”.

The first library I uploaded is: Go.Simple.Logging

GoSimple.Logging is a small and simple library that provides a common interface for logging. It comes together with an implementation for Log4Net: GoSimple.Logging.Log4Net.

It provides a simple logging interface (Logger.Debug(..), Logger.info(..), Logger.warn(…), Logger.Error(…),….).  I use this nuget package in all my projects to easily integrate with Log4Netwithout having to remember how to configuer & setup Log4Net.

The library comes with an appender to send the logs through syslog to a Splunk server. The TcpSyslogAppender you’ll find in the Log4Net implementation was extensively tested and fine-tuned on many large scale applications running in production.

You can download it through nugget by using the nugget console:

Install-Package GoSimple.Logging.Log4Net

The most valuable extensions you’ll find in this project are:

  • Syslog Appender: used to send your logs over TCP or UDP to a syslog server like Splunk, Logstach or Kiwi.
  • Rolling File Appender: when GoSimple rolls a log file, it saves and closes the old file and starts a new file.

GoSimple.Logging comes with a sample project, you’ll find it on the github project home. It provides an example of how to configure your application for GoSimple.Logging in just one line of code. You’ll also find a sample Log4Net config file with example config sections for each appender.

To enable it on your project you need to :

  • 1) Review the Log4Net.config file on the application root.
  • 2) In VS set the property “Copy to output directory” of the Log4Net.config file to “Copy always”
  • 3) In your application entry point (bootstrapper/main) initialize the Logger:
    Logger.Initialize(new Log4NetLogger());

Voilà that’s all you need to configure to enable logging in your application.

How to get the powershell version

To print out the current Powershell version you can use the $PSVersionTable variable that was introduced since Powershell version 2.

$PSVersionTable.PSVersion

Quality saves time and money!

In software projects quality saves time and money!.   

This principle is based on the observation that one of the most time consuming activity is rework. The rework arises from changes in requirements, change in design, or debugging. The single biggest activity of building software is debugging and correcting code that doesn’t work properly. Following my experience this activity account for about half of the time spent on development. Think at what you really do when you code, generally the time spent in writing production code is ridiculous compared to the time spent at debugging, fixing infrastructure issues, reading code, fixing bugs…

Therefore, the most obvious method to reduce our development cost is to improve the quality of the product and decrease the amount of time spent debugging and reworking our software. This analysis is confirmed by external field data. In a review of 50 development projects involving over 400 work-years of effort and almost 3 million lines of code, a study at NASA's Software Engineering Laboratory found that increased quality assurance was associated with decreased error rate but did not increase overall development cost. Statistical analysis conducted at IBM found that software projects with the lowest levels of defects had the shortest development schedules and the highest development productivity. They explained their findings by staying that software defect removal is actually the most expensive and time-consuming form of work for software (Jones, Capers 2000: “Software Assessments, Benchmarks, and Best Practices.” Addison-Wesley).

Because the duration at which a software defect stays in a program is directly correlated with the cost of fixing it, quality practices should focus on solutions that enable to remove and/or detect errors as soon as possible in each stage of the project lifecycle. Indeed other studies have proven that one of the most important cost factors is the time in which errors are found. The longer the defect stays in the software production chain, the more damage it causes further down the chain. Since requirements are done first, requirements defects have the potential to be in the system longer and to be more expensive. Defects inserted into the software upstream also tend to have broader effects than those inserted further downstream.


Average Cost of Fixing Defects Based on When They're Introduced and Detected

Time Detected 

Time Introduced 

Requirements 

Architecture 

Construction

System Test

Post-Release

Requirements

1

3

5-10

10

10-100

Architecture

-

1

10

15

25-100

Construction

-

-

1

10

10-25

 

Based on book “Code Complete” and studies* -> Fagan 1976; Leffingwell 1997; Willis et al. 1998; Grady 1999; Shull et al. 2002; Boehm and Turner 2004.

The bowling game Kata

Here is a kata made by uncle Bob (Robert C. Martin).  It should be resolved the TDD way (you know…by writing the test first).  The user story of the kata sounds like:
“The game consists of 10 frames as shown above. In each frame the player has two opportunities to knock down 10 pins. The score for the frame is the total number of pins knocked down, plus bonuses for strikes and spares.

A spare is when the player knocks down all 10 pins in two tries. The bonus for that frame is the number of pins knocked down by the next roll. So in frame 3 above, the score is 10 (the total number knocked down) plus a bonus of 5 (the number of pins knocked down on the next roll.)
A strike is when the player knocks down all 10 pins on his first try. The bonus for that frame is the value of the next two balls rolled. In the tenth frame a player who rolls a spare or strike is allowed to roll the extra balls to complete the frame. However no more than three balls can be rolled in tenth frame.”

You can find my C# solution here, but you should not look at it before you tried to implement it by yourself.

Have fun…

Create an offline HTML5 application for IOS with ASP.NET MVC3

 You need to build an application for the IPad or IPhone but you don’t have the time to learn objective-c and cocoa.  The good news is that you don't need to! 

This walkthrough demonstrate how to use the .Net web technology stack to create applications for the IOS platform.  Because we want to be capable of using the application also offline, the UI need to rely purely on HTML and Javascript and we can't use any server side markup generation. Nevertheless we'll need ASP.NET MVC for the creation of web services and his brand new model binding feature to deserialize the JASON message back to a server side model.

We'll first create a new Visual Studio Asp.Net MVC3 empty web application and add an “index.htm” page to the project root:

<!DOCTYPE html>
<html>
<head>
    <title>Subscription Form</title>
    <link href="Content/Site.css" rel="stylesheet" type="text/css" />
    <script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
    <script src="/Scripts/jquery.validate.min.js" type="text/javascript"></script>
</head>
<body>
    <div class="page">
        <header>
            <div id="title">
               Subscription Form
            </div>
 
        </header>
        <section id="main">
        <span id="resultmessage"></span>
        <form id="sub_form" method="" action="">
            <table>
                <tr>
                    <td>
                        Firstname:
                    </td>
                    <td>
                        <input type="text" id="firstname" name="firstname" />
                    </td>
                    <td>
                        Lastname:
                    </td>
                    <td>
                        <input type="text" id="lastname" name="lastname" />
                    </td>
                </tr>
                <tr>
                    <td>
                        E-mail:
                    </td>
                    <td>
                        <input type="text" id="email" name="email" />
                    </td>
                    <td>
                        Phone:
                    </td>
                    <td>
                        <input type="text" id="phone" name="phone" />
                    </td>
                </tr>
                <tr>
                    <td>
                        <input type="button" id="create_subscription" value="Create" >
                    </td>
                    <td>
                        <input type="button" id="send_data" value="Send" />
                    </td>
                </tr>
            </table>
        </form>
        <footer>
            <div>
                <span id="busy"><img src="/Content/wait.gif" alt="wait" /></span>
            </div>
        </footer>
        </section>
    </div>
    <script src="/Scripts/index.js" type="text/javascript"></script>
</body>
</html> 

The first line uses the Html5 doctype and the header links to jQuery. We uses two buttons, one to create the profiles in the browser local storage and another the send the profiles to the server.

To create red boxes arround our input boxes when jQuery detects some validation we need to add these few lines of css to stylesheet:

input.error { border: 2px solid red; }

Now it’s time to implement our UI logic with javascript. By creating a separate file for our javascript we keep the  html page clean.

Add a “index.js” to the script folder:

var root = '/Subscription';
var subscriptionsUploaded = 0;
 
//jQuery on document ready handler
$(function () {
    //Show the busy indicator during ajax calls
    $("#busy").hide();
    $("#busy").ajaxStart(function () { $("#busy").show(); })
    $("#busy").ajaxStop(function () { $("#busy").hide(); })
    var x = $("#createSubscription");
    //When the createSubscription button is clicked create a subscription
    $("#create_subscription").click(createSubscriptionClick);
 
    //When the sendData button is clicked retrieve the subscriptions stored in the local storage and send the data to the server
    $("#send_data").click(sendDataClick);
 
    //Define jQuery validation rules and execute the validation when the form is validated 
    $("#sub_form").validate({
        rules: {
            firstname: {
                required: true,
                minlength: 2
            },
            lastname: {
                required: true,
                minlength: 2
            },
            email: {
                required: true,
                email: true
            },
            phone: {
                required: true,
                number: true,
                minlength: 9,
                maxlength: 9
            }
        },
        messages: {
            firstname: "",
            lastname: "",
            email: "",
            phone: ""
        }
    });
});
 
function sendDataClick() {
    //Iterate over the subscriptions stored in the local storage
    for (var i = 0; i < window.localStorage.length; i++) {
        //Retrieve the serialized subscription  
        var json = window.localStorage.getItem(window.localStorage.key(i));
        try {
            //Send the subscription to the server 
            sendData(
                    json,
            //On success remove the subscription from the local storage 
                    function (data) {
                        window.localStorage.removeItem(window.localStorage.key(data.Message));
                        subscriptionsUploaded++;
                        $("#resultmessage").html(subscriptionsUploaded + " subscriptions uploaded!");
                    },
            //On error
                    function (xhr) {
                        alert(xhr.responseText);
                    });
        }
        catch (e) { alert(e); }
    };
}
 
//Stores a subscription into the local storage
function createSubscriptionClick() {
    //check the jQuery validation rules 
    if ($("#sub_form").valid()) {
        var person = getSubscription();
        //seialize the subscription 
        var jsData = JSON.stringify(person);
        //store the subscription
        window.localStorage.setItem($("#email").val(), jsData);
        //update the resultMessage
        $("#resultmessage").html($("#email").val() + " stored in local storage");
        clearAll();
    }
}
 
//Create a subscription object and bind to the input boxes values
function getSubscription() {
    var firstname = $("#firstname").val();
    var lastname = $("#lastname").val();
    var email = $("#email").val();
    var phone = $("#phone").val();
    return { Firstname: firstname, Lastname: lastname, Email: email, Phone: phone };
}
 
//Clear the input boxes values
function clearAll() {
    $("#firstname").attr("value", "");
    $("#lastname").attr("value", "");
    $("#email").attr("value", "");
    $("#phone").attr("value", "");
}
 
//Ajax: post the json serilized subscriptions 
function sendData(json, success, error) {
    $.ajax({
        url: root + '/save',
        type: 'POST',
        dataType: 'json',
        data: json,
        contentType: 'application/json; charset=utf-8',
        success: success,
        error: error
    });
}

When the user click on the create button the createSubscription function is called, this function is responsible for serializing the data into a Json object and to store it in the isolated storage.  Isolated storage is a feature defined in the Html5 spec. For each domain the browser provide access  to private key/value pair collection where data can be stored  and retrieved. The sendData button is attached with an anonymous function that iterate over the key/value pair collection that contains the JSON serialized subscriptions and post the JSON serialized subscription object.

The MVC 3 includes built-in JSON binding support that enables action methods to receive JSON-encoded data and model-bind it to action-method parameters. We will now create our Model to bind to, add a SubscriptionModel class to the models of the MVC app:

public class SubscriptionModel
{
    [Required]
    [Display(Name = "Firstname")]
    public string Firstname { get; set; }
 
    [Required]
    [Display(Name = "Lastname")]
    public string Lastname { get; set; }
 
    [Display(Name = "Phone")]
    public string Phone { get; set; }
 
    [Required]
    [DataType(DataType.EmailAddress)]
    [Display(Name = "Email address")]
    public string Email { get; set; }
 
    public void Save()
    {
        //store the object in db
        //...
    }
}

The MVC3 model binder will automatically bind all properties that matches the properties in the JSON encoded data.  Now we will define our action method to post to, add a SubscriptionController class to the controllers folder:

[HttpPost]
public ActionResult Save(SubscriptionModel inputModel)
{
    //Server side validation
    if (ModelState.IsValid)
    {
        //If the model is valid we can call the save method
        inputModel.Save();
        string message = inputModel.Email;
 
        //We return the email so that when a subscription has been successfully stored we can remove it from the localstorage.
        //--> SendData function in index.js-> window.localStorage.removeItem(window.localStorage.key(data.Message));
        return Json(new { Message = message });
    }
    else
    {
        //When server side validation fails we return in the details about the validation rules that failed.
        string errorMessage = "<div class=\"validation-summary-errors\">"
                + "The following errors occurred:<ul>";
        foreach (var key in ModelState.Keys)
        {
            var error = ModelState[key].Errors.FirstOrDefault();
            if (error != null)
            {
                errorMessage += "<li class=\"field-validation-error\">"
                    + error.ErrorMessage + "</li>";
            }
        }
        errorMessage += "</ul>";
        return Json(new { Message = errorMessage });
    }
}

Now you should be able to test the application. 

Set a breakpoint on the Save method of the SubscriptionModel. When you enter data in the form and push on create profiles are added to the local storage, when you click on send you should hit the breakpoint and all properties of the model should been set.

To be able to load the application when we are offline we need to use a new feature available in the latest browser like IE9, the Html5:”offline application”.  More info of this feature can be found here.

Add a cache.manifest file to the root of the application:

CACHE MANIFEST
/index.htm
/Content/Site.css
/Scripts/index.js
/Scripts/jquery-1.5.1.min.js
/Scripts/jquery.validate.min.js
/Content/wait.gif

Change the doctype of the index.htm file:

<html manifest="cache.manifest">

You will also need to change the http header that is returned by the IIS server when serving the manifest file.  Therefore in IIS7 you need to click on HTTP Headers, open IIS console manager, navigate to the cache.manifest file, click on http headers, add for the name set-> manifest,value->text/cache-manifest.

If you want an optimal experience when deploying your app on the IPhone or IPad you should also add the following meta tags inside the HTML header:

<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="apple-touch-icon" href="/Content/applogo.gif" />
<link rel="apple-touch-startup-image" href="/Content/startuplogo.gif" />

You should also add your own image files (applogo & startuplogo) in the content folder so that the startup and app icon is set on the IPhone.

Now you can navigate to the page with your IOS device, click on “+” button of the safari browser, add shortcut and voilà you’ve an offline application for your IPhone/IPad made entirely in HTML5/Javascript/ASP.NET MVC3.

Have fun!

kick it on DotNetKicks.com

HTML5 Local Storage

There is a feature in HTML5 that enables you to store named key/value pairs in the local storage of your browser.  The advantage over using regular cookies is that your data is never send to the remote web server and that you can store a lot more compared to the 4KB limitation of cookie storage space.

As the local storage is a feature making part of the HTML5 specification, only modern browser supports is;
Safari 4.0, Opera 10.5,IE8, FireFox 3.5, Chrome 4.0 and IOS above version 2.0.

As for any feature of HTML5 before using it you should check if your browser supports the feature:

   1: function can_use_html5() {
   2:    try {
   3:        return 'localStorage' in window && window['localStorage'] !== null;
   4:    } 
   5:    catch (e) {
   6:        return false;
   7:    }
   8: }

To store or retrieve an item from the local storage:

   1: //Retireve an item:
   2: var item = localStorage.getItem("mykey");
   3: //Store an item:
   4: localStorage.setItem("myKey", "myValue");

To clear an item from the local storage or remove all items:

   1: //Remove an item
   2: localStorage.removeItem("myKey");
   3: //Remove all
   4: localStorage.clear();

 

With this feature we are now able to build web applications that can work offline.  Here under I build an application that stores persons profiles in the local storage.  I use the JSON.stringify method to serialize the persons before storing the JSON strings in the local storage and JQuery to retrieve the values and bind the events:

   1: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   2: <html xmlns="http://www.w3.org/1999/xhtml">
   3: <head>
   4:     <title>Local Storage</title>
   5:     <script src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.5.1.js" type="text/javascript"></script>
   6: </head>
   7:  
   8: <body>
   9:     <div id="resultMessage">&nbsp;</div>
  10:     <table style="position: absolute; left: 10px;">  
  11:         <tr>
  12:             <td>
  13:             Firstname:
  14:             </td>
  15:             <td><input type="text" id="firstname" />
  16:             </td>
  17:         </tr>
  18:         <tr>
  19:             <td>
  20:             Lastname:
  21:             </td>
  22:             <td><input type="text" id="lastname" />
  23:             </td>
  24:         </tr>
  25:         <tr>
  26:             <td>
  27:             E-mail: 
  28:             </td>
  29:             <td><input type="text" id="email" />
  30:             </td>
  31:         </tr>
  32:          <tr>
  33:             <td>
  34:                 <input type="button" id="save"  value="Create" />
  35:             </td>
  36:             <td>
  37:                 <input type="button" id="print"  value="Print"/>
  38:             </td>
  39:         </tr>
  40:     </table>
  41:     <script type="text/javascript">
  42:         $(function () {
  43:             if (!can_use_html5()) {
  44:                 alert("This browser does not support Html5 storage, upgrade or change your browser!");
  45:             }
  46:         });
  47:  
  48:         $(function () {
  49:             $("#save").click(function () {
  50:                 
  51:                 var person = getPerson();
  52:                 
  53:                 //simple validation
  54:                 if (person == null) {
  55:                     alert("Fill in all fields please!");
  56:                     return;
  57:                 }
  58:                 
  59:                 var jsData = JSON.stringify(person);
  60:                 localStorage.setItem($("#email").val(), jsData);
  61:                 
  62:                 $("#resultMessage").html($("#email").val() + " stored in local storage");
  63:                 clearAllText();
  64:             })
  65:         });
  66:  
  67:         $(function () {
  68:             $("#print").click(function () {
  69:                 for (var i = 0; i < window.localStorage.length; i++) {
  70:                     document.write('<div id="record_' + i + '"> ' + localStorage[localStorage.key(i)] + '</div>');
  71:                 }
  72:                 localStorage.clear();
  73:             })
  74:         });
  75:  
  76:         function getPerson() {
  77:             var firstname = $("#firstname").val();
  78:             var lastname = $("#lastname").val();
  79:             var email = $("#email").val();
  80:             //simple validation
  81:             return (firstname == "" || lastname == "" || email == "") ? null : { Firstname: firstname, Lastname: lastname, Email: email };
  82:         }
  83:  
  84:         function can_use_html5() {
  85:             try {
  86:                 return 'localStorage' in window && window['localStorage'] !== null;
  87:             } 
  88:             catch (e) {
  89:                 return false;
  90:             }
  91:         }
  92:  
  93:         function clearAllText() {
  94:             
  95:             $("#firstname").attr("value", "");
  96:             $("#lastname").attr("value", "");
  97:             $("#email").attr("value", "");
  98:         }
  99:     </Script>
 100: </body>
 101: </html>

HTML5 enables new possibilities for all types of scenarios like creating IPAD/IPhone web applications without having to program in objective c and/or upload the app to the app store.  In a future post I will demonstrate how you can extend this application to create such an application.   

kick it on DotNetKicks.com

Answer for Puzzle 2

public IEnumerator GetEnumerator()

{

for (int index = 0; index < values.Length; index++)

{

yield return values[(index + startingPoint) % values.Length];

}

}

This small code block of c#2 replaces the entire Iterator class. The trick here is in the yield return statement.  When you write this statement you actually ask .Net to create a state machine for you. This statement is keeping track of what we were doing when we last returned a value.  Every time the yield return statement is hit the method returns but when the calling method ask for the next element in the IEnumerable collection you re-enter the method just after the last yield return statement as you would never have left it. All the state of the local variables inside the IEnumerator method is preserved.  What is also important to understand is that trick is not performed by the runtime but by the compiler so you don’t incurs real performance lost.

Puzzle 2: iterators using the yield statement (intermediate)

Remove the iterator class from the listing and replace the call to the iterator class, inside the iteration sample(line 29), by using the yield operator of C#2.

The output of the Problem() method should remain the same.

  1: using System;
  2: using System.Collections;
  3: 
  4: namespace Puzzles
  5: {
  6: 
  7:     public class Enumarators
  8:     {
  9:         public static void Problem()
 10:         {
 11:             var myValues = new[] { "a", "b", "c", "d" };
 12:             var col = new IterationSample(myValues);
 13:             foreach (var x in col)
 14:             {
 15:                 Console.WriteLine(x);
 16:             }
 17:         }
 18: 
 19:         public class IterationSample : IEnumerable
 20:         {
 21:             internal object[] values;
 22: 
 23:             public IterationSample(object[] values)
 24:             {
 25:                 this.values = values;
 26:             }
 27:             public IEnumerator GetEnumerator()
 28:             {
 29:                 return new Iterator(this);  //Change this line by using yield
 30:             }
 31:         }
 32: 
 33:         public class Iterator:IEnumerator
 34:         {
 35:             IterationSample parent;
 36:             int position;
 37: 
 38:             internal Iterator(IterationSample parent)
 39:             {
 40:                 this.parent = parent;
 41:                 position = -1;
 42:             }
 43:             public bool MoveNext()
 44:             {
 45:                 if (position != parent.values.Length)
 46:                 {
 47:                 position++;
 48:                 }
 49:                 return position < parent.values.Length;
 50:             }
 51:             public object Current
 52:             {
 53:                 get
 54:                 {
 55:                     if (position==-1 || position==parent.values.Length)
 56:                     {
 57:                      throw new InvalidOperationException();
 58:                     }
 59:                     return parent.values[position];
 60:                 }
 61:             }
 62:             public void Reset()
 63:             {
 64:                 position = -1;
 65:             }
 66:         }
 67:     }
 68: }
 69: 

Answer for puzzle 1

The result is: xhello The thing here is that because the stringbuilder is a reference type, when you change the content of the stringbuilder inside the method AppendHello() this change is reflected in the caller method –> Problem() but when you set the stringbuilder to null this change is not visible inside the caller method. This is because in .Net all parameters are passed by value, even reference types. For reference types it’s not the value of the object itself that is passed by value but a pointer to the underlying value (the reference). The pointer is copied on the stack and is passed by value. When you change the value inside the called method this change is reflected in the underlying value and is visible for the calling method. When you set the pointer to null inside the called method you only destroy the copied pointer not the underlying value.

Puzzle 1: Passing reference types by value (Beginner)

With this post I’ll start a series about programming puzzles and kata’s.

These small exercises will focus on the specific features of C#1,2 & 3.

Have fun…

 

What is the output of: ValueRef.Problem() ?

Can you explain why?

 

  1: public class ValueRef
  2: {
  3:         public static void Problem()
  4:         {
  5:             StringBuilder myStrBuilder = new StringBuilder("x");
  6:             AppendHello(myStrBuilder);
  7:             Console.WriteLine(myStrBuilder.ToString());
  8:             Console.ReadLine();
  9:         }
 10: 
 11:         static void AppendHello(StringBuilder builder)
 12:         {
 13:             builder.Append("hello");
 14:             builder = null;
 15:         }
 16: }
kick it on DotNetKicks.com