Caching implementation strategy

Caching implementation strategy

Old forum URL: forums.lhotka.net/forums/t/9011.aspx


Andreas posted on Monday, May 31, 2010

Hi,

I am looking for a way to implement caching into our business object layer (all csla based) without breaking the existing code. Simplified I want to lookup in an identity cache (kind of dictionary) for an instance with the same identity as requested on the client. If found, I want to return it to the business layer. If not found, I have to load it from the server though the DataPortal, but before returning it to the business layer it should be inserted it into the cache. Basically I want intercept calls to the DataPortal to implement caching. But this doesn't seem to be easy (if possible). A custom DataPortalProxy might be another option. But this seems to be complicated as well. Is there recommend “csla pattern” how to implement this in a more or less generic way?

Andreas

edore replied on Monday, May 31, 2010

Hello,

a good way to handle this, if you use ObjectFactory to handle DataPortal_XYZ methods is to implement your own base object factory class(es).  That's what we did and it provided us a good control over the cache.  The road down this path is probably not as simple as you would wish but it has its value.  To give you some insight, we implemented 2 different factory base classes which have the following public interface (simplified but still, you'll get the point) :

1. SelectableEntityFactoryBase<TEntity, TEntityId>

public virtual TEntity Create(); 

 

 

public virtual TEntity Fetch(EntityIdCriteria<TEntity,TEntityId> criteria);

 

 

2. EditableEntityFactoryBase(sub-class of SelectableEntityFactoryBase)  

public virtual TEntity Update(TEntity entity); 

public void Delete(EntityIdCriteria<TEntity, TEntityId> criteria);

SelectableEntityFactoryBase verifies if the entity exists in the cache before fetching it from the database.  And EditableEntityFactoryBase takes care of updating or deleting the entity from the cache when an update or a delete occurs.  Since those classes are generic and abstract, the sub class only defines the class and the type of the entity id.  For example :

public class EmployeeFactory : EditableEntityFactoryBase<Employee, Int32> { }

 

is the factory class declaration.

Also note we use a singleton called CachingFactory to hide the caching implementation defined in a ICachingService which is defined as follows :

public T Get<T>(string entityId) where T : class

public void Update<T>(string entityId, T entity, DateTime absoluteExpiration) where T : class

public void Delete<T>(string entityId) where T : class

I hope it gets you started!

Andreas replied on Tuesday, June 01, 2010

Thanks edore! ObjectFactory seems to be the right approach to implement client side caching.

RockfordLhotka replied on Tuesday, June 01, 2010

The factory objects run on the logical "server side" and so aren't good for client-side caching.

One way to do client-side caching is to create your own data portal proxy, and implement the caching code in your proxy's fetch method. You'd either service the request from your cache, or delegate to the normal WcfProxy to actually invoke the data portal.

Andreas replied on Tuesday, June 01, 2010

Good to know. Thanks Rocky. BTW, can you point me to any sample implementation? When I was looking into the source of WcfProxy I noticed that none of the Fetch/Update/Delete members are declared as virtual. So I can't use it as a base class for my custom CachingWcfProxy. As far as I understood the proxy concept I only can have one proxy per request. So I probably need to copy and past the code and insert my caching stuff before I delegate to the base class. Is that what you meant?

Andreas

RockfordLhotka replied on Tuesday, June 01, 2010

Unfortunately I don't know of a reference application.

I did not mean to subclass, no. I meant you should implement IDataPortalProxy and create your own proxy.

The data portal uses exactly one proxy (usually) - which can be your proxy, which checks the cache, and otherwise delegates to its own private instance of the standard WcfProxy.

There's also IDataPortalProxyFactory, which is a way of intelligently switching between proxies on a per-call basis, but I don't think that's the best solution for your caching scenario.

Copyright (c) Marimer LLC