C# Programming: Using Generic Factory Classes to Create Generic Exception Handlers

Introduction

Exception handling is termed to be a costly affair and should be used meticulously. It undoubtedly serves as an integral part of our applications, and cannot be sidelined for any reason. The common problem in implementing an Exception handling mechanism is the dependency on the library after we create a provider.This C# tutorial looks at a possibility of switching the providers at ease.

It's a problem for every developer be it ASP.NET developer or C# developer. Evaluating each provider takes some toll on the development. So let us re-use them.

For e.g. If you start using the Enterprise Library, you can't just switch your code if you decide to switch the provider.The solution in such cases is to create wrappers around this common piece and abstract the provider. You can use factory classes like shown below and abstract the provider. Then switch providers through a simple config change.

For reference: this article uses Enterprise Library as default provider. The code sample below consists of a Factory Class that facilitates easy pick of an Exception handler through a config change.

To start with create an interface, as shown below.

List down all the methods that you think any Exception handling component would have. For now, let's start with a single method HandleException which asks for an Exception object and a policy name.

namespace Infrastructure.ExceptionHandling
{
    /// <summary>
    /// IExceptionHandler defines a contract for the Exception Handlers.
    /// </summary>
    public interface IExceptionHandler
    {
        /// <summary>
        /// Handles the specified ex, applying the policy.
        /// </summary>
        /// <param name="ex">The ex.</param>
        /// <param name="policyName">Name of the policy.</param>
        /// <returns></returns>
        bool HandleException(Exception ex, string policyName);    }
}

Create an Exception handler Factory Class to return an instance of the Exception handler.We need to create as many Exception handlers as we need to switch.The Interface IException handler would drive the exception handlers.

namespace Infrastructure.ExceptionHandling
{
    /// <summary>
    /// creates Exception handler.
    /// </summary>
    /// <typeparam name="TExceptionHandler">The type of the Exception handler.</typeparam>
    public class ExceptionHandlerFactory < TExceptionHandler > where TExceptionHandler: IExceptionHandler, new()
    {
        /// <summary>
        /// creates an instance for TClass
        /// </summary>
        /// <returns>instance of TClass</returns>
        public static TExceptionHandler CreateProvider()
        {
            TExceptionHandler instance = new TExceptionHandler ();
               return instance;
        }
    }
}



C# Programming: Using Generic Factory Classes to Create Generic Exception Handlers

Create a Wrapper

Wrapper is created to make all our calls routed through one common method.

namespace Infrastructure.ExceptionHandling
{
    public static class ExceptionWrapper
    {
        /// <summary>
        /// exceptionHandler
        /// </summary>
        static IExceptionHandler exceptionHandler;

        /// <summary>
        /// Gets the exceptionHandler.
        /// </summary>
        /// <value>The exceptionHandler.</value>
        public static IExceptionHandler ExceptionHandler
        {
            get
            {
                if (null == exceptionHandler)
                {
                    //Create the Exception Handler
                    exceptionHandler = ExceptionHandlerHelper.GetExceptionHandler();
                }
                return exceptionHandler;
            }
        }

    }
}

Create a Helper Class for Exception handler. Please note the use of the Exception handler type. This is what corresponds to multiple exception handlers. Currently Microsoft Enterprise Library is used as an example. We can add as many as need be. Also create a Property in the setting file - ExceptionHandlerType. This Property can be used to switch between the Log Providers. Currently it holds the default value of "ENTLIB".

namespace Infrastructure.Logging
{
    /// <summary>
    /// Enumurator for ExceptionHandlerType
    /// </summary>
    public enum ExceptionHandlerType
    {
        /// <summary>
        /// Microsoft Enterprise Library
        /// </summary>
        ENTLIB
    }


    /// <summary>
    /// Helper class for Exception Handler
    /// </summary>
    public class ExceptionHandlerHelper
    {
        private static  ExceptionHandlerType  _exceptionHandlerType   = ExceptionHandlerType.ENTLIB;
        private static  IExceptionHandler  _exceptionHandler       = null;
        
	
       /// <summary>
        /// Initializes the <see cref="ExceptionHandlerHelper"/> class.
        /// </summary>
        static ExceptionHandlerHelper()
        {
            try
            {
                _exceptionHandlerType = (ExceptionHandlerType)Enum.Parse(typeof(ExceptionHandlerType), 	Properties.Settings.Default.ExceptionHandlerType.Trim().ToUpper());
            }
            catch //(Exception exception)
            {
                //Set the default to EntLib
                _exceptionHandlerType = ExceptionHandlerType.ENTLIB;
            }
        }

        /// <summary>
        /// Gets the Exception Handler.
        /// </summary>
        /// <returns></returns>
        public static IExceptionHandler GetExceptionHandler()
        {
            switch (_exceptionHandlerType)
            {
                case ExceptionHandlerType.ENTLIB:
                    return _exceptionHandler = ExceptionHandlerFactory<EntLibExceptionHandler>.CreateProvider();
                default:
                    return _exceptionHandler = ExceptionHandlerFactory<EntLibExceptionHandler>.CreateProvider();
            }
        }
}

}

And finally, the implementation of the Entlib Exception handling class. Note the use of the local Exception.

#region Namespaces

using Microsoft.Practices.EnterpriseLibrary.Logging;

#endregion Namespaces

namespace Infrastructure.ExceptionHandling
{
    /// <summary>
    /// ExceptionHandler class. Uses Microsoft Enterprise Library
    /// </summary>
    public sealed class EntLibExceptionHandler : IExceptionHandler
    {
        /// <summary>
        /// Handles the specified ex.
        /// </summary>
        /// <param name="ex">The ex.</param>
        /// <param name="policyName">Name of the policy.</param>
        /// <returns></returns>
        public bool HandleException(System.Exception ex, string policyName)
        {
            return ExceptionPolicy.HandleException(ex, policyName);
        }
    }
}}

    
Don't forget to add the Exception handler configuration in the Application config file
     
<!-- ENTLIB EXCEPTION HANDLING CONFIGURATION START -->

    <section name="exceptionHandling" 	type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, 	Microsoft.Practices.EnterpriseLibrary.ExceptionHandling" />
 	<exceptionHandling>
   	 <exceptionPolicies>
      		<add name="Default Policy">
     		   <exceptionTypes>
         			 <add name="Exception" type="System.Exception, mscorlib" postHandlingAction="None" >
          		  <exceptionHandlers>
            		  <add name="Infrastructure Exception Handler"
               			 type="Infrastructure.ExceptionHandling.InfrastructureExceptionHandler,Infrastructure"/>
             		 <add name="Logging Block"
       		logCategory="Error"
       		 eventId="100"
        		severity="Error"
       		 title="My App"
       		 formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, 		
		Microsoft.Practices.EnterpriseLibrary.ExceptionHandling"
       		 priority="0"
        		type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, 		
	   	Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging"
        	/>
            </exceptionHandlers>
          </add>
        </exceptionTypes>
      </add>
    </exceptionPolicies>
  </exceptionHandling>

  <!-- ENTLIB EXCEPTION HANDLING CONFIGURATION END -->

All in place, we need to handle our exceptions using the exception handler that we created. Note that the switch for the exception handler is made at the provider level and not at the consumer level.

//Create the Exception Handler and handle the exception.
ExceptionWrapper.ExceptionHandler.HandleException(ex, "Default Policy");

Note that since, Entlib uses IExceptionHandler as one of its interfaces. You would have to rename the IExceptionHandler with a different name when you try this code. The name used here is only to make it easy to understand.

Also note that, you may have to read the Exception Handling Application Block documentation to understand about the Exception policies supported by the Enterprise Library.

The ground rule of exception handling would still apply: Do not catch an Exception more than once per thread.

References

http://msdn.microsoft.com/en-us/practices/default.aspx
http://www.microsoft.com/downloads/details.aspx?FamilyId=5A14E870-406B-4F2A-B723-97BA84AE80B5&displaylang=en
http://www.devx.com/dotnet/Article/31463

Related Articles





About the Author

Srinath M S

I would love to leave a footprint in this flat world

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Finance leaders have been talking about expanding the value-added role of their teams for a long time. The debate is no longer whether the finance and accounting function needs to become a more strategic partner to the rest of the business but rather how to get there. Technology innovation has caught up to this ambition, and what was once aspiration can be a reality – and the choice is now yours. Read this research report to learn how to make the most of information tools to enable innovation and growth.

  • Is your organization increasingly concerned about being the victim of a targeted attack? With targeted attacks increasing in frequency and ruthlessness, companies must take steps to protect themselves. This Smart Select provides customized guidelines to advise you in how to protect your IT assets.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date