What is a DAL (Part 4)

As has been mentioned previously, one of the purposes of the DAL is to shield that application from the database. That said, what happens if a DAL throws an exception? How should the application respond to it? In fact, how can it respond to an exception that it should not know about?

If something goes wrong with a query in the database an exception is thrown. If the database is SQL Server then a SqlException is thrown. If it isn’t SQL Server then some other exception is thrown. Or the DAL may be performing actions against a completely different type of data source such as an XML file, plain text file, web service or something completely different. If the application knows nothing about the back end database (data source) then how does it know which exception to respond to?

In short, it doesn’t. It can’t know which of the myriad of possible exceptions that could be thrown will be and how to respond to it. The calling code could just catch(Exception ex) but that is poor practice. It is always best to catch the most specific exception possible.

The answer is to create a specific exception that the DAL can use. A DalException that calling code can use. The original exception is still available as an InnerException on the DalException.

using System;
using System.Runtime.Serialization;

namespace Dal
{
    public class DalException : Exception
    {
        public DalException()
            : base()
        {
        }

        public DalException(string message)
            : base(message)
        {
        }

        public DalException(string message, Exception innerException)
            : base(message, innerException)
        {
        }

        public DalException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
    }
}

The DAL will catch the original exception, create a new one based on the original and throw the new exception.

public DataSet GetPolicy(int policyId)
{
    try
    {
        SqlDataAdapter da =
            (SqlDataAdapter)this.BuildBasicQuery("GetPolicy");
        da.SelectCommand.Parameters.AddWithValue("@id", policyId);
        DataSet result = new DataSet();
        da.Fill(result);
        return result;
    }
    catch (SqlException sqlEx)
    {
        DalException dalEx = BuildDalEx(sqlEx);
        throw dalEx;
    }
}

The code for wrapping the original exception in the DAL Exception can be refactored in to a separate method so it can be used repeatedly. Depending on what it needs to do it may be possible to put that as a protected method on one of the abstract base classes

private DalException BuildDalEx(SqlException sqlEx)
{
    string message = string.Format("An exception occured in the Policy DALrn" +
        "Message: {0}", sqlEx.Message);
    DalException result = new DalException(message, sqlEx);
    return result;
}

Previous articles in the series:

 

 

Technorati Tags: , ,

 

What is a DAL (Part 3)

In this continuation of my series on the DAL I’m going to show the ability to create several DALs and have a Factory class instantiate the correct DAL based on settings in a config file.

One of the purposes of the DAL is to shield the application from the detail of accessing the database. You may have a system where you may have to talk to different databases depending on the way the software is installed. Typically this is most useful by creators of components that need to plug into many different database systems.

The DAL will no longer be a singleton, but rely on a Factory to create the correct DAL class. This is most useful when the data may be coming from different sources. It can also be useful when your application is in development and the database isn’t ready because you can then create a mock DAL and return that instead of the real thing.

UML Diagram showing multiple DALs

UML Diagram showing multiple DALs

The above UML Diagram shows the base DAL that was introduced in the last article in this series. Again, it is an abstract class as it does not contain enough functionality to be instantiated on its own. However, it is now joined by two additional abstract classes. These add a bit more functionality specific to the target database, but still not enough to be useful as an object in its own right.

Finally at the bottom layer are the various concrete DAL classes that act as the proxies to the database.

So that the calling application doesn’t need to know what database it is dealing with the concrete classes implement interfaces. That way the application receives a reference to an IPolicyDal, for example, without having to know whether it is connected to an Oracle database or a SQL Server database (or any other future database you may need to support)

The factory class, not shown in the UML diagram above, picks up information in a config file which tells it which specialised DAL to actually create. It returns that specialised instance through a reference to the interface. This means that the calling code does not need to know what specialised class has actually been created. Nor should it need to care.

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace Dal
{
    /// <summary>
    /// Creates and dispenses the correct DAL depending on the configuration
    /// </summary>
    public class DalFactory
    {
        private static IPolicyDal thePolicyDal = null;
        private static IClaimDal theClaimDal = null;

        /// <summary>
        /// Gets the policy DAL
        /// </summary>
        /// <returns>A dal that implements IPolicyDal</returns>
        public static IPolicyDal GetPolicyDal()
        {
            if (thePolicyDal == null)
            {
                string policyDalName = DalConfig.PolicyDal;
                Type policyDalType = Type.GetType(policyDalName);
                thePolicyDal =
                    (IPolicyDal)Activator.CreateInstance(policyDalType);
            }
            return thePolicyDal;
        }

        /// <summary>
        /// Gets the claim DAL
        /// </summary>
        /// <returns>A DAL that implements IClaimDal</returns>
        public static IClaimDal GetClaimDal()
        {
            if (theClaimDal == null)
            {
                string claimDalName = DalConfig.ClaimDal;
                Type claimDalType = Type.GetType(claimDalName);
                theClaimDal =
                    (IClaimDal)Activator.CreateInstance(claimDalType);
            }
            return theClaimDal;
        }
    }
}

The factory stores the each DAL class as it is created so that if a Get...() method is called repeatedly it always returns the same instance. The DAL classes should not be storing any state so this is a safe thing to do.

The DalConfig class is a very simple static class that consists of a number of property getters that retrieves the information out of the config file. The PolicyDal and ClaimDal properties return the fully qualified name of the specialised DAL class to instantiate.

Previous articles in the series:

Technorati Tags: ,

SQLBits

I haven’t said much about SQLBits, a community conference that I was at last weekend in Reading. It was a brilliant day out and I hardly spent anything. The snacks and lunch were free at the venue (Microsoft Campus) and the “GROUP BY” (Geek Dinner) was sponsored so it didn’t cost anything either.

A big thank you has to be said to Tony Rogerson, Simon Sabin, Martin Bell and all the other organisers that helped make it such a fantastic day.

Here are some photos of from SQL Bits that were taken by Craig Murphy:

Pre-SQLBits dinner - Simon Sabin and me
Simon Sabin and Colin Mackay

Pre-SQLBits dinner - Martin Bell and me
Colin Mackay and Martin Bell

Pre-SQLBits dinner - Martin Bell and me
Colin Mackay and Martin Bell

At the GROUP BY event after SQLBits
Tim Leung, Colin Mackay, Martin Cairney, Tony Rogerson

sql-bits group by group hug
Group hug at Group By

SQLBits - I was the room monitor
Me as a room monitor in Chicago 2

Scottish SQL Server User Group Meeting

When: 24th October at 18:30 until 21:00

Where: HBOS’ offices on Bankhead Crossway North, Sighthill Industrial Estate, EH11 4DT.

What: Two speakers – Dave Johnston of HBOS will talk about backup solutions for SQL Server. Colin Mackay will deliver a micro-presentation on SQL Injection Attacks.

Registration: For security a delegate list needs to be submitted in advance. See this event page for details.

Anything else? There will be refreshments and sandwiches.

 

A problem with Windows Live Writer

I have an external USB hard disk that I use to store all my documents on. I move it between my laptop and my desktop PC so that when I’m out with my laptop I still have access to all my files. And when I get back I don’t have any synchronisation issues.

However, I don’t seem to be able to tell Windows Live Writer where to save my drafts (e.g. A blog folder on my external HDD) so it all ends up in My Documents.

I don’t suppose it will be too difficult to take a USB stick and copy the posts from one to the other, but I’d rather just plug the HDD in and go.

Technorati Tags: , ,

Windows Live Writer

Today I was encouraged to try Windows Live Writer as a way to create blog entries. So this is my first test entry using Live Writer which is supposed to be able to publish the entries directly to the blog without me actually having to visit the blog admin page at all.

First feature that is nice is that the keyboard shortcut for adding hyperlinks is the one I am used to (Ctrl+K) which is shared with Word and Expression Web.

Unfortunately I don’t see a download for a plug in to create Technorati tags. That could be quite useful and if I have time, and that is a big IF, I might look in to writing one myself.

Stupid Thunderbird

A few hours after Thunderbird decided that it really MUST download all the messages all over again for my Yahoo account. It has now decided that it must do so AGAIN! Why?! Was the thrill of downloading 16000 emails not enough the first time round? Must it do so again? And how often will I find my email box bulging with more duplicates of 4 year old emails?