Extended Properties In The NuSoft Framework

posted on 12/21/07 at 09:00:17 pm by Joel Ross

While I'm away on vacation, I figured I'd put up a series of posts on the NuSoft Framework. This is one of those posts.


I've used the NuSoft Framework for a few different projects, and one pattern that keeps recurring is the idea of "extended properties" - properties that are convenient to have on an entity, but that don't get stored in the database table for that entity. Here's an example of how you can add a couple of properties to a Customer object - to allow easy access to a customer nick name and to summarize the number of orders a customer has.

You could get to each of these values fairly simply, but it would have be lazy loaded, meaning that if you had a list of customers and wanted to show the number of orders for each customer, you'd be hitting the database once to get the list, and then once for each customer in the list. This would result in 1001 hits for a list of 1000 customers. Using this pattern, you can get all of this information in one database hit, and still be able to load on demand as necessary.

The first step is to add the properties:

   1:          private int _orderCount = int.MinValue;
   2:          public int OrderCount
   3:          {
   4:              get
   5:              {
   6:                  if (_orderCount == int.MinValue)
   7:                  {
   8:                      FillExtendedProperties();
   9:                  }
  10:                  return _orderCount;
  11:              }
  12:              set
  13:              {
  14:                  _orderCount = value;
  15:              }
  16:          }
  17:   
  18:          private string _customerNickName = String.Empty;
  19:          public string CustomerNickName
  20:          {
  21:              get
  22:              {
  23:                  if (_customerNickName == String.Empty)
  24:                  {
  25:                      FillExtendedProperties();
  26:                  }
  27:                  return _customerNickName;
  28:              }
  29:              set
  30:              {
  31:                  _customerNickName = value;
  32:              }
  33:          }


Above are the two properties. Each acts like a simple property, except if the value isn't set, it calls FillExtendedProperties(), which will populate all of the extended properties. We took the approach that if you're going to take the hit to populate one extended property, let's just go ahead and populate all of them at the same time - again, to keep the database hits to a minimum. Here's what we do in FillExtendedProperties():

   1:          private void FillExtendedProperties()
   2:          {
   3:              using (SqlHelper helper = new SqlHelper())
   4:              {
   5:                  string commandText = "GetCustomerExtendedProperties";
   6:                  
   7:                  List<SqlParameter> parameters = new List<SqlParameter>();
   8:                  parameters.Add(new SqlParameter("@CustomerID", this.CustomerID));
   9:                  
  10:                  using (IDataReader reader = helper.ExecuteDataReader(
                                  commandText, CommandType.StoredProcedure, ref parameters))
  11:                  {
  12:                      if (reader.Read())
  13:                      {
  14:                          FillExtendedProperties(reader);
  15:                      }
  16:                  }
  17:              }
  18:          }
  19:   
  20:          private void FillExtendedProperties(IDataReader reader)
  21:          {
  22:              this.OrderCount = int.Parse(reader["OrderCount"].ToString());
  23:              this.CustomerNickName = reader["CustomerNickName"].ToString();
  24:          }


In it, we call a stored procedure called GetCustomerExtendedProperties. This would be a custom stored procedure that would return (in this case) the customer's nick name and a count of the customer's orders. Once that's done, we read those values and populate all of the extended properties.

Note that so far, this doesn't solve the problem of being able to retrieve a whole list of customers with the extended properties already populated. To accomplish that, you'd use a new static method that gets all of the information to populate a customer, including the extended property values:

   1:          public static EntityList<Customer> GetFullCustomers()
   2:          {
   3:              using (SqlHelper helper = new SqlHelper())
   4:              {
   5:                  string commandText = "GetFullCustomers";
   6:   
   7:                  List<SqlParameter> parameters = new List<SqlParameter>();
   8:                  EntityList<Customer> customers = new EntityList<Customer>();
   9:   
  10:                  using (IDataReader reader = helper.ExecuteDataReader(
                                  commandText, CommandType.StoredProcedure, ref parameters))
  11:                  {
  12:                      while (reader.Read())
  13:                      {
  14:                          Customer customer = EntityBase.GetEntityInstance<Customer>();
  15:                          customer.Initialize(reader);
  16:                          customer.FillExtendedProperties(reader);
  17:                          customers.Add(customer);
  18:                      }
  19:                  }
  20:   
  21:                  return customers;
  22:              }
  23:          }


This code pulls from some of what's done in EntityBase up into our custom code to accomplish what we want to do. To start with, we call a new, custom stored procedure called GetFullCustomers. That would return all of the fields in the customer table, as well as the extended properties. And remember, this gets a list of all customers, but it could easily be parameterized to return a filtered list of customers.

We're starting to look at another release of the NuSoft Framework, and are trying to determine what features to add. I've thought about incorporating this into the framework as a better supported pattern. My initial thoughts to make this happen would be to have an ExtendedProperty attribute you could add to any property, and use that in conjunction with an IExtendedProperties interface. The interface would require you to implement the FillExtendedProperties methods. I'm not sure of the actual implementation, but I think we could make this a little simpler by incorporating some of it into the framework. If you're using the framework, would this be something helpful to add?

Tags: | |

Categories: Development, Software, RCM Technologies