Tuesday, September 5
Generic Business layer
On my current project I have discovered a nice way to write generic database access code in the business layer.
Most database access operations are
The approach I have been following is to reduce the number of places where I write database code (code reuse) so as to make it maintainable and make necessary changes in a few places instead in all of the business layer.
e.g
This way we minimize the places where we write database access code. I think I achieved a lot of code reuse by this aproach.
One would say that why not have ONE generic public method in DBHandler (for each operation) that accepts a storedProc & parameters. The only argument I have against this approach is that, with this approach my "page behinds" (controllers) will be clouded by names of stored procedures and SqlParameters statements. I think this would cause more maintainance depending on all the places from where it is called. I think it wouldn't be completely MVC complaint.
In this approach, only the changes need to made to the DBHandler class and specific methods if needed.
I have also realised from reading some posts from microsoft gurus that they are prominently using "using () { }" in their database access operations in order to dispose of the connection objects.
Most database access operations are
a. returning DataTable of results (for binding with
objectdatasource & other controls)
b. Inserting/updating data
c. returning a single value (execute scalar)
The approach I have been following is to reduce the number of places where I write database code (code reuse) so as to make it maintainable and make necessary changes in a few places instead in all of the business layer.
e.g
Here we use the params SqlParameters[] parameters to accept variable number of arguments in turn enabling us to write generic methods.148 public class DBHandler149 {
150 private static DataTable GenericGetDataTable(string storedProc,151 params SqlParameters[] parameters)152 {
153 DataTable retTable = null;154 string connStr = Configuration.AppSettings["ConnectionString"];155 using (SqlConnection conn = new SqlConnection(connstr))156 {
157 conn.open();
158 SqlCommand cmd = new SqlCommand(storedProc, conn);159 foreach (SqlParameter para in parameters)160 {
161 cmd.Parameters.Add(para);
162 }
163 cmd.CommandType = CommandType.StoredProcedure;164 .
165 .
166 .
167 .
168 conn.close();
169 }
170 return retTable;171 }
172 public static DataTable GetBooks( int publicationID, string authorName)173 {
174 SqlParameter pubID = new SqlParameter("@pubID", publicationID);175 SqlParameter authName = new SqlParameter("@authName", authorName);176 return GenericGetDataTable("sp_getAllBooks", pubID, authName);177 }
178 public static DataTable GetPapers(int journalID, int year)179 {
180 SqlParameter jourID = new SqlParameter("@journalID", journalID);181 SqlParameter jYear = new SqlParameter("@year", year);182 return GenericGetDataTable("sp_getAllPublications", jourID, jYear);183 }
184 .
185 .
186 .
187 .
188 // similarly for INSERT & Execute Scalar methods189 private static object GenericExecuteScalar(string storedProc,190 params SqlParameters[] parameters)191 {
192
193 }
194 private static int GenericInsert(string storedProc,195 params SqlParameters[] parameters)196 {
197
198 }
199 }
This way we minimize the places where we write database access code. I think I achieved a lot of code reuse by this aproach.
One would say that why not have ONE generic public method in DBHandler (for each operation) that accepts a storedProc & parameters. The only argument I have against this approach is that, with this approach my "page behinds" (controllers) will be clouded by names of stored procedures and SqlParameters statements. I think this would cause more maintainance depending on all the places from where it is called. I think it wouldn't be completely MVC complaint.
In this approach, only the changes need to made to the DBHandler class and specific methods if needed.
I have also realised from reading some posts from microsoft gurus that they are prominently using "using () { }" in their database access operations in order to dispose of the connection objects.
Comments:
<< Home
Do you remember the discussion we had about using the "using" clause on my other blog?
I think it is very good practice to move the burden of cleanup on the resource objects themselves rather than the client who uses the resource by having the resource implement the IDisposable method. All the client does is limit the scope of the resource by using the "using" clause. When the resource goes out of scope, the appropriate cleanup is automatically done. This is a first class design pattern and "best practice."
I think it is very good practice to move the burden of cleanup on the resource objects themselves rather than the client who uses the resource by having the resource implement the IDisposable method. All the client does is limit the scope of the resource by using the "using" clause. When the resource goes out of scope, the appropriate cleanup is automatically done. This is a first class design pattern and "best practice."
Yes, your blog was very helpful in revising for the C# exam. I have started using "using() {}" every where now.
I haven't actually implemented a IDisposable interface for any custom resource as yet.
Where have you used it?
Post a Comment
I haven't actually implemented a IDisposable interface for any custom resource as yet.
Where have you used it?
Subscribe to Post Comments [Atom]
<< Home
Subscribe to Posts [Atom]