Login or Sign Up to become a member!

EXPERTS, INFORMATION, IDEAS & KNOWLEDGE

Social bookmarker Add this

Your profile

Search

September 2008
Mon Tue Wed Thu Fri Sat Sun
 << <   > >>
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          

XML Feeds

« Use solution foldersMicrosoft Source Analysis for C# Announced »
The Desktop Developers Journal

Generic List Provider in C#

by AlexCuse


Permalink 02 Jun 2008 07:27 , Categories: Microsoft Technologies, C# Tags: c#

Since this is probably the most-often reused piece of code I’ve written recently, I thought it may be worth sharing. It is pretty raw still, so I will post it to the wiki as well, and hopefully people will see ways to improve it (and show us!). Here is the link to the wiki page: Generic List Provider in C#.

I wrote this because I found myself constantly writing code to fill lists of objects from database commands. I was too far into the project and the project was a little to small to justify moving to an ORM like NHibernate, but I thought there must be a better way to do this.

It turns out we can do it, using a couple of my favorite features in .NET 2.0, Reflection and Generics. By making this ListProvider a generic class, we can return a list of objects of any type. And by using reflection we can interrogate the type we are working with at runtime, and assign its’ properties.

There is one pretty major limitation of this method, and that is that your property names need to match the column names that you return from the database. When limiting access to the database to stored procs, this is pretty easy to enforce, so I have not needed to find a way around it. I’m sure there is a way to do this by adding a list of database field names and their associated properties that the calling code can provide, but I have not needed to do it yet. Hopefully someone will add to the wiki page and do it for me :D

Anyways here is the code, it is pretty self explanatory:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Reflection;
  5. using System.Data;
  6.  
  7. namespace MyApp.Utilities
  8. {
  9.     public class ListProvider<T> where T: new()
  10.     {
  11.         public List<T> FindAll(IDbCommand com, IDbConnection con)
  12.         {
  13.             //ensure that command object’s connection is set, open connection
  14.             com.Connection = con;
  15.             con.Open();
  16.  
  17.             //create data reader used in filling objects
  18.             IDataReader rdr = com.ExecuteReader();
  19.  
  20.             //instantiate new list of <T> that will be returned
  21.             List<T> returnList = new List<T>();
  22.  
  23.             //need a Type and PropertyInfo object to set properties via reflection
  24.             Type tType = new T().GetType();
  25.             PropertyInfo pInfo;
  26.  
  27.             //x will hold the instance of <T> until it is added to the list
  28.             T x;
  29.  
  30.             //use reader to populate list of objects
  31.             while (rdr.Read())
  32.             {
  33.                 x = new T();
  34.  
  35.                 //set property values
  36.                 //for this to work, command’s column names must match property names in object <T>
  37.                 for (int i = 0; i<rdr.FieldCount; i++)
  38.                 {
  39.                     pInfo = tType.GetProperty(rdr.GetName(i));
  40.                     pInfo.SetValue(x, rdr[i], null);
  41.                 }
  42.  
  43.                 //once instance of <T> is populated, add to list
  44.                 returnList.Add(x);
  45.             }
  46.  
  47.  
  48.             //clean up – assumes you don’t need command anymore
  49.             con.Close();
  50.             com.Dispose();
  51.             rdr.Dispose();
  52.  
  53.             return returnList;
  54.         }
  55.     }
  56. }

I tried to remove most of the comments that didn’t add much (parameter descriptions and what not) but I think its’ still pretty easy to understand. As I said this is a work in progress (I just need to run into a reason to actually need the progress ;) ) so don’t be too rough on me. And feel free to do my job for me offer suggestions to make this better!

Leave a comment »Send a trackback » 420 views

Trackback address for this post

Trackback URL (right click and copy shortcut/link location)

No feedback yet

Leave a comment


Your email address will not be revealed on this site.

Your URL will be displayed.
PoorExcellent
(Line breaks become <br />)
(Name, email & website)
(Allow users to contact you through a message form (your email will not be revealed.)