Cache for CSLA.NET

Cache for CSLA.NET

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


ayubu posted on Sunday, October 18, 2009

Hi all

It has been a good time once again to share with you what i am trying to do. Apart from sharing also i want to get other insight form others . As what my collegue out there are thinking in regard to the issue of caching.

For a long time i have trying to have a generic cache which is a first class citizen in the csla.net framework .

To have a first class cache for csla.net is no an easy task due to many reason but the most intuitive once are:

  1) CSLA.NET is not tied to any data access technology. So the idea of intercepting queries and targeting to the cache is  very ideal for you have to define the query interceptors for all data access technoligies.

2) CSLA.NET objects are mobile so its data access can run  locally or at the server . IF the cache is locally located fine but when you change form 2 tire to 3 -tire the cache will be have to be tuned accordingly of course a lot of work.

3) CSLA.NEt objects are designed to work even in the silverlight runtime. so any cache to support the objects are also need to accomodate the behaviour of silverlight if at all we want to honour the easy of switching the objects working in windows environment  to silverlight runtime 

Due to all that reason i have come up with the attached code which follows these design decisions.

- I dropped the idea of incorparating the cache into  fething XYZ-dataportal methods as their execution location is not known( locally or at the server ?).

   Also putting the cache is the fetching  XYZ methods does not bring sense as XYX methods are to be intercepted ( the should be called only if there is not data at the client) 

  Lasty the cache should be working also in the silverlight runtime where there is not xyz methods (if not local proxy)

- I dropped the idea of query interceptors due to absence of supported in csla.net data access technology( which is good)

Also query interceptors are not feasible if the cache is to work in the silverlight environment for the query structure has some  dependency on the structure dataaccess technology. Escpeciaaly of ADO.NET EF , LINQ to SQL which their definitions i dont know if they can deployed in the silverlight runtime.

The options lead me to:

1)Intercept execution of dataportal xyz fetch methods and not query result.

        So the developer ends up doing whatever in the xyz and the cache is totally ignorant to the      logic     i n the xyz

How it does.

First we cache csla.net Objects and not raw data.

So if you have two different objects(classes) with the same data( Database table as well columns) they will all be cached as two different cacheitem

The only thing i could use to intercept execution of dataportalXYZ fetch method is by using the criteria objects.

IF ANY FETCH METHOD IN AN OBJECT  EXECUTES ONLY ONE SQL COMMAND

IT CAN BE SAID THAT CRITERIA OBJECT IS REPRESENTS THE QUERY

Before any execution the cache constructs the key from criteria object  .

Private Function CreateKeyString(Of T As csla.Core.MobileObject)(ByVal key As Object) As String

        Dim _key As String = GetType(T).FullName + key.GetType.FullName

        For Each df In key.GetType.GetProperties
            _key = _key + df.GetValue(key, Nothing).ToString()
        Next
        Return _key

    End Function

The function has a generic type T which passes the type which a criteria is for. This is so since there a re some citeria which will be used by more than one type. There are other possibilites here is see especially if the criteria is of type criteria base. But the function is private no worry much.

The method constructs the key by getting the values of the criteria objects and the name of the object .The result is that the key will be unique for any call.

 

Another thing is that i have written a cachefactory, to be renamed to cachedataportal or ....? i dont know.

Its main entry point is

Public Function GetCache(ByVal name As String) As Cache '(Of csla.Core.MobileObject)
        Return GetCache(name, 10, True)
    End Function

Public Function GetCache(ByVal name As String, ByVal expiryTime As Integer, ByVal allowOffLine As Boolean) As Cache '(Of csla.Core.MobileObject)

     
        If Not caches.ContainsKey(name) Then
            CreateCache(name, expiryTime, allowOffLine)
        End If
        Return caches(name)
    End Function


    Private Sub CreateCache(ByVal name As String, ByVal validDuration As Integer, ByVal AllowOfLine As Boolean)
        caches.Add(name, New Cache(name, validDuration, AllowOfLine))
    End Sub

    Private Function GetCache() As Cache
        Return GetCache("default")
    End Function

I have the idea of the concept of named cache. You can have different a policies on different type of objects. rather than defining on each obects you can define a cache with name, ExpiryTime as well as it can be offline or not and other(to be done).

Then objects will be cached in their allocated cache.

Default cache is named "default", with 10 minuted validDuration and AllowOFLine of false.

If the cache is not there it will be created

 Private _caches As Dictionary(Of String, Cache)

Private Sub CreateCache(ByVal name As String, ByVal validDuration As Integer, ByVal AllowOfLine As Boolean)
        caches.Add(name, New Cache(name, validDuration, AllowOfLine))
    End Sub

 

//FOR WINDOWS

 

  Public Function Fetch(Of T As csla.Core.MobileObject)(ByVal criteria As Object) As T
        Dim _cache As Cache = Nothing
        If TypeOf criteria Is CachableCriteria Then
            _cache = GetCache(CType(criteria, CachableCriteria).CacheName)
        Else
            _cache = GetCache()
        End If
        Return _cache.Get(Of T)(criteria)
    End Function

 

// FOR SILVERLIGHT

//INCOMPLETE but latery before current refactoring  it worked

//Italiced words needs to be removed . I am sory

 Public Function BeginFetch(Of T As csla.Core.MobileObject)(ByVal criteria As Object) as T
        Dim _cache As Cache = Nothing
        If TypeOf criteria Is CachableCriteria Then
            _cache = GetCache(CType(criteria, CachableCriteria).CacheName)
        Else
            _cache = GetCache()
        End If
        '  Return _cache.
    End Function

I have also defined the CachableCriteria inherits from Criteria base

<Serializable()> _
Public MustInherit Class CachableCriteria
    Inherits csla.CriteriaBase

 

    Public Overridable ReadOnly Property CacheName() As String
        Get
            Return "default"
        End Get
    End Property

 

End Class

This is designed so that you can define in which cache the criteria result should be cached. And all the policies defined on the cache will be applied to the result.

If you just want to use the default cache just inherit the criteria from criterabase or do as you like.

To save in the other cache inherite the criteria object from the CachableCriteria class and override the cache name returning the cachename to be used otherwise it will end up using the default cache.

For modification:  I plan to have another cache class  property  IsEnabled with default true. In case one anticipate to use the cache but not for now.


How to use.

 

Look in the class2

In the factory

  Public Shared Sub GetClass(ByVal age As Integer)
        CacheFactory.Fetch(Of Class2)(New NGH(age))
    End Sub

The cach will call dataportal fetch in case the object is not cached or is invalidated.

The cachefactory/cache  can be also the dataportal by itself not decided.

Note i just made this codes yesterday. so they are mainly proof of concept and not tested vigourously apart from the example 

Of line /Online capability will be added. By having the classes inherit from CachableBusinessBase (to be writtern) which will override Save and BeginSave and just check the factory if online proceed otherwise check validation rules if valid  serielize and/or encrypt to disk.

We shall add the fonfiguration capabity so that the names and policies of caches can be defined in the configuration file.

Should the configuration file( or just a file) be placed in the application server so that the changes are automatically rolled to all client ?? 

There is a work to hook the objects saved event in the cache.

The cache caches only the parent objects but it has not tested against other objects stereotypes such as lists and readonly. Obvious it will not cache command objects(at least for now)

There are many design issues and actual work to be done.

The project for silverlight and Windows share the same files , assembly name though i dont think the cache itself will move between the two runtime, but think it will enable the same csla.net obects two function between the environments with easy while maintaining/using the cache.

The root namespace is csla for easy usage.

Note still under development so very flagile codes

 

 

The thanx for your hand

Ayubu

 

Copyright (c) Marimer LLC