How can I cache a collection or list of items

Topics: Caching Application Block , General discussion
Mar 17, 2009 at 8:40 AM
Edited Mar 17, 2009 at 8:45 AM
Hi,
Never used the caching block before and I am about to implement in our application.

I have seen the examples that come with the Enterprise Library + googled a bit but still not sure how you cache list<T> in your cache.

Let me explain

Suppose we have a customer class

I would do something like

public Customer GetCustomer(int id)
{
    Customer customer=(Customer)cache.GetData(id);
    if (customer==null)
   {
        customer=dal.GetCustomer(id);
            if (customer!=null)
                    cache.Add(id,customer);
   }

return customer;
                    
}


Now suppose I have a method GetCustomerList    what do you do?
Is the below wrong?
Is it the right approach to store a list?


public List<Customer>GetCustomerList()
{
    List<Customer> customerList=(List<Customer>)cache.GetData(???);//Do I have to make a key up?
    if (customerList==null)
   {
        customerList=dal.GetCustomerList(???); //Do I have to make a key up?
            if (customerList!=null)
                    cache.Add(???,customerList);
   }

return customerList;
                    
}
Any suggestions ,code examples?

My query is suppose you have a list of Countries,Cities,etc very static data do you cache the list?How?

Thanks a lot
Mar 17, 2009 at 9:14 AM
Yes you'll have to create a key for that object that you put into the cache.


Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
Mar 17, 2009 at 10:16 AM
Thanks for  your prompt reply.
Ok so for each list <T> I want to cache I create my own Key.
Just for the benefit of the doubt is the above the suggested/intended way of storing a list?

Reason I am asking is because I have not seen a single example anywhere on how you store a list of objects but just a single object.

thanks
Mar 17, 2009 at 11:37 AM
Yes it is. Not just for a list but also for other objects, usually those objects that does not come with something unique identifier.

Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
Mar 17, 2009 at 12:56 PM
Edited Mar 17, 2009 at 1:03 PM
Thanks
One more question on this one :)

If I implement memory caching everytime instantiate my object the cache will be cleared ? Is this how it's meant to work.
Am I missing something?

I have nTier app and I am caching in the Business Layer. I have noticed that all the time my cache is null. I dont kill the app but may be is to do from where i create my customer object.
mmmmm . sorry a bit confused.

readonly ICacheManager customerCacheManager;

public class Customer
{
     public customer()
     {
          cache=customerCacheManager.GetCacheManager("CustomerCache");
      }
}

Should be global or something like the asp.net cache?

sorry for silly questions.Just trying to get a grasp of how memory works and should be adopted

Any suggestions?
Mar 18, 2009 at 3:13 AM
Your customerCacheManager is of type ICacheManager, 
        customerCacheManager.GetCacheManager("CustomerCache");
There is no GetCacheManager method available in ICacheManager.  If you mean it like this

public class Customer
{
    ICacheManager customerCacheManager;
    public Customer()
    {
        customerCacheManager = CacheFactory.GetCacheManager("CustomerCache");
    }
}

Instantiating a Customer object will always result to your customerCacheManager with a Count of 0 but not null.  (Let me know if you're really getting null.) I would also like to ask why would you mark your cacheManager as readonly?  


Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
Mar 18, 2009 at 7:09 AM
Thanks a lot for your reply.

  •     Yes .CacheFactory.GetCacheManager(blah);   Sorry that was a typo mistake from me .
  •     Yes the count is 0 not null but getting the data from the cache will have a null object of course.
  •     I  marked the cacheManager as readOnly without understanding it but i just copied and pasted from the QuickStart Example.

I am new to caching via enterprise library and trying to find the best caching that will suits our needs.
My scenario and really appreciate your suggestions is that we have many applications(win/web and webservices) that use the same middleTier  .
We have many parts of the system that could really do with caching (EG GetCountries,GetCurrencyList,GetApplicationPermissions

A made a mistake/assumption(silly me) that for some magic reasons even in memory that cache would be lasting as long as i didnt shut the app
(windows Form app).Obviosly since the cacheManager is created in the constructor of the object i was creating a new one all the time.

If I have a CustomerCache within a CustomerObject and I dont want this cache to be "Destroyed" the only way to do it is by instantiating this object in the "right" place or use the DatabaseBackingStore.Is this Correct?

What I found out is that I was instantiating the object all the time and consequentely i was creating a new CacheManager all time and therefore never hitting the cache!!

In a nutshell if i wanted something to be cached but not to destroy the cache my solution would be
    Use DatabaseBackingStore
    Or
    Create a customer object when you start your app and only comes out of scope when you shut the app 
    Or
how do people use the CAB in these  scenarios (Do they create some sort of staticCustomerCache that never gets destroyed?)

Is going to the database with DatabaseBackingStore always faster than going to your own database? otherwise it would defeat the point no? Really appreciate an answer on this one.

Since I cannot find some example applications that is not as noddy or simple as quickstart , I cannot really learn/see how I should use it.

Thank you for your fantastic support.




Mar 18, 2009 at 7:35 AM
Edited Mar 23, 2009 at 3:29 PM

Yes, creating a static cache manager is an option.  However, I recommend you create it in a separte service or some sort of helper class.   The DatabaseBackingStore is mainly for persisting cache objects even during application restarts.  

"Is going to the database with DatabaseBackingStore always faster than going to your own database?"

Yes, assuming you've verified that caching is appropriate for your application based on how frequent your call to your database is, the amount of data, etc.  No point in providing support for this if itdoesn't improve performance :).  


Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Mar 18, 2009 at 7:53 AM

Again thanks for your VERY quick reply.

Is there any example somewhere to get an idea about how to write one eg ("customerStaticCacheManager")?

that would be fantastic!!!

Thanks
Mar 18, 2009 at 8:07 AM
public class CacheService
{
    private static ICacheManager cacheManager = CacheFactory.GetCacheManager();

    //expose methods of cachemanager here...
    //mark all methods as static
}


Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com