Writing cache based repositories for web application prototyping

When I started building in-house demo application I thought about how to solve temporary data layer so I don’t have to use real database and object mappings for it. Playing with new object model and new components I move way faster if I don’t have any additional ballast that I can avoid. So I wrote simple cache based repository mechanism I can use to imitate real repositories that I will write in the future.

NB! Don’t develop this idea too much further because you can use my method  only to some certain point. Don’t forget that you have also maintain relations between objects and keep them consistent. Use my method until your object model is small and simple.

If you look for something perfect you don’t find it here. It is just my pretty raw solution that I still test and I am not very sure if I don’t replace it with something better soon.

Structure of my application

Basically my application follows structure show here (example data, just took it from air):

  • ppName.Core (all business classes and interfaces are here)
    • Contacts
      • Person.cs
      • Company.cs
    • Projects
      • Project.cs
      • ProjectTask.cs
    • Repositories
      • IPersonRepository
      • ICompanyRepository
    • BusinessEntity.cs
  • AppName.Data.CacheBasedStorage (this is the topic of this posting)
    • Repositories
      • BaseRepository.cs
      • PersonRepository.cs
      • CompanyRepository.cs
  • AppName.Data.NHibernate (not there really, but comes if users like my app)
  • AppName.Infrastructure (IoC, validation and other “low level” stuff)
    • Resolver.cs
    • Validator.cs
  • AppName.Web (web version of my application)

I think this structure tells almost everything about architecture. Okay, some notes too. AppName.Core has only interfaces for repositories because it doesn’t deal with objects persisting and doesn’t provide any Data Access Layer logic. It is all done in external repository implementations. I use Unity as IoC container and Resolver class in infrastructure library is mediator between client applications and repository implementations. I can always move from Unity to some other IoC container and client applications doesn’t need to be built again.

Why cache based storage?

I considered different ways about how to implement my toy-repositories and cache seemed to me as pretty good option:

  • it is accessible to all users of my application,
  • it is easy to use,
  • it needs no additional coding for saving and loading data,
  • it’s not a problem when data expires – I need data for building and demonstration purposes only.

Of course, it is also possible to use some more elegant solutions but … I am just too lazy to run for idealism and beautiful things. When I get something that works right now for me – I am happy. In this point I don’t know if users like my app or not and I don’t want to make any moves I can avoid.

Implementation of repositories

Cache based data storage implementation is in AppName.Data.CacheBasedStorage library. In short we have abstract class BaseRepository that does all the dirty work for us. The real repositories extend it and they also follow repository interfaces from core library. Basically they wrap calls to base library with correct types.

Let’s start with BaseRepository. The implementation shown here is awful in multi-user context, but for one-man testing and developing it is okay.


public abstract class BaseRepository
{
   
private Cache
_cache;

   
protected
BaseRepository()
    {
       
// Here we add some sample data to cache
    }

   
private Cache
Cache
    {
       
get
        {
           
if (_cache != null
)
               
return
_cache;

            _cache =
HttpContext
.Current.Cache;
           
return
_cache;
        }
    }

   
protected T Get<T>(int
id)
    {
       
var
list = GetList<T>();
       
if (list == null
)
           
return default
(T);

       
if
(list.ContainsKey(id))
           
return
list[id];

       
return default
(T);
    }

   
protected void Save<T>(T instance) where T : BusinessEntity
    {
       
var
list = GetList<T>();
       
var
id = instance.Id;

       
if
(id == 0)
        {
           
if
(list.Count > 0)
                id = (
from l in
list
                       
orderby l.Key descending
                        select
l.Key).First();
            id++;
            instance.Id = id;
           
if
(list.ContainsKey(id))
                list[id] = instance;
           
else
                list.Add(id, instance);
        }
       
else
            list[id] = instance;
    }

   
protected void Delete<T>(T instance) where T : BusinessEntity
    {
       
var
list = GetList<T>();
       
if
(list.ContainsKey(instance.Id))
            list.Remove(instance.Id);
    }

   
protected IDictionary<int, T> GetList<T>() where T : BusinessEntity
    {
       
var type = typeof
(T).ToString();

       
if (Cache[type] != null
)
           
return (IDictionary<int
, T>)Cache[type];

       
var list = new Dictionary<int
, T>();
        Cache[type] = list;
       
return list;
    }
}

Now you may have question: what about data querying? My answer is simple: let’s take LINQ and use it. We don’t have tons of data, we don’t have millions of users – we have only our development machine and one or two users.

And here is one example repository. It is very simple and as stated above it just wraps calls to base repository with correct types. Of course, if I need some more logic in repositories then I can add it to appropriate methods. Later, if users like my applications, I can take this logic from my toy-repositories and put it in real repositories.


public class CompanyRepository : BaseRepository, ICompanyRepository
{
   
public Company GetCompanyById(int
id)
    {
       
return Get<Company
>(id);
    }

   
public CompanyName GetCompanyNameById(int
id)
    {
       
return Get<CompanyName
>(id);
    }

   
public IList<Company
> ListCompanies()
    {
       
return GetList<Company
>().ToList();
    }

   
private void Save(Company
company)
    {
        Save<
Company
>(company);
    }

   
public void SaveCompanyName(CompanyName
name)
    {
        Save<
CompanyName
>(name);
    }

   
public void Delete(Company
company)
    {
        Delete<
Company
>(company);
    }

   
public void DeleteCompanyName(CompanyName
name)
    {
        Delete<
CompanyName>(name);
    }
}

Well, this is my current experiment with repositories that should save me some time and be flexible enough to get working prototypes done. I also like the idea that I can keep my object model evolving with my prototype so I create additional value when building prototypes – when I have to start real coding I can use classes I wrote during prototyping and hopefully it saves me some time.


Leave a Reply

Your email address will not be published. Required fields are marked *