csla

Reloading child BusinessListBase object inside a parent ReadOnlyBase object on database update


I'm very new to CSLA and have been roped in to fix bugs in a legacy code that uses CSLA. I'm facing the following issue,

Our microservice loads a ReadOnlyBase during the first call and I'm assuming it caches al the data in memory after that. Another microservice directly updates the database. How do I force refresh the child object? We do have a notification service that notifies changes to the database(I can know which is the corresponding CSLA object) but I don't know how to do this?

The following is a sample code,

public class C : BusinessBase<C>
    {
        public int Id { get; set; }
        public string Value { get; set; }
        public bool IsActive { get; set; }
    }

    public class CList : BusinessListBase<CList, C>
    {
        
    }

    public class B : ReadOnlyBase<B>
    {
        public CList Cs
        {
            get;set;
        }
    }


    public class A : ReadOnlyBase<A>
    {
        public B Games
        {
            get; set;
        }
    }

Solution

  • In most cases, services are stateless and so maintain no data between service calls.

    So if your first service returns the A/B/C data to the client, then only the client would have that state data.

    Presumably the client then calls the second service, sending the data to that service. The second service will need to use that data to load the business object graph with data, and then use the CSLA data portal to save it.

    You can't save data that is in a ReadOnlyBase - that type of domain object is read-only. So only the C data can be saved, because that's a read-write domain object.

    Back to the A and B types, which are read-only. These might be cached on the server, but if they are that is code in your application. CSLA doesn't do any caching by itself.

    A common way to cache read-only objects is to use a factory method to fetch the object, and in that factory method there is code to access the cache.

    Simplistically, it might be like this pseudocode:

    public static async Task<B> GetBAsync(IDataPortal<B> portal)
    {
      var result = HttpContext.Session["BCache"];
      if (result == null)
      {
        result = await portal.FetchAsync();
        HttpContext.Session["BCache"] = result;
      }
      return result;
    }
    

    The cache might be a static field, Session, REDIS, or whatever you choose.