Thursday, April 26, 2012

Design class to handle processing times in a distributed environment.


Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4.  
  5. namespace Import.Data
  6. {
  7.     /// <summary>
  8.     /// Class that stores execution times, messages and other
  9.     /// information required to generate exception report for
  10.     /// import process
  11.     /// </summary>
  12.     public class SyncResultItemNew : IDisposable
  13.     {
  14.         #region Private Variables
  15.  
  16.         private readonly List<SyncResultItemNew> _childern;
  17.         private readonly Dictionary<string, string> _parameters;
  18.         private readonly bool _shouldFallThrough;
  19.         private readonly Stopwatch _stopWatch;
  20.         private string _action;
  21.         private string _description;
  22.         private TimeSpan _duration;
  23.         private string _logicalStep;
  24.         private SyncResultType _resultType;
  25.  
  26.         #endregion
  27.  
  28.         #region PrivateMethods
  29.  
  30.         private string SubstituteParamName(string paramName)
  31.         {
  32.             string baseParamName = paramName;
  33.             string actualParamName = paramName;
  34.             int index = 0;
  35.  
  36.             while (_parameters.ContainsKey(actualParamName))
  37.             {
  38.                 actualParamName = baseParamName + "(" + ++index + ")";
  39.             }
  40.             return actualParamName;
  41.         }
  42.  
  43.         #endregion
  44.  
  45.         #region Constructor
  46.  
  47.         /// <param name="stepName">Name of the step.</param>
  48.         /// <remarks>
  49.         ///   If step name is not provided then
  50.         ///   step name is set to "Unknown"
  51.         /// </remarks>
  52.         private SyncResultItemNew(string stepName)
  53.         {
  54.             _logicalStep = !string.IsNullOrEmpty(stepName) ? stepName : "Unknown";
  55.             _stopWatch = Stopwatch.StartNew();
  56.             _parameters = new Dictionary<string, string>();
  57.             _childern = new List<SyncResultItemNew>();
  58.             _action = string.Empty;
  59.             _description = string.Empty;
  60.             _shouldFallThrough = false;
  61.             _resultType = SyncResultType.Success;
  62.         }
  63.  
  64.         #endregion
  65.  
  66.         #region Public Properties
  67.  
  68.         /// <summary>
  69.         /// Gets a value indicating whether code processing should fall through or not.
  70.         /// </summary>
  71.         /// <value><c>true</c> if code processing should fall through otherwise, <c>false</c>.</value>
  72.         public bool ShouldFallThrough
  73.         {
  74.             get { return _shouldFallThrough; }
  75.         }
  76.  
  77.         #endregion
  78.  
  79.         #region IDisposable Members
  80.  
  81.         void IDisposable.Dispose()
  82.         {
  83.             if (_stopWatch != null)
  84.             {
  85.                 _stopWatch.Stop();
  86.                 _duration = _stopWatch.Elapsed;
  87.             }
  88.         }
  89.  
  90.         #endregion
  91.  
  92.         #region Public Methods
  93.  
  94.         /// <summary>
  95.         ///  Creates a parent that stores all the necessary information required
  96.         ///  for exception report and stores execution times of all the logical steps.
  97.         /// </summary>
  98.         /// <param name="stepName">Name of the step.</param>
  99.         /// <returns>
  100.         /// A newly created instance of the <see cref="SyncResultItemNew"/> class
  101.         /// that stores all information required for exception reporting after
  102.         /// import process.
  103.         /// </returns>
  104.         /// <exception cref="ObjectDisposedException">Object is already disposed.</exception>
  105.         /// <remarks>
  106.         /// If step name is not provided, then root is created with name "Unknown".
  107.         /// </remarks>
  108.         public static SyncResultItemNew CreateRoot(string stepName)
  109.         {
  110.             return new SyncResultItemNew(stepName);
  111.         }
  112.  
  113.         /// <summary>
  114.         ///  Creates a child of <see cref="SyncResultItemNew"/> name with logical step
  115.         ///  under a parent <see cref="SyncResultItemNew"/>.
  116.         /// </summary>
  117.         /// <param name="stepName">Name of the step.</param>
  118.         /// <returns>
  119.         /// A newly created child instance of the <see cref="SyncResultItemNew"/> class
  120.         /// that stores all information required for exception reporting after
  121.         /// import process under a parent.
  122.         /// </returns>
  123.         /// <exception cref="ObjectDisposedException">Object is already disposed.</exception>
  124.         /// <remarks>
  125.         /// If no step name is provided then child will be
  126.         /// created with step name "Unknown".
  127.         /// </remarks>
  128.         public SyncResultItemNew CreateChild(string stepName)
  129.         {
  130.             var syncResultItemNew = new SyncResultItemNew(stepName);
  131.             _childern.Add(syncResultItemNew);
  132.             return syncResultItemNew;
  133.         }
  134.  
  135.         /// <param name="paramName">Name of the parameter.</param>
  136.         /// <param name="paramValue">Value of the parameter</param>
  137.         /// <remarks>
  138.         /// If parameter name is not provided then parameter name would be defaulted
  139.         /// to "Key". If an existing parameter name is provided then code
  140.         /// increments the parameter name and then add it to collection
  141.         /// </remarks>
  142.         public void AddParam(string paramName, string paramValue)
  143.         {
  144.             paramName = string.IsNullOrEmpty(paramName) ? "Key" : paramName;
  145.  
  146.             if (!_parameters.ContainsKey(paramName))
  147.             {
  148.                 _parameters.Add(paramName, paramValue);
  149.             }
  150.             else
  151.             {
  152.                 _parameters.Add(SubstituteParamName(paramName), paramValue);
  153.             }
  154.         }
  155.  
  156.         /// <param name="ex">The exception that needs to be added to collection</param>
  157.         /// <remarks>
  158.         /// If proper exception is not passed, then the exception
  159.         /// messages are ignored/not stored. If this method is called more
  160.         /// than once within the the scope/context of the object and exception is
  161.         /// provided exception messages are added to collection with an incremented key.   
  162.         /// </remarks>
  163.         public void AddUnexpectedError(Exception ex)
  164.         {
  165.             if (ex != null)
  166.             {
  167.                 AddParam("Message", ex.Message);
  168.             }
  169.         }
  170.  
  171.  
  172.         /// <param name="syncResultType">Type of the sync result.</param>
  173.         /// <param name="description">The description that needs to be added.</param>
  174.         /// <remarks>
  175.         /// Populates result type, description. If description is not passed then
  176.         /// description is substituted with default description, "No Description".
  177.         /// If this method is called more than once within the the scope/context of the
  178.         /// object then previous description and result type are overwritten.  
  179.         /// </remarks>
  180.         public void AddResult(SyncResultType syncResultType, string description)
  181.         {
  182.             _resultType = syncResultType;
  183.             _description = !string.IsNullOrEmpty(description) ? description : "No Description";
  184.         }
  185.  
  186.         /// <param name="syncResultType">Type of sync result.</param>
  187.         /// <param name="description">Description that needs to be set.</param>
  188.         /// <param name="ex">The exception that needs to be added to collection.</param>
  189.         /// <remarks>
  190.         /// Populates result type, description and exception
  191.         /// If description is not passed then description is substituted with default
  192.         /// description "No Description". If proper exception is not passed then exception
  193.         /// messages are ignored and not added to collection. If this method is called more than
  194.         /// once within the the scope/context of the object then previous description and result
  195.         /// type are overwritten. If exception is provided new exception messages are
  196.         /// stored with an incremented key.
  197.         /// </remarks>
  198.         public void AddResult(SyncResultType syncResultType, string description, Exception ex)
  199.         {
  200.             _resultType = syncResultType;
  201.             _description = !string.IsNullOrEmpty(description) ? description : "No Description";
  202.             if (ex != null)
  203.             {
  204.                 AddParam("Message", ex.Message);
  205.             }
  206.         }
  207.  
  208.         #endregion
  209.     }
  210. }

No comments:

Post a Comment