Implementing a Generic Data Transfer Object in C#
page 3 of 4
by Joydip Kanjilal
Feedback
Average Rating: 
Views (Total / Last 10 Days): 45418/ 39

Implementing a generic Data Transfer Object

We basically have an interface called IDTO, a DTO class and a DTOStore class in this design. The IDTO interface is the base interface for the DTO. It contains the declaration for the generic business entity type. The following is the code for the IDTO interface.

Listing 1

using System;
using System.Data;
using System.Collections;
using System.Collections.Generic;
 
namespace DTOServices
{
    public interface IDTO<BE>
    {
        BE BusinessEntity
        {
            get;
            set;
        }
    }
}

This IDTO interface is implemented by the DTO class. The class contains the implementation for the generic business entity property declared in the IDTO interface and is sealed to prevent further inheritance. The following is the code for the DTO class.

Listing 2

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
 
namespace DTOServices
{
    [Serializable()]
    internal sealed class DTO <BE> : IDTO <BE>
    {
        private BE businessEntity;
 
        public BE BusinessEntity
        {
            get { return businessEntity; }
            set { businessEntity = value; }
        }
    }
}

The DTOStore class is responsible for creating, registering and un-registering DTO instances. The following is the code for the DTOStore class.

Listing 3

using System;
using System.Collections;
using System.Xml.Serialization;
using System.IO;
 
namespace DTOServices
{
    public sealed class DTOStore<BE>
    {
        private static Hashtable dtoRegister = null;
        private static readonly object lockObj = new object();
        private static int key = -1;
       
        private DTOStore()
        {
 
        }
 
        public IDTO <BE>CreateDTO()
        {
            IDTO<BE> dto = new DTO<BE>();
            return dto;
        }
        
        public IDTO<BE> GetDTO(int key)
        {
            lock (dtoRegister.SyncRoot)
            {
                if (dtoRegister.ContainsKey(key))
                    return (IDTO<BE>)dtoRegister[key];
            }
            return null;
        }
        
       public bool RegisterDTO(IDTO<BE> dtoObject)
        {
            if (dtoRegister.ContainsKey(dtoObject.GetHashCode()))
            {
                return false;
            }
 
            lock (dtoRegister.SyncRoot)
            {
                dtoRegister.Add(dtoObject.GetHashCode(), dtoObject);                
                key = dtoObject.GetHashCode();
            }
 
            return true;
        }
        
        public bool UnRegisterDTO(int key)
        {
            if (dtoRegister.ContainsKey(key))
            {
                lock (dtoRegister.SyncRoot)
                {
                    dtoRegister.Remove(key); 
                    key = -1;
                    return true;
                }
            }
            return false;
        }
 
        public static int Key
        {
            get
            {
                return key;
            }
        }
 
        public static DTOStore<BE> Instance
        {
            get
            {
                lock (lockObj)
                { 
                    return Nested.dtoStore; 
                }
            }
        }
 
        internal class Nested
        {
            static internal readonly DTOStore <BE>dtoStore = new DTOStore<BE>();
            
            static Nested()
            {
                dtoRegister = Hashtable.Synchronized(new Hashtable());
            }
        }
    }
}

The DTOStore class contains a hash table called DTORegister that acts as a container of DTO instances. Note the usage of the private constructor in the DTOStore class to prevent its instantiation.

The DTOStore class contains the following important methods:

·         CreateDTO()     

·         GetDTO()

·         RegisterDTO()

·         UnRegisterDTO()

While the CreateDTO method is used to create a new DTO instance, the GetDTO method returns an IDTO instance from the DTORegister. Actually, it returns IDTO Instance from the DTORegister hash table corresponding to the hash code passed to it as a parameter. The RegisterDTO method registers an IDTO instance with the DTOStore. This implies that it stores the IDTO instance and its hash code in the DTORegister hash table. The UnRegister method un-registers the IDTO instance from the DTOStore, i.e., it removes the occurrence of the IDTO instance that corresponds to the hash code passed to it as a parameter.

Note the usage of a nested class called "Nested" within the DTOStore class. The class "Nested" within the DTOStore class is used to ensure that multiple threads access only one DTOStore object one at a time. The static constructor of this class is used to instantiate the DTOStore instance called dtoStore. This is done only once during the entire application's lifetime. Further, a synchronized object is used here to provide a thread safe wrapper in case of multiple reads and writes.

The DTOStore class also contains two properties, Instance and Key. The instance property is used to access an IDTO instance and the Key property is used to retrieve the hash code of the DTO instance. Further, note that the DTO class was marked internal as shown in the code in listing 2. An instance of the DTO class is accessible only using the Instance property of the DTOStore class.

Now, the Data Transfer Object that we have implemented earlier can be used as shown in the following code snippet.

Listing 4: Using the Data Transfer Object

DataSet dataSet = new DataSet();
//Necessary code to populate the DataSet instance with data
IDTO<DataSet> idto = DTOServices.DTOStore<DataSet>.Instance.CreateDTO();
 idto.BusinessEntity = dataSet;
 
  if (DTOServices.DTOStore<DataSet>.Instance.RegisterDTO(idto))
    {
      int key = DTOServices.DTOStore<DataSet>.Key;
      Response.Write("The hash code is " + key.ToString());            
      //Necessary code to pass this key to the other layers of the application
    }
      else
       Response.Write("Error in registering the DTO instance.");

The code in listing 4 illustrates how we can use the generic Data Transfer Object. Note that the Data Transfer Object can be used to store a DataSet, a DataTable, a Custom Business Entity instance or any other data container irrespective of its type. We can assign any business entity instance using generic type parameter as illustrated above.


View Entire Article

User Comments

No comments posted yet.






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-20 2:40:58 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search