Tuesday, May 27, 2014

Decompiling BAML

We know that XAML is a declarative markup language. XAML simplifies creating a UI for .NET application created using WPF or Silverlight. It is simple and easy to create UI elements using XAML, and then separate the design from run-time logic by using code-behind files, joined to the markup by partial class definitions. So what is a BAML ?

BAML is the short form of Binary Application Markup Language, as the name implies it is a binary representation of the XAML file containing implementation details. It is nothing but  parsed, tokenism and XAML that is converted into binary format. Tokenized  means lengthier bits of XAML are replaced with shorter tokens. It is compressed declarative format that is faster to load and parse also it is smaller in size as compared to regular XAML.

So when you compile a WPF project, all XAML files whose build action are set to Page or Resource gets converted to BAML and then embedded as resource in the assembly. So now you have a binary object that is smaller and also optimized in a way that makes it faster to parse at runtime. BAML gets embedded as a resource so developer don't need to worry about linking,parsing or referencing anything  except calling InitializeComponent() in code-behind.

BAML is converted to implementation code during runtime, internally it is used for creating objects. If  you set the x:shared attribute to false, a new copy is created from the BAML every time you use the object. In earlier versions developers didn't have access to BAML, After WPF 4 the new implementation of XamlReader.Load(), BAML loading, Control & DataTemplates functionality with a new engine built on top of the new System.Xaml.dll, I know back in the early days of WPF that CAML was generated rather than BAML, looks like the WPF team has decided to eliminate it, and keep the BAML version.

Baml2006Reader :
Again as most of us know that in WPF, UI can be created either by code or by XAML-which is basically an declarative XML to describe object graphs. This approach makes UI development  easy and fast but parsing XAML file at runtime is quite expensive. So the MarkupCompiler converts the XAML file to BAML.The BAML API is something unique of WPF and was not public until .NET 4.0. Now it's available through the Baml2006Reader implementation. The following code shows how to load a BAML stream .Baml2006Reader uses Reflection to load the assemblies needed for decompilation, which is a little expensive.
var reader = new Baml2006Reader(stream);
var writer = new XamlObjectWriter(reader.SchemaContext);
while(reader.Read())
{
    writer.WriteNode(reader);
}
return writer.Result;
A simple way to decompile the generated BAML is by using the dotPeek from JetBrains or .NET Reflector. Lets walk through the process of installing the plugin.

dotPeek : We have to build and install a plugin for dotPeek. To install the plugin follow this steps.
  1. Download the addin Baml4dotPeek  from the github project https://github.com/cprieto/Baml4dotPeek
  2. Build the project, you might have to update reference to point to your dotPeek bin folder.
  3. A successful  build will generate a output file "BamlFromResource.dll".
  4. Copy this file to the dotpeek bin directory.
  5. Restart dotPeek, and verify form the Tools|Options, if you have the BamlDecompiler.



Once you have the plugin installed open any WFP project and expand the directory tree to find the resources . From the resources you will find some baml file, select any file and the window on the right will display the xaml for that resource.




Note: For Silverlight the XAML files are not converted in to BAML.When you build a Silverlight project a .xap file is created, it is just a .zip-file containing an AppManifest.XAML and all resources in your project compiled as dll's.  You can verify that by opening a dll in dotPeek or Reflector, it will show the XAML-files and other resources.

Thursday, February 13, 2014

Async task helper


Here is a simple helper class for async tasks. The helper class encapsulates code for creating task, This is a very interesting way to isolate the complexity of task programming. Class implementation is nothing much fancy, Async and await keywords are only used in the helper class so our main code remains very clean. The method DoAsync accepts three parameters, one function and two action. First is the function that is the actual work or task we want to accomplish asynchronously, second action is fired when the work is completed successfully and the third parameter is a action that is fired in case of an exception.

   1: using System;
   2: using System.Threading.Tasks;
   3:  
   4: namespace Common.Helper
   5: {
   6:     public class TaskHelper
   7:     {
   8:         public static void DoAsync<T>(Func<T> work, Action<T> completed, Action<Exception> exceptionHandler)
   9:         {
  10:             Task<T> task = AsyncTask(work);
  11:             task.GetAwaiter().OnCompleted(() =>
  12:             {
  13:                 if (task.IsFaulted)
  14:                     exceptionHandler(task.Exception);
  15:                 else
  16:                     completed.Invoke(task.Result);
  17:             });
  18:         }
  19:  
  20:         private static async Task<T> AsyncTask<T>(Func<T> func)
  21:         {
  22:             return await Task.Run(func);
  23:         } 
  24:     }
  25: }

 

Below is a very simple class that utilize TaskHelper. Assuming that we are using the class in a UI application to perform some lengthy work, once the work is complete we want to display some data to the user. The method DoWork is suppose to perform the lengthy work and return the result as a string value. Once the work is finish the method WorkCompleted will be invoked, if there are any exception during this process the method HandleException should handle and display proper error to the user.

 


   1: public class SomeTask
   2: {
   3:     public SomeTask()
   4:     {
   5:         TaskHelper.DoAsync<string>(DoWork, WorkCompleted, HandleException); 
   6:     }
   7:     private string DoWork()
   8:     {
   9:         return "TaskDone";
  10:     }
  11:     private void WorkCompleted(string status)
  12:     {
  13:     }
  14:     private void HandleException(Exception ex)
  15:     {               
  16:     }
  17: }

Friday, July 12, 2013

Using StopWatch to calibrate code performance


When we have to calibrate the performance of a loop, method or block of code we quickly tend to throw in few datetime.now and calculate the time difference. This approach has some flaws and does not provide accurate results. One major reason is datetime.now has a very low resolution depending on the computer, a typical computer has a resolution of somewhere around 100 ticks per second.

Microsoft introduced the Stopwatch class to help developers get more accurate time stamp. Stopwatch is generally more precise then datetime.now and secondly it’s more lightweight, also it support object oriented design. So what does the stopwatch class do, It just stores the current time-stamp (via QueryPerformanceCounter) when you start it, and compare it to the time-stamp when you stop it, so between start and stop it does not use cpu cycles and so it does not effect the performance of your code. Stopwatch was designed specifically for accurate time measurements, so you can be sure it is optimized. Though it would be a good idea to remove any performance counters in a release build. It is also much more accurate than comparing successive values of datetime.now.

For everyday debugging use case we need a easy and clean code to calculate execution time, so lets create a re-usable class that can be easily used to measure performance of our code.


   1: using System;
   2: using System.Diagnostics;
   3:  
   4: namespace Common.Helper
   5: {
   6:     public class StopWatchHelper
   7:     {
   8:         public static void CalculateTime(string stopWatchLabel, Action action)
   9:         {
  10:             var internalStopWatch = new InternalStopWatch();
  11:             action();
  12:             PrintToConsole(internalStopWatch.TimeDifference(), null, stopWatchLabel);
  13:         }
  14:  
  15:         public static void CalculateTime(Action action)
  16:         {
  17:             var internalStopWatch = new InternalStopWatch();
  18:             action();
  19:             PrintToConsole(internalStopWatch.TimeDifference(), action.Method.Name, null,
  20:                            new StackTrace(new StackFrame(1, true)));
  21:         }
  22:  
  23:         private static void PrintToConsole(TimeSpan timeDifference, string methodName = null,
  24:                                            string stopWatchLabel = null, StackTrace st = null)
  25:         {
  26:             if (string.IsNullOrEmpty(stopWatchLabel))
  27:             {
  28:                 PrintDottedLine();
  29:                 Console.WriteLine(" Method : {0} ", methodName);
  30:                 Console.WriteLine(" Time : {0} ", timeDifference);
  31:                 Console.WriteLine(" Location: {0}", st);
  32:                 PrintDottedLine();
  33:             }
  34:             else
  35:             {
  36:                 PrintDottedLine();
  37:                 Console.WriteLine(" Label : {0} ", stopWatchLabel);
  38:                 Console.WriteLine(" Time : {0} ", timeDifference);
  39:                 PrintDottedLine();
  40:             }
  41:         }
  42:  
  43:         private static void PrintDottedLine()
  44:         {
  45:             Console.WriteLine("-------------------------------------------------\n");
  46:         }
  47:  
  48:     }
  49:  
  50:     internal class InternalStopWatch
  51:     {
  52:         private readonly Stopwatch stopwatch;
  53:  
  54:         public InternalStopWatch()
  55:         {
  56:             stopwatch = new Stopwatch();
  57:             stopwatch.Start();
  58:         }
  59:  
  60:         public TimeSpan TimeDifference()
  61:         {
  62:             stopwatch.Stop();
  63:             return stopwatch.Elapsed;
  64:         }
  65:  
  66:     }
  67:  
  68: }



Code for the main console application

   1: using System;
   2: using System.Collections.Generic;
   3: using Common.Helper;
   4:  
   5: namespace StopWatchHelperConsole
   6: {
   7:     internal class Program
   8:     {
   9:         private static void Main(string[] args)
  10:         {
  11:             //If not release mode then exit the application
  12:             if (!CheckIfReleaseMode()) return;
  13:  
  14:             //Single line statment
  15:             var list = CreateNewList();
  16:             StopWatchHelper.CalculateTime(list.Sort);
  17:  
  18:             //Use Lambda
  19:             list = CreateNewList();
  20:             StopWatchHelper.CalculateTime(() =&gt; { list.Sort(); });
  21:  
  22:             //User a label to indicate the location
  23:             list = CreateNewList();
  24:             StopWatchHelper.CalculateTime("StopWatch for List", () =&gt;
  25:                 {
  26:                     list.Sort();
  27:                     list.Sort();
  28:                 });
  29:  
  30:             Console.Read();
  31:         }
  32:  
  33:         private static List CreateNewList()
  34:         {
  35:             var list = new List();
  36:             const int size = 10000;
  37:             var random = new Random();
  38:             for (int i = 0; i &lt; size; ++i)
  39:                 list.Add(random.Next());
  40:             return list;
  41:         }
  42:  
  43:         private static bool CheckIfReleaseMode()
  44:         {
  45: #if DEBUG
  46:             Console.WriteLine("Performance test should be done in Relase Mode");
  47:             Console.Read();
  48:             return false;
  49: #else
  50:             return true;
  51: #endif
  52:         }
  53:     
  54:     }



Output on the console screen

Console Output






















Friday, July 6, 2012

c# readonly vs constant in different assembly

In C#/.NET we can declare a constant value by either using keyword 'const' or 'readonly' . Using const keyword will define compile time constant and readonly will define runtime. Only the C# built-in types can be declared using 'const' for user-defined types like class, struct or array use 'readonly'. Compiler will have a literal value for all the fields that declared const, so if you decompile the code you will find no reference to the constant but actual value. Compile time constant are faster then readonly but are less flexible and can create issues if not used properly. As a general rule one should strictly use compile time constant only for values that are never going to change for example defining value of PI, any value that might change in future use readonly.

During developing a large application there are numerous scenario where you might have to choose between compile-time and run-time constant's. Compile time constants are faster then run-time, although in certain conditions to avoid potential problems you might want to consider using run-time constants . The difference between the two is more clearly explained in this post [ linky ]

Here is an practical example, two teams are working on a same project one team develops a external class library and other team develops the main application. Team one has developed the class library that has some const and readonly variables, these values are consumed in the application developed by the team two. If in future team one updates the constant value in the external class library and the application is not recompiled it would not reflect the new value. This issue is only created if your are using constant values form external assemblies. If a const value changes in a assembly then you need to rebuild all the clients applications dependent on it.




   1:  using System;
   2:  using ExternalLibrary;
   3:   
   4:  namespace ExternalLibrary
   5:  {
   6:      public class ConstantLib
   7:      {
   8:          public static readonly int StartValue = 105;
   9:          public const int EndValue = 120;
  10:          public readonly int ReadonlyValue = 555;
  11:      }
  12:  }
  13:   
  14:   
  15:   
  16:  namespace CTvsRT
  17:  {
  18:     class Program
  19:     {
  20:        static void Main(string[] args)
  21:        {
  22:         ConstantLib cl = new ConstantLib();
  23:   
  24:         Console.WriteLine("ConstantLib.StartValue {0}", ConstantLib.StartValue.ToString());
  25:         Console.WriteLine("ConstantLib.EndValue {0}", ConstantLib.EndValue.ToString());
  26:         Console.WriteLine("ConstantLib.readonlyValue {0}", cl.ReadonlyValue.ToString());
  27:   
  28:         Console.Read();
  29:        }
  30:     }
  31:  }

Friday, January 13, 2012

Visual Studio Templates for Silverlight

For Visual Studio and Silverlight there are nice templates available online. If you are a new developers this templates will be very useful, also for experience developers they should be a handy tool in their toolbox. In this post we will learn how to install the project item templates and use them. I assume every .NET developer should have used the inbuilt visual studio template's and understand how helpful they can be.

The five template are :-
1) Silverlight Client Access Policy File:-
This templates adds a file named clientaccesspolicy.xml in the root folder of the Silverlight project.Silverlight 4 supports two different mechanisms for services to enable cross-domain access clientaccesspolicy.xml or crossdomain.xml file. This file need to be at the root of the domain where the service is hosted, I tend to use clientaccesspolicy.xml file because it provides more granular control over allowed domains and can also be used to set configuration for Sockets.A very good explanation can be found here http://www.devtoolshed.com/explanation-cross-domain-and-client-access-policy-files-silverlight

Either way, when you are done  the policy file needs to go in the ROOT of the domain. This is important as it is not the application root, but the root web. Even if your app is located at   foo.com/myapp, the policy file needs to be at  foo.com/clientaccesspolicy.xml.

2) Value Converter:-
This templates adds a file for converter.

3) C# Trigger Template for Silverlight:-
This templates adds a file for trigger.

4) C# Behavior Template for Silverlight:-
This templates adds a file for behavior.

5) C# Action Template for Silverlight:-
This templates adds a file for action.

How to get the templates ?
Open Visual Studio, open an existing silverlight project or create new one.
Right click on the Silverlight Project –> Add -> New Item ->(left side) select Online Templates -> Silverlight


Organizing the templates
This templates will create files and place them under the root folder. What I do is usually create folders in the silverlight project named as behaviors,triggers,actions,converters. How this helps? eventually and gradually when the projects files increase its easy to locate code-files and manage them effectively.

Code Snippets
I know there are code snippets available for the same, I like the templates because a single click will generate the file with basic code and it opens the popular open-file dialog where you can name the file.




Sunday, October 30, 2011

Silverlight Cookie Manager

Cookies are popular in web programming for state management, mostly used for persisting small data on client computer. Each cookie is a name-value pairs, this information is stored as small files on client hard-disk. You can also set expiration  date and time of a cookie. If no expiration is provided cookie will be discarded when user closes the browser, this type of non-persistent cookies is useful to store secure or short time data.

In Silverlight, one can access cookies through the 'HtmlPage' class. This class provides browser functionalities and other details like Cookie data, Browser name and version, Popup Window, Platform, UserAgent, Product name and version.  Below is a diagram illustrating how the Silverlight plug-in access cookies through the browser. In traditional web programming, the Response Object or java script is used to set a cookie. A user can disable cookies on his browser, so while using the response object  we should check if cookies are enabled or not. To verify if cookies are enabled, set a cookie and try to read it back, if you can't read it means cookies are disabled. Silverlight code executes on client PC, so we can directly check if cookies are enabled or not just by using 'HtmlPage.BrowserInformation.CookiesEnabled'.




Securing cookie data is very important and should be take in account during application design. To prevent unauthorized access of cookies, combination of tricks can be used like encryption, expiration time, HttpOnly,etc. Silverlight code executes on client PC and cannot access HttpOnly cookies. Cookie class is a part of 'System.Net' and is used to retrieve information about cookies that are received with Http responses. Cookies are stored in a CookieContainer on a Web request, and a CookieCollection on a Web response. You must always create a CookieContainer to send with a request if you want cookies to be returned on the response, also for HTTPOnly cookies.

Limitation if a cookie is that it can store only string data types.
1) Some user may disable cookies on their browser in some case user may manually delete cookies
2) Size limitations Most browsers place a 4096-byte limit on the size of a cookie, although support for 8192-byte cookies is becoming more common in newer browser and client-device versions.
3) User-configured refusal Some users disable their browser or client device's ability to receive cookies, thereby limiting this functionality.
4) Potential security risks Cookies are subject to tampering. Users can manipulate cookies on their computer, which can potentially cause a security risk.

I have created a simple class that aggregates common functionality related to cookies. All members in the class are static so there is no need to create new instances every time you read or write a cookie. The overloaded method SetCookie() will create a new cookie or reset the value of an existing cookie, you can also set the expiration time, path, domain, security using the same method. GetAllCookieList() method will return a list of all available cookies. DeleteCookie() method will delete the cookie by setting the expiration time to yesterday. GetCookieAsString() will return the full cookie data as a string.

  1. using System;
  2. using System.Net;
  3. using System.Text;
  4. using System.Linq;
  5. using System.Collections.Generic;
  6. using System.Windows.Browser;
  7.  
  8. namespace Utilities
  9. {
  10.     public static class CookieManager
  11.     {
  12.         // 1) If same name cooke exist, SetCookie() will over-ride value.
  13.         // 2) Exception handling should be done in user code
  14.         // 3) - expireDays = 0, indicates a session cookie that will not be written to disk
  15.         //    - expireDays = -1, indicates that the cookie will not expire and will be permanent
  16.         //    - expireDays = n, indicates that the cookie will expire in n days
  17.  
  18.  
  19.         public static bool IsCookieEnabled()
  20.         {
  21.             return HtmlPage.BrowserInformation.CookiesEnabled;
  22.         }
  23.  
  24.         public static bool SetCookie(string key, string value)
  25.         {
  26.             return SetCookie(key, value, null, null, null, false);
  27.         }
  28.  
  29.         public static bool SetCookie(string key, string value, TimeSpan? expiry)
  30.         {
  31.             return SetCookie(key, value, expiry, null, null, false);
  32.         }
  33.  
  34.         public static bool SetCookie(string key, string value, TimeSpan? expiry, string path, string domain, bool secure)
  35.         {
  36.             if (!IsCookieEnabled()) return false; //If cookies not enabled return false.
  37.  
  38.             StringBuilder sbCookie = new StringBuilder();
  39.             sbCookie.Append(string.Concat(key, "=", value));
  40.  
  41.             if (expiry.HasValue)
  42.             {
  43.                 DateTime expire = DateTime.UtcNow + expiry.Value; sbCookie.Append(string.Concat(";expires=", expire.ToString("R")));
  44.             }
  45.  
  46.             if (path != null)
  47.             {
  48.                 sbCookie.Append(string.Concat(";path=", path));
  49.             }
  50.  
  51.             if (domain != null)
  52.             {
  53.                 sbCookie.Append(string.Concat(";domain=", domain));
  54.             }
  55.  
  56.             if (secure)
  57.             {
  58.                 sbCookie.Append(";secure");
  59.             }
  60.  
  61.             HtmlPage.Document.SetProperty("cookie", sbCookie.ToString());  // User should handle exceptions if any while writing cookie.
  62.  
  63.             return true;
  64.         }
  65.  
  66.         public static List<Cookie> GetAllCookieList()
  67.         {
  68.             string[] cookies = HtmlPage.Document.Cookies.Split(';');
  69.             List<Cookie> cookieList = new List<Cookie>();
  70.             foreach (string cookie in cookies)
  71.             {
  72.                 string[] cookieParts = cookie.Split('=');
  73.                 if (cookieParts.Count() >= 1)
  74.                 {
  75.                     cookieList.Add(new Cookie(cookieParts[0].Trim(), cookieParts[1].Trim()));
  76.                 }
  77.             }
  78.  
  79.             return cookieList; //User should check for count to know how many cookies are retrieved.
  80.  
  81.             ////LINQ code
  82.             //return (from cookie in cookies
  83.             //        select cookie.Split('=')
  84.             //            into cookieParts
  85.             //            where cookieParts.Count() >= 1
  86.             //            select new Cookie(cookieParts[0].Trim(), cookieParts[1].Trim())).ToList(); //User should check for count to know how many cookeies are retrieved.
  87.         }
  88.  
  89.         public static CookieCollection GetAllCookieCollection()
  90.         {
  91.             string[] cookies = HtmlPage.Document.Cookies.Split(';');
  92.             CookieCollection cookieCollection = new CookieCollection();
  93.             foreach (string cookie in cookies)
  94.             {
  95.                 string[] cookieParts = cookie.Split('=');
  96.                 if (cookieParts.Count() >= 1)
  97.                 {
  98.                     cookieCollection.Add(new Cookie(cookieParts[0].Trim(), cookieParts[1].Trim()));
  99.                 }
  100.             }
  101.             return cookieCollection; //User should check for count to know how many cookies are retrieved.
  102.  
  103.             //LINQ code
  104.             //foreach (string[] cookieParts in
  105.             //   cookies.Select(cookie => cookie.Split('=')).Where(cookieParts => cookieParts.Count() >= 1))
  106.             //{
  107.             //    cookieCollection.Add(new Cookie(cookieParts[0].Trim(), cookieParts[1].Trim()));
  108.             //}
  109.             //return cookieCollection; //User should check for count to know how many cookies are retrieved.
  110.         }
  111.  
  112.         public static string GetCookieAsString(string key)
  113.         {
  114.             string[] cookies = HtmlPage.Document.Cookies.Split(';');
  115.  
  116.             foreach (string cookie in cookies)
  117.             {
  118.                 string[] keyValue = cookie.Split('=');
  119.  
  120.                 if (keyValue.Length == 2)
  121.                 {
  122.                     if (keyValue[0].ToString().Trim() == key) //sometime we get one space infront of the cookie so need to Trim()
  123.                     {
  124.                         return cookie;
  125.                     }
  126.                 }
  127.             }
  128.             return null;
  129.             //LINQ code
  130.             //return (from cookie in cookies
  131.             //        let keyValue = cookie.Split('=')
  132.             //        where keyValue.Length == 2
  133.             //        where keyValue[0].ToString().Trim() == key
  134.             //        select cookie).FirstOrDefault();
  135.         }
  136.  
  137.         public static string GetValue(string key)
  138.         {
  139.             string[] cookies = HtmlPage.Document.Cookies.Split(';');
  140.  
  141.             foreach (string cookie in cookies)
  142.             {
  143.                 string[] keyValue = cookie.Split('=');
  144.  
  145.                 if (keyValue.Length == 2)
  146.                 {
  147.                     if (keyValue[0].ToString().Trim() == key) //sometime we get one space infront of the cookie so need to Trim()
  148.                     {
  149.                         return keyValue[1]; //this will return only Value                        
  150.                     }
  151.                 }
  152.             }
  153.  
  154.             return null;
  155.             //LINQ code
  156.             //return (from cookie in cookies
  157.             //        select cookie.Split('=')
  158.             //            into keyValue
  159.             //            where keyValue.Length == 2
  160.             //            where keyValue[0].ToString().Trim() == key
  161.             //            select keyValue[1]).FirstOrDefault();
  162.         }
  163.  
  164.         public static bool DeletCookie(string key)
  165.         {
  166.  
  167.             if (Exists(key, ""))// check if cookie is present or not
  168.             {
  169.                 DateTime expireDate = DateTime.Now - TimeSpan.FromDays(1); // yesterday
  170.                 string expires = ";expires=" + expireDate.ToString("R");
  171.                 string cookie = key + "=" + expires;
  172.                 HtmlPage.Document.SetProperty("cookie", cookie);
  173.                 return true;
  174.             }
  175.             else
  176.             {
  177.                 return false;
  178.             }
  179.         }
  180.  
  181.         public static bool Exists(string key, string value)
  182.         {
  183.             if (string.IsNullOrEmpty(key))
  184.                 return false; //If key not provided, return false
  185.  
  186.             return string.IsNullOrEmpty(value)
  187.                        ? HtmlPage.Document.Cookies.Contains(key + "=")
  188.                        : HtmlPage.Document.Cookies.Contains(key + "=" + value);
  189.         }
  190.  
  191.     }
  192. }


Cookie FAQ
http://www.cookiecentral.com/faq/

Silverlight cookies
http://msdn.microsoft.com/en-us/library/dd920298%28v=VS.95%29.aspx

HttpOnly cookies
http://msdn.microsoft.com/en-us/library/system.web.httpcookie.httponly.aspx