Thursday, November 21, 2013

Bridge Design Pattern & Logging System

   While going through some basic stuff about design pattern, I come across the Bridge design pattern & decided to implement it for Logging system. 
  My take is to separate concern about What Is Being Logged & where is being Logged.
An application can log errors as well as user actions too. Same time logging can go to various places like Database, EventLog or a File. 
   Here is Code for Classes that implement Logging system as Bridge Design pattern.
Code here is from a console application 'POALoggingAgent' with a class file 'LoggingAgent.cs' & implicitly created entry point i.e. Program.cs.

[LoggingAgent.cs]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data;
using System.Data.SqlClient;

namespace POALoggingAgent
{
    //Process of Logging Should be Decoubled from Loggable Message
    abstract class LogImplementor
    {
        public abstract bool Log(string Message);
    }

    //Let us to change Logging Implementation at any latter moment when new requirement arise
    class LogAbstraction
    {
        protected LogImplementor Implementor;
        protected string Message;

        public LogAbstraction(string Msg)
        {
            Message = Msg;
        }

        // Implementor
        public LogImplementor LogImplementor
        {
            set
            {
                Implementor = value;
            }
        }

        public virtual  bool Log()
        {
            return Implementor.Log(Message);
        }
    }

    //what is to be logged an error,a user event,application event etc
    class ErrorLogAbstraction : LogAbstraction
    {
        Exception LogggbleException;
        public ErrorLogAbstraction(Exception exp):base(string.Empty)
        {
            LogggbleException = exp;
        }

        public override bool Log()
        {
            /*manipulate exception object propeties to build */
            Message = FormatMessage();
            return Implementor.Log(Message);
        }

        public string FormatMessage()
        {
            //Do Some work on LogggbleException to create formated message and set it to Message inherited Variable
            return "***" + LogggbleException .Message+ "***";
        }
    }

    //initial logging was on console
    class ConsoleLogImplementor : LogImplementor
    {
        public override bool Log(string Message)
        {
            try
            {
                /*BEGIN - Code To Log Message To Console*/
                /*END   - Code To Log Message To Console*/

                //Place Holder
                Console.WriteLine("Class:ConsoleLogImplementor,Method:Log,Message:" + Message);
                return true;
            }
            catch
            {
                return false;
            }
        }
    }

    //logging to database is new requirement generated
    class DbLogImplementor : LogImplementor
    {
        public override bool Log(string Message)
        {
            try
            {
                /*BEGIN - Code To Log Message To DB*/
                /*END   - Code To Log Message To Db*/

                //Place Holder
                Console.WriteLine("Class:DbLogImplementor,Method:Log,Message:" + Message);
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}

Calling above code from our console Application

[Program.cs]

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

namespace POALoggingAgent
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                int i = 0;
                int j = 1;
                Console.WriteLine("Trying to Divide 1 by 0,Output = " + Convert.ToString(j / i));
            }
            catch (Exception exp)
            {
                LogAbstraction LogAb = new ErrorLogAbstraction(exp);

                //  choose console Logging Implementation
                LogAb.LogImplementor = new ConsoleLogImplementor();
                LogAb.Log();

                // choose Database Logging Implementation
                LogAb.LogImplementor = new DbLogImplementor();
                LogAb.Log();
            }
            // Wait for user
            Console.ReadKey();
        }
    }
} 
   To be Frank, I am not sure if Bridge Design Pattern is suitable case for Logging system as there are Singleton & Command, Chain of Responsibility & Subscriber- Publisher; that are often used with logging system.

   Anyone who willing to help me to improve above design of so called Logging system is more than welcomed!

Tuesday, November 19, 2013

UL LI based Drag & DROP with Pure Javascipt & HTML 5

   Currently I am working on UL& LI based DRAG & DROP functionality on my own with pure javascript just for fun as HTML 5 is interesting stuff to explore.
  The functionality to drag an element from other UL is fine but some party is still edgy like re arranging LI's within UL.

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript">
        function dragStart(ev) {
            ev.dataTransfer.effectAllowed = 'move';
            ev.dataTransfer.setData("outerHTML", ev.target.outerHTML);
            ev.dataTransfer.setData("item", ev.target.innerHTML);
            ev.dataTransfer.setData("parent_id", ev.target.parentNode.id);
            ev.dataTransfer.setDragImage(ev.target, 0, 0);
            return true;
        }
        function dragEnter(ev) {
            ev.preventDefault();
        }
        function dragOver(ev) {
            ev.preventDefault()
        }
        function dragDrop(ev) {
           var dragged_li_outer_html = ev.dataTransfer.getData("outerHTML");
            var parent_id = ev.dataTransfer.getData("parent_id");
            var current_id = ev.target.id;
          

            //remove from current location
            for (i = 0; i < document.getElementById(parent_id).children.length; i++) {
                if (document.getElementById(parent_id).children[i].outerHTML == dragged_li_outer_html) {
                    document.getElementById(parent_id).removeChild(document.getElementById(parent_id).children[i]);
                }
            }

            if (parent_id == current_id) {
                //rearrage li of same ui
                alert('Not Supported Yet!');
                return false;
            } else {
                //dragged from other ul and dropped
              
            }
            ev.target.innerHTML = ev.target.innerHTML + dragged_li_outer_html;
            ev.stopPropagation();
            return false;
        }
        function ChilddragDrop(ev) {
            var parent_id = ev.dataTransfer.getData("parent_id");
            var current_id = ev.target.parentNode.id;

            var item = ev.dataTransfer.getData("item");

            if (parent_id == current_id) {
                //rearrage li of same ui
                alert('Not Supported Yet!');
                return false;
            } else {
                //dragged from other ul and dropped

            }

            //remove from source
            for (i = 0; i < document.getElementById(parent_id).children.length; i++) {
                if (document.getElementById(parent_id).children[i].outerHTML == ev.target.outerHTML) {
                    document.getElementById(parent_id).removeChild(document.getElementById(parent_id).children[i]);
                }
            }

            var obj = document.createElement("li");
            for (i = 0; i < ev.target.attributes.length; i++) {
                obj.setAttribute(ev.target.attributes[i].name, ev.target.attributes[i].value);
            }
            var t = document.createTextNode(item);
            obj.appendChild(t);
           
            ev.target.parentNode.insertBefore(obj, ev.target);
            //no bubble up
            ev.stopPropagation();
            return false;
        }
        function dragEnd(ev) {
            ev.preventDefault();
        }
        function mouseup(elt)
        {
           
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
       <div style="border:1px solid black;width:300px;height:300px">
           <span style="text-align:center;display:block;font-weight:bold;">Empty Bucket</span>
           <ul id="dest" draggable="false" 
                          ondragenter="return dragEnter(event)"
                          ondrop="return dragDrop(event)"
                          ondragover="return dragOver(event)"
                          style="border:1px solid red;width:200px;height:200px;background-color:yellow;margin:auto;">

           </ul>
       </div>
        <div style="border:1px solid black;width:300px;height:300px;">
            <span style="text-align:center;display:block;font-weight:bold;">Fruit Basket</span>
            <ul id="source" draggable="false" style="border:1px solid red;width:200px;height:200px;background-color:red;margin:auto;"
                          ondragenter="return dragEnter(event)"
                          ondrop="return dragDrop(event)"
                          ondragover="return dragOver(event)" >
                        <li draggable="true" ondragstart="return dragStart(event)" onmouseup="mouseup(this)" ondragend="dragEnd(event)" ondrop="return ChilddragDrop(event)">mango</li>
                        <li draggable="true" ondragstart="return dragStart(event)" onmouseup="mouseup(this)" ondragend="dragEnd(event)" ondrop="return ChilddragDrop(event)">orange</li>
                        <li draggable="true" ondragstart="return dragStart(event)" onmouseup="mouseup(this)" ondragend="dragEnd(event)" ondrop="return ChilddragDrop(event)">apple</li>
                        <li draggable="true" ondragstart="return dragStart(event)" onmouseup="mouseup(this)" ondragend="dragEnd(event)" ondrop="return ChilddragDrop(event)">banana</li>
                        <li draggable="true" ondragstart="return dragStart(event)" onmouseup="mouseup(this)" ondragend="dragEnd(event)" ondrop="return ChilddragDrop(event)">pineapple</li>
                        <li draggable="true" ondragstart="return dragStart(event)" onmouseup="mouseup(this)" ondragend="dragEnd(event)" ondrop="return ChilddragDrop(event)">guava</li>
                        <li draggable="true" ondragstart="return dragStart(event)" onmouseup="mouseup(this)" ondragend="dragEnd(event)" ondrop="return ChilddragDrop(event)">jackfruit</li>
                        <li draggable="true" ondragstart="return dragStart(event)" onmouseup="mouseup(this)" ondragend="dragEnd(event)" ondrop="return ChilddragDrop(event)">cashew</li>
            </ul>
        </div>
    </div>
    </form>
</body>
</html>

Here is Screenshot:



Happy Coding !

Saturday, November 9, 2013

Simple Custom MVC Helper


In last post we have seen Extension method concept,Here in this post we will see  Extension method usages in creation of custom  MVC HTML Helper.Though I have quite few other example of custom Helper like dropdown from enumeration or Datetime picker widget, i am taking example code syntax Highlighting as it need simple 'pre' tag in HTML.
     In ASP.NET MVC Framework, Html Helper extension methods are located in System.Web.Mvc.Html namespace. To have our own custom Html Helper method we can write Extension Methods for HtmlHelper class.
Here I am going to create very simple syntax highlighter extension for MVC. I am starting with Empty MVC 4 Web Application.
First I am adding a folder called Utility; in that folder I add a class “CustomHelper.cs”.
 [Code: CustomHelper.cs]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace CustomHtmlHelper.Utility
{
    public static class SyntaxHighlighterExtension
    {
        public static MvcHtmlString SyntaxHighlighter(this HtmlHelper htmlHelper,string WidgetId, string Code)
        {
             StringBuilder sb = new StringBuilder();
             sb.Append("<pre name='code' class='c-sharp'>");
             sb.Append(Code);
             sb.Append("</pre>");
             return MvcHtmlString.Create(sb.ToString());
        }
    }
}
Secondly we need to have syntax highlighter JQuery plugin. I referred resources at http://code.google.com/p/syntaxhighlighter/  & downloaded available code and extracted the plugin into my JS folder. After adding the plugin files my folder structure look as below.

Now add a Default controller.In controllers Index action what we are doing is passing ViewData["CsharpCode"] containing some simple C# code to view for rendering.
[Code: DefaultController.cs]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace CustomHtmlHelper.Controllers
{
    public class DefaultController : Controller
    {
        //
        // GET: /Default/

        public ActionResult Index()
        {
            ViewData["CsharpCode"] = @"private void MyTaskWorker(string[] files)
{
  foreach (string file in files)
  {
    // a time consuming operation with a file (compression, encryption etc.)
    Thread.Sleep(1000);
  }
}";
            return View();
        }

    }
}

Now Add a folder Shared inside view folder, into it add a view file “SiteMaster.cshtml
[Code: SiteMaster.cshtml]
<!DOCTYPE html>
<html>
<head>
    <link type="text/css" rel="stylesheet" href="~/JS/JQueryPlugins/SyntaxHighlighter/Styles/SyntaxHighlighter.css"/>
    <script src="~/JS/JQueryPlugins/SyntaxHighlighter/Scripts/shCore.js"></script>
    <script src="~/JS/JQueryPlugins/SyntaxHighlighter/Scripts/shBrushCSharp.js"></script>
    <script src="~/JS/JQueryPlugins/SyntaxHighlighter/Scripts/shBrushXml.js"></script>

   
    <title>@ViewBag.Title</title>
    <style type="text/css">
         #RightMenu ul li {
            display:inline;
            background-color:red;
           
        }
        #RightMenu ul li a {
            padding-left:10px;
            color:white;
        }
    </style>
</head>
<body style="margin: auto; width: 1024px; height: 768px;">
    <div id="MainContainer" style="border: 1px solid black; width: auto; height: auto; margin: 5px auto auto;">
        <div id="header" style="border: 1px solid black; width: auto; height: 110px;">
             <div id="LeftLogo" style="border: 1px solid black; width: 120px; float: left; height: 100%;">
                <div style="text-align: center; vertical-align: middle; padding-top: 5px;">side menu..</div>
            </div>
            <div id="RightMenu" style="border: 1px solid black; height: 100%;">
                <div style="height:70px;">

                </div>
                <ul style="list-style-type: none;text-align:center;">
                    <li>
                        <a href="#">Home</a>
                    </li>
                    <li>
                        <a href="#">About Us</a></li>
                    <li>
                        <a href="#">Services</a>
                    </li>
                    <li>
                        <a href="#">Technology</a> 
                    </li>
                    <li>
                        <a href="#">Outsourcing</a> 
                    </li>
                    <li>
                        <a href="#">Quality</a> 
                    </li>
                    <li>
                        <a href="#">Career</a> 
                    </li>
                    <li>
                        <a href="#">Blogs</a> 
                    </li>
                    <li>
                        <a href="#">Partner</a> 
                    </li>
                    <li>
                        <a href="#" title="Contact Us">Contact Us</a> 
                    </li>
                </ul>
            </div>
               
        </div>
        <div id="content" style="border: 1px solid black; width: auto; height: 620px;">
            <div id="LeftMenu" style="border: 1px solid black; width: 120px; float: left; height: 100%;">
                <div style="text-align: center; vertical-align: middle; padding-top: 5px;">side menu..</div>
            </div>
            <div id="RightContent1" style="border: 1px solid black; height: 100%;">
                @RenderBody()
            </div>
        </div>
        <div id="footer" style="border: 1px solid black; width: auto; height: 50px;">
            <div style="text-align: center; vertical-align: middle; padding-top: 5px;">footer..</div>
        </div>
    </div>

    <script type="text/javascript">
        dp.SyntaxHighlighter.ClipboardSwf = '/JS/JQueryPlugins/SyntaxHighlighter/Scripts/clipboard.swf';
        dp.SyntaxHighlighter.HighlightAll('code');
    </script>
</body>
</html>

SiteMaster.cshtml is our master page (Layout page in MVC).
Now add a view file _ViewStart.cshtml into View folder
[Code: _ViewStart.cshtml]
@{
    Layout = "~/Views/Shared/SiteMaster.cshtml";
}

Underscore in name of this file is indicator of its private nature, it is used to assign master page i.e. Layout in MVC terminology based on condition at runtime. In our case we are assigning same Layout Page to all pages.

Now add a view for our Default controller Index action. Code in this file is as below.
[Code: Index.cshtml]
@using CustomHtmlHelper.Utility
@{
    ViewBag.Title = "Index";
}
<div style="text-align:center;vertical-align:middle;padding-top:5px;">from content page..</div>
@Html.SyntaxHighlighter("MyWidgetId",ViewData["CsharpCode"].ToString());


Using directive is needed to access our newly defined MVC Helper for SyntaxHighlighting.
The line below Makes call to our custom MVC helper it passes string send in ViewData from Controller action to our extension method.
@Html.SyntaxHighlighter("MyWidgetId",ViewData ["CsharpCode"].ToString());\

Below is our custom MVC Html Helper at work
Main idea behind between this custom html helper is to generate simple html of type below.
<pre name='code' class='c-sharp'>
   some c# snipet
</pre>
Layout Page used in this project is preliminary ,My  focus is this code is on Custom MVC HTML Helper method and not on Layout.On some latter post we will touch the concept of layout in MVC.
Complete code of this application is can be downloaded from here