5,691,626 members and growing! (12,738 online)
Email Password   helpLost your password?
Web Development » Web Services » General     Intermediate

Web Service via Data Access Object Pattern

By Andrew Golik

Data Access Object pattern implementation
SQL, C# 2.0, C#, Windows, .NET, .NET 2.0, ASP.NET, WebForms, SQL 2000, SQL 2005, VS2005, IE 6.0, SQL Server, Visual Studio, IE, IE 7, Architect, DBA, Dev

Posted: 19 May 2007
Updated: 9 Oct 2007
Views: 24,358
Bookmarked: 46 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
13 votes for this Article.
Popularity: 4.24 Rating: 3.81 out of 5
0 votes, 0.0%
1
2 votes, 15.4%
2
1 vote, 7.7%
3
2 votes, 15.4%
4
8 votes, 61.5%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article

Introduction

Access to the data source varies depending on source of data. Access to the persistent storage, such as to the database varies greatly depending on type of storage and vendor implementation. The ODBC API enables applications to use SQL statements. However, even within RDBMS environment the actual syntax and format of the SQL statement varies depending on the particular database product. There is even greater variation with different types of persistent storage. Access mechanism, supported APIs, and features vary between different types of persistent storage, such as(RDBMS, object-oriented database, LDAP, flat file, Xml file, and so forth). Such disparate data sources make challenges to applications and can potentially create a direct dependency between application and data source code. When business components need to access to the data source, they use appropriate APIs to create connectivity and manipulate the data source. But including the data access code within business components introduces tight coupling between the business components and data source implementation. Such code dependencies make it difficult to migrate form one type of data source to another. When the data source changes, the business components have to be changed to handle the new type of data source.

Solution
Use the Data Access Object to do all manupulation to the data source object. The DAO manages the connection with datasource to get and store data. The DAO implements all access functionality to work with the data source. It doesn't matter what the data source is. It could be any persistent storage such as RDBMS, a repository like LDAP, or even just a XML files. The business components that rely on DAO use simple interface exposed by DAO to its clients. The DAO doesn't show the certain data source implementation and there is no need to do this. Because the DAO interface doesn't need to change when the underlying data source changes, this ability allows DAO to adapt to different types of storage without having to handle it within business component. You can also say that the DAO acts as adapter between components and data source object.

Picture 1. Relationships in DAO pattern.

   
       ------------------   uses          -------------------   encapsulates    -----------
      |   BusinessObject | ------------> |  DataAccessObject | --------------> | DataSource | 
       ------------------                 -------------------                   ------------
                         \                 /
                          \               /
                           \             /  
obtains, modifies, and      \           / save the transfer object into  
creates the transfer object  \         /  persistent data storage
                              \       /
                               \     /
                                \   /
                                \/ \/
                           -----------------
                          |  TransferObject |
                           -----------------    
  

Business object

This object represents the data client. It's the object that requires access to the data source to obtain and modify the data.

Data Access object

This object is underlying object in this pattern. It abstracts the data access implementation for its clients to enable transparent access to the data source. The business object delegates the data creation and store actions to data access object.

Data source

This object represents a data source implementation. It could be any persistent storage, for instance (RDBMS, OODBMS, XML repository, flat file system, and so forth).

Transfer object

This object represents a data carrier. The data access object uses this object to return the data to client as well as to receive to update, create the data in the data source.

Sample of project

I provided this sample of project with two kind of DAO: XmlRepository and MSSql. This sample of project demonstrates how to easy to use this pattern. It also shows that any migration from one datasource to another is a piece of cake.

Screenshot - Diagram.jpg

As you can see I use the abstract factory model. The DaoFactory is abstract class for all dao factories.

 public abstract class DaoFactory 
    {

        public abstract  CustomerDao  GetCustomerDao();
        public abstract  OrderDao   GetOrderDao();
       

       
       
        public static DaoFactory GetDaoFactory()
        {
            string strDaoFactoryType = ConfigurationManager.AppSettings["DaoFactory"];
            if (String.IsNullOrEmpty(strDaoFactoryType))
                throw new NullReferenceException("DaoFactory type configuration is missing from your web.config.");

            else
            {
                Type DaoFactoryType = Type.GetType(strDaoFactoryType);
                if (DaoFactoryType == null)
                    throw new NullReferenceException("DaoFactory type can not be found.");

                Type DaoFactoryBaseType = Type.GetType("AndrewGolik.DaoTraining.DataAccessLayer.DaoFactory");
                if (!DaoFactoryBaseType.IsAssignableFrom(DaoFactoryType))
                    throw new ArgumentException("DaoFactory type does not inherits from AndrewGolik.DaoTraining.DataAccessLayer.DaoFactory.");


                DaoFactory daoFactory = (DaoFactory)Activator.CreateInstance(DaoFactoryType);
                return daoFactory;
            }
            
        }
         
       


    }

The certian implementation of the MSSqlDaoFactory.

 public class MSSqlDaoFactory:DaoFactory
    {
         public static string ConnectionString
        {
            get
            {
                if (ConfigurationManager.ConnectionStrings["MsSqlDao"] == null)
                    throw new NullReferenceException("MsSqlDao connectionString configuration is missing from your web.config.");
                string connectionString = ConfigurationManager.ConnectionStrings["MsSqlDao"].ConnectionString;
                if (String.IsNullOrEmpty(connectionString))
                    throw new NullReferenceException("MsSqlDao connectionString configuration is missing from your web.config.");
                else
                    return connectionString;
            }
               
            
        }
        public override CustomerDao GetCustomerDao() 
        {

           return new MSSqlCustomerDao();
            
        }

        public override OrderDao GetOrderDao() 
        {

            return new MSSqlOrderDao();
        }

     


    }

The implementation for XmlDaoFactory is the same, except specific changes. The XmlDaoFactory hasn't the connection string, but it has paths to xml files.

  public class XmlDaoFactory:DaoFactory
    {
        public static string PathToCustomersFile
        {
      

           get{
       
                 string pathToFile = HttpContext.Current.Server.MapPath("App_Data/XmlRepository/Customers.xml");
                 if (!File.Exists(pathToFile))
                 {
                     XmlDocument xmlDoc = new XmlDocument();
                     xmlDoc.LoadXml("<customers lastgeneratedid="\"0\"">");
                     xmlDoc.Save(pathToFile);

                 }
                 return pathToFile;
              
           }
       
        }
        public static string PathToOrdersFile 
        {
            get
            {

                string pathToFile = HttpContext.Current.Server.MapPath("App_Data/XmlRepository/Orders.xml");
                if (!File.Exists(pathToFile))
                {
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.LoadXml("<orders lastgeneratedid="\"0\"">");
                    xmlDoc.Save(pathToFile);

                }
                return pathToFile;

            }
        }
        public override  CustomerDao  GetCustomerDao()
        {


             return new XmlCustomerDao();
        }

        public override OrderDao GetOrderDao() 
        {

            return new XmlOrderDao();
        }

    }
 </orders></customers>

There are only two business objects in this project the Customer and Order. So we need to have two interface: the CustomerDao and OrderDao.

   public interface OrderDao
    {
          
        int CreateOrder(Order order);
        bool DeleteOrder(int orderID);
        bool UpdateOrder(Order order);
        List<order> GetOrders();

    }
    
    public interface CustomerDao
    {

         int CreateCustomer(Customer customer);
         bool DeleteCustomer(int customerID);
         bool UpdateCustomer(Customer customer);
         List<customer> GetCustomers();
         bool DeleteOrders(int customerID);
        

    }
 </customer></order>
These interfaces describe the base data access functionality for all DAO implementations. Once you add a new interface method, you have to modify all DAO implementations of the interface.

The certain implementation of OrderDao.

  public class MSSqlOrderDao:OrderDao
    {
        public int CreateOrder(Order order)
        {

            //using the Transact-SQL 
            //return the order id on success  
           ......
        }
        
        public bool DeleteOrder(int orderID) 
        {
           //using the Transact-SQL 
           //return the true if the order is removed, otherwise false
            .......
        }
        
        public bool UpdateOrder(Order order) 
        {
           //using the Transact-SQL 
           //return the true if the order is removed, otherwise false
            .......
       
        
        }

        public List<order> GetOrders() 
        {
           //using the Transact-SQL 
           //return the list of orders
            .......
       
        }
   }
   
  </order>

The implementation of the XmlOrderDao is specific due to it uses xml files to store the data.

The transfer objects is used by DAO to send and receive data from data client.

 public class Customer
    {
        private const int defaultIDValue = 0; 
        private int _customerID;
         private string _companyName; 
        private string _contactName; 
        private string _contactTitle; 
        private string _address; 
        private string _city;  
        private string _region; 
        private string _postalCode; 
        private string _country;  
        private string _phone; 
        private string _fax;

        //get and set properties.....
        
    }
    
    
    public class Order
    {
        private const int defaultIDValue = 0; 
        private int _orderID;
        private int _customerID;
        private DateTime _orderDate;
        private Decimal  _freight;
        private    string _shipName;
        private string _shipAddress;
        private string _shipCity;
        private string _shipRegion;
        private string _shipPostalCode;
        private string _shipCountry;
        
        //get and set properties..... 
        
          
  

It's pretty simple to use Dao from data client.

  
   [WebMethod]
        public bool UpdateCustomer(int customerID ,string companyName, string contactName,
                        string contactTitle, string address, string city, string region,
                        string postalCode, string country, string phone, string fax)
        {

            Customer customer = new Customer(customerID , companyName, contactName,
                        contactTitle, address, city, region,
                         postalCode,  country, phone, fax);

            CustomerDao customerDao = DaoFactory.GetDaoFactory().GetCustomerDao();
            return customerDao.UpdateCustomer(customer);
             
        }
 

The web service classes in this project act as business objects or data clients. As you can see the data client hasn't any undestanding what is the data source. The Dao abstracts all manipulations to the data source.

Notes: Currently, in this code the default DAO is XML Repository as means that it can work standalone. It will store the xml files locally in the App_Data folder(be sure that ASPNET user has the write permissions on your machine). If you going to use it with MS SQL, you have to modify the web.config file. You need to comment the XMLDaoFactory and uncomment the MSSqlDaoFactory and also specify the connection string to your database as well as to execute the sql script that is in SqlInstall folder. That is all what you need to migrate from one datasource to another.

Links

The related articles:

Note

Please don't use this code AS IS in your projects. It's just a demo version that deals with data and needs to be tested well.

If you find this article interested, please vote for me.

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

About the Author

Andrew Golik


Andrew Golik is a software professional working in Minsk, Belarus.
He enjoys design infrastructures based on object oriented paradigm. His programming experience includes ASP, ASP.NET, .NET, COM, JAVA, PHP, DHTML, AJAX, blah blah blah....

He is developer at TargetProcess Project (www.targetprocess.com).
TargetProcess is an integrated Project Management and Bug Tracking software.


Occupation: Web Developer
Location: Belarus Belarus

Other popular Web Services articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 9 of 9 (Total in Forum: 9) (Refresh)FirstPrevNext
GeneralOne questionmemberReve10111:05 27 Aug '08  
GeneralI have some reservations about this topicmemberEugenio Piacci15:31 11 Oct '07  
GeneralRe: I have some reservations about this topic [modified]memberAndrew Golik8:36 13 Oct '07  
GeneralDataaccess problemmemberkhalidahmad4:31 8 Jun '07  
Generalgood articlememberflyingchen15:53 5 Jun '07  
GeneralRe: good articlememberHuanacaraz1:05 6 Jun '07  
GeneralRe: good articlememberAndrew Golik2:35 6 Jun '07  
GeneralRe: good articlememberMKauffman7:17 10 Oct '07  
GeneralRe: good articlememberAndrew Golik2:20 6 Jun '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 9 Oct 2007
Editor:
Copyright 2007 by Andrew Golik
Everything else Copyright © CodeProject, 1999-2008
Web20 | Advertise on the Code Project