Click here to Skip to main content
16,012,468 members
Articles / Programming Languages / C#
Article

Automatic Object Persistency – Part I

Rate me:
Please Sign up or sign in to vote.
3.06/5 (9 votes)
13 Aug 2006GPL36 min read 26.5K   776   20  
An API to persist business entities without writing database centric code or mapping schema in an external XML File

Auto Persist Demo Application

Introduction

As an experienced developer one may not be able to answer the question "How many times I wrote database centric code to save/retrieve/delete business entities?" We wrote database centric code many times in our lives. Sometimes by getting tired, we thought to get rid of writing such common code again and again!

Most of the business application requires us to write database centric code like the following:

OleDbConnection connection = null;	
try
{
	string strSql = "SELECT ID, Name, ... FROM tblCust;";
	connection = // create connectoin
	OleDbCommand command = new OleDbCommand(strSql, connection);

	command.Parameters.Add("@ID", 1323);
	.
	.
	command.Parameters.Add("@Address", "First Lane");
		
	OleDbDataReader reader = command.ExecuteReader();
	if (reader.Read())
	{
		// additional code
	}
} catch 
{

}

After getting bored on writing such same logic to persist business entities, engineers and researchers started thinking a way to reduce application code to persist business entities. Writing logic for Creating, Retrieving, Updating, and Deleting business objects to and from the database tables looks like a common pattern in any given language. That is, the code to do such operation looks almost similar in all context. If you wish to perform an INSERT operation into a database table to persist a business object, there are many chances that you write the same code logic to persist other business entities in a brand new application.

When such patterns are seen over and over again, researchers are thinking to establish a framework to achieve the same goal by providing an API. We have seen such frameworks to persist business entities. NHibernate is an example, using which we can minimize database centric code, which in turn, also makes our lives easier.

Background

In 2003, I started developing a Human Resource Management System (HRMS) called HRMZone using J2EE, part of which offers posting of visitors' resume. The application is similar to those of job searching websites such as http://www.jobpilot.com/. While I was tired of coding same database code, I started thinking to develop a Framework to minimize the same efforts; as the code to persist business entities to a backend server looks like a common pattern. Motivation of developing the framework came from my knowledge on the Java's reflection API.

By spending a whole day, I was able to write my first Object Persistence Framework in Java; I named it AutoPersist Framework initially. Interestingly, it saved my live more than I though it could. Sadly, I saw after a couple of months that there is a stable persisting framework had been released called 'Hibernate'! Seemed that I reinvented the same wheel!! Yes, although it was the same wheel, it has the different shape than Hibernate in one aspect; AutoPersist didn't (and still doesn't) require someone to write an OR Mapping file (a schemaic XML mapping).

After Visual C# had been released, I though that I would write a port of my AutoPersist in C# language. I was tremendously busy those days and could not implement a port of the same. Finally, in this week, I have had a little leisure at my home and have written the port of AutoPersist in C# - the very first version that only supports basic CRUD without supporting any complex or simple relational integrity. That is, the first version of AutoPersist will neither allow saving nested object nor it will allow master-child relationship of Database Entities. But interestingly, it can save any business object without writing a mapping file (a schematic mapping in the form of XML).

Using the code

The actual source of the AutoPersist API can be found in the source download link of this article; on the other hand the demo download consist the demo of the same project.

Consider that we have a class called Customer, which defines two properties: Name and Address:

C#
public class Customer
{	
	private int id;
	private string name;
	private string address;

	public Customer()
	{			
	}


	public int ID
	{
		set { this.id = value; }
		get { return this.id; }
	}

	public string Name
	{
		set { this.name = value; }
		get { return this.name; }
	}

	public string Address
	{
		set { this.address = value; }
		get { return this.address; }
	}

}

Now our goal is to persist an object of type Customer without writing database centric code! We will use PersistManager, which is the central heart of the AutoPersist API to achieve this. To have an instance of this class, we need to invoke its NewInstance() method which takes a parameter of type DBInfo to determine the backend type, connection string etc. Until recently, the DBInfo just only provides the connection string property. So the following code snippet at the client end will return an instance of PersistManager:

DBInfo info = new DBInfo();
info.ConnectionString = // here is a connection string;
PersistManager objPersistManager = PersistManager.NewInstance(info);

After having an instance of PersistManager class, we can save our Customer in the following way:

Customer objCustomer = new Customer();
objPersistManager.CreateObject(objCustomer);

Convention

To save a business object using the AutoPersist API, one doesn't need to write any schematic mapping file. So how will the API determine the name of the database table into which a row will be created or deleted? And how will the API determine the name of the columns to map to the property names of an object?

To achieve the goal of automatic persistency for our business object, we must follow some conventions:

Your business entity (your class) must follow the following structure:

C#
public class Customer
{	
	private int id;
	
	// must have a no-arg default public constructor
	public Customer() 
	{
	}
	
	// must have a ID property method of type int
	public int ID
	{
		set { this.id = value; }
		get { return this.id; }
	}	
}

In the database table:

  • there must be a table, name of which must match the name of the object, i.e., table name = object.GetType().Name, where object is your object. For the above example, the table name must be 'Customer'
  • there must be a auto-increment column called 'ID' (autonumber in MS Access).
  • there must be columns, name of which must match with all the property names of the object. For example, if there is property named CustomerName, in the table, there must be a column exactly called 'CustomerName'.

In the demo project, there is a MS Access database called 'AutoPersist' in the '/database' folder to show an example of persisting Customer entity.

Testing

In the first version of the AutoPersist API only property of types 'int' and 'string' have been tested with only MS Access database. For accessing database, I have only used OLE DB API of the .NET Framework.

Enhancement

One may enhance the Framework's code to suite one's own need by supporting (some or all of) the following:

  • saving nested object
  • maintaining a relational integrity
  • both automatic and mixed-mode persistency with the aid of a schematic mapping file (usually an XML file)
  • other database server/application
  • other database access API such as ADO.NET
  • code emitter for creating ASP.NET's web forms (along with code behind and helper classes) or WinForm for Desktop Application

All the above can be achieved. If you have any question or require any support, just drop me an email.

Performance

Balancing a program in all aspect is almost impossible. One needs to compromise an aspect to achieve other advantages. If we use Automatic Persistency, which heavily depends of utilizing Reflection API, we must compromise the speed of the Application. Reflection requires introspection of object structure at runtime (as opposed to design time) to find out method/properties to be invoked. This is somewhat similar to late binding feature in COM, which costs a performance bottleneck.

Final Thoughts

Obviously nothing can stop us from getting advantages of using the AutoPersist like API. There must be solutions for each and every problem. Achieving a performance benefit is hard but not impossible! Are you confused? If you are, please drop me emails stating your confusion -:)

 

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Architect TechAnts Technologies Limited
Bangladesh Bangladesh

Mohammad Ali Azam has been working as an Architect in TechAnts Technologies Limited, located in Dhaka, Bangladesh since 2008.


Azam had long been working as a Senior Java Enterprise Architect in several companies and now has been working on software development using ASP.NET platform. He is as competent in both Visual C# and Visual Basic .NET as he is in J2EE.


For last couple of years, he has actively been working on Email Campaign Software, ECMS, Search Engine Integration, Hospital Management System, Knowledge Management System, Human Resource Management System and open source PHP web application such as Joomla, WordPress and Magento. Along with his regular tasks in the industry, he has also been researching on inventing technologies to promote Rapid Application Development (RAD).


While he works on designing various component models utilizing the best industry practices and the latest specification of UML, at leisure, he plays with his little baby girl and watches Sci-Fi movies on satellite TVs (or on DVDs) with his
wife!


Comments and Discussions

 
-- There are no messages in this forum --