Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Creation of Exception Layer using OOPs Concept

0.00/5 (No votes)
5 May 2005 1  
This article explains how one can trap exceptions in an application. This layer helps to determine from which layer, module and source an exception has occurred.

Introduction

The objective behind writing this article is to make use of concepts into implementation. Here I have tried to create a separate layer which is pluggable and reusable in any application. Suppose in an application an exception has occurred. It becomes difficult to track from which module and layer the exception has arisen. There may be the easiest way around to catch the exception, but my aim is to show how one can make snippets reusable.

Key Scenario

Use of:

  • Abstract Class
  • Interface
  • Sealed Class
  • Interface

Implementation of Exception Layer

Now let's start making the things in a real world application. Create a ExceptionAccessLayer.cs where we going to define the various classes:

Under namespace ExceptionAccessLayer of the class file, create the following classes and interfaces:

  • Exception interface (IPALException)
  • Layer class
  • Module class
  • abstract class PALExceptionBase: System.Exception, IPALException
  • sealed class PALDataValidationException: PALExceptionBase
  • sealed class PALSqlException: PALExceptionBase

Now we will have a walkthrough on the various classes.

  • Layer Class:

    In application development, we always have layers in implementation such as DAL (data Access Layer), Business Access layer, Exception Layer, Data Object layer, Presentation Access Layer and so on, according to the requirement. To give a short description, Business layer is where all formulation, computation or logical blocks of business models are present. For example, interest rate calculation etc. If we talk about DAL layer, we are actually talking about loading of a combo box, opening a connection, database calls and so on. Below is the Layer Class:

    #region Layer Class
    public class Layer
    {
      public const string BUSINESS = "01" ;
      public const string DATAOBJ = "02" ;
      public const string DALC = "03" ;
    }
    #endregion
  • Module Class:

    In any application, there are a number of modules. A module can be having a menu which has various processes related to it. Such as:

    • ADDRECORD
    • DISPLAYRECORD
    • DELETERECORD
    • MODIFYRECORD

    If an exceptions occur then one has to know from which module exception the was raised. So we have a container class for it.

    #region Module Class
    public class Module
    {
      public const string ADDRECORD = "01";
      public const string DISPLAYRECORD = "02";
      public const string DELETERECORD = "03";
      public const string MODIFYRECORD = "04";
    }#endregion
  • Interface:

    An abstract class can have abstract members as well non abstract members. But in an interface, all the members are implicitly abstract and all the members of the interface must override to its derived class. The members of the interface are public with no implementation. Abstract classes can have protected parts, static methods, etc.

    A class can inherit one or more interfaces, but only one abstract class.

    #region Exception interface
    public interface IPALException
    {
        //Implemented into Class--All are Abstract---
    
        string ErrDescription {get;set;}
        Exception InnerExceptionObj {get;set;}
    }
    #endregion

    Implementation (defining) of the above properties will be done in the abstract class below.

    Hope till now we are on the same line of thinking.. Now let's look at the other blocks.

  • Abstract class:

    We have defined an abstract class which has its method in a non abstract state. If you would like to make classes that only represent base classes, and don�t want anyone to create objects of these class types, you can make use of abstract classes to implement such functionality in C# using the modifier 'abstract'.

    Here an overall idea is to declare and define a common base class of Exception such as PALException (PAL: Project Access Layer). Now we can have various exceptions which can be user defined as well as system exceptions derived from it.

    In our case, the PALDataValidation exception class will be derived from the PALException base class and will use the non abstract methods of the PALException base class.

    Abstract class PALExceptionBase inherits System.Exception as well as the interface 'IPALException'.

    Let's look at the code snippet:

    #region PALExceptionBase Class
    public abstract class PALExceptionBase : Exception , IPALException
    {
        private int  _actualNumber ;
        private string _layer ;
        private string _module ;
        private string _description ;
        private Exception _innerException ;
    
        public PALExceptionBase(){}
    
    public PALExceptionBase(string layer, string  module, 
              string description, Exception innerException)
    {
    
        this._layer = layer ;
        this._module = module ;
        this._actualNumber = actualNumber ;
        this._description = description ;
        this._innerException = innerException ;
    
    }
    public string LayerType
    {
        get { return _layer; }
        set { _layer = value ;}
    }
    
    /// <summary>
    
    /// Gets ans Sets Module Type defined
    
    ///    in Module Object of Fourseason Application 
    
    /// </summary>
    
    
    public string ModuleType
    {
        get { return _module; }
        set {_module = value ; }
    }
    public string ErrDescription
    {
        get 
        {
            return _description;
        }
        set
        {
            _description = value ;
        }
    }
    
    public Exception InnerExceptionObj
    {
        {
            get
            {
                return _innerException;
            }
            set
            {
                _innerException = value ;
            }
        }
    }
  • Sealed Class:
    public sealed class PALDataValidationException : PALExceptionBase

    Now look at the dependencies we have declared above. The class is sealed so that it cannot be derived or inherited. Here is the basic question why we are doing all this. See, there are many types of exceptions. Exceptions can be user-defined or system defined exceptions. In an application, we may have SqlException.Math exception, argument exception, memory exception etc. We may throw them in a catch block, but in order to categorize them, we have made classes such as PALDataValidationException, PALSqlException, PALMathException and so on. Just remember when we throw the exception we will declare the object of this class and pass a parameter such as EX(SqlException Ex), LayerName, ModuleName, ErrorDescription.

    So let's see the code snippet:

    #region PALSqlException Class
    public sealed class PALSqlException: PALExceptionBase
    {
    
      public PALSqlException(){}//Default null constructor
    
    
      //Parametrized Constructor
    
    
      public PALSqlException (string layer, string module, 
         int actualNumber,string description, Exception innerException):
         base(layer,module,description,innerException)
      {}
    }
    #endregion
    
    #region PALDataValidationException Class
    public sealed class PALDataValidationException : PALExceptionBase
    {
    
      public PALDataValidationException (){}//Default null constructor
    
    
      //Parametrized Constructor
    
    
      public PALDataValidationException (string layer, string module, 
         int actualNumber,string description, Exception innerException):
         base(layer,module,description,innerException)
      {}
    }//....So on..
    
    #endregion

    See how we have used the abstract class in our implementation class using :base(). That is why abstract classes always hide the implementation.

Hope till now we made some sense on the conceptual ground and gained some implementation momentum on a real world application.

Now time to raise some exceptions purposely from the learning perspective.

I have tried to open a database. But the connection string provided by us contains some flaws. We have purposely not given a password. SQL Server requires Password=sa for opening a connection in our case.

try
{
  SqlConnection objConn= new 
    SqlConnection("SERVER=localhost;Database=northwind;uid=sa;pwd=");
  // See here we purposely not provided

  // pwd though we require in our server

  objConn.Open();
}
catch(SqlException ExERR)
{
  PALSqlException objSQL=new PALSqlException(Layer.DALC, 
                    Module.ADDRECORD,ExERR.Message,ExERR);

  lbl2.Text=objSQL.LayerType;
  lbl3.Text=objSQL.ModuleType;
  lbl4.Text=objSQL.ErrDescription;
  lbl5.Text=ExERR.Source;
}

See in our case we created an object of PALSqlException. Likewise we can create many classes from the abstract base class PALException (PALDataValidationexception, PALSqlEXception, PALFileException: PALException).

PALSqlException objSQL= 
         new PALSqlException(Layer.DALC, Module.ADDRECORD, 
         ExERR.Message, ExERR);

Output:

  1. Layer: 03
  2. Module: 01
  3. Error Description: Login failed for user 'sa'.
  4. Exception: .NET SqlClient Data Provider

Other articles

Conclusion:

Any suggestions, criticism or any information is most welcomed.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here