views:

118

answers:

3

I used to have a situation where I hit the database a every time I needed information on an employee. Then I taught myself about data caching and have since cleared up that problem substantially.

Now, I'd like to take it to the next level. I'd like to reduce load times by caching my object instantiation. I'm not sure that I'm being clear, so I'll explain a little more. I have an employee object that (for example sake) has 50 properties. Some of those properties are generic lists of other related objects (such as a list of network assets belonging to that employee). So, when I instantiate an employee object for employee #30455, I don't have to hit the database (neccessarily) because that much is cached.

BUT, I do have to run down the property list, filling them with data from datarows from the cached dataset. I also have to populate those generic lists I chose to include at the head end. Seems like I should be able to cache that object so I don't have to do all of that over again. Thoughts?

+3  A: 

Sounds like you're trying to re-implement NHibernate. That's a mammoth undertaking. NHibernate caches what you're talking about here through first and second level caches. I'm not sure how it's implemented there, but they are using Session objects that expire, typically when a web request ends. Everything can be cached within a given Session by storing objects in-memory.

Does your data layer include some type of session-based object like this? If not, you can do some very crude caching through a public static dictionary that you maintain throughout the life of what corresponds to a session in NHibernate.

asbjornu
A: 

One thought I have had is to instantiate employee objects using a method instead of a constructor. Then, I can do something like...

public static Employee getEmployee(int EmployeeId)
    {
        HttpContext context = HttpContext.Current;
        string key = e.ToString() + "_" + EmployeeId;

        Employee e = (Employee)context.Session[key];
        if (e == null)
        {
            e = new Employee(EmployeeId);
            context.Session[key] = e;
        }
        return e;
    }

...so that I can just...

Employee e = Employee.getEmployee(35440);

I'm already doing this in places, but I never felt like it was the best way... seems more correct to always instantiate using a constructor. Is there a better way?

Byron Sommardahl
A: 

This is a pattern I use for what I think you're trying to accomplish:

public class Foo
{
   private static Dictionary<int, Foo> FooCache = new Dictionary<int, Foo>();

   private Foo(int id) 
   {
      // logic for creating/looking up/whatever Foo objects from their ID
      // goes here 
   }

   public static Foo CreateFoo(int id)
   {
      if (!FooCache.ContainsKey(id))
      {
         FooCache.Add(id, new Foo(id));
      }
      return FooCache[id];
   }
}

You can of course implement the Foo constructor and CreateFoo method so that they take additional arguments beyond id (e.g. the DataRow object that you're using to populate the Foo object with).

Robert Rossney