views:

91

answers:

2

I realise there have been a few posts regarding where to add a cache check/update and the separation of concerns between the controller, the model and the caching code.

There are two great examples that I have tried to work with but being new to MVC I wonder which one is the cleanest and suits the MVC methodology the best? I know you need to take into account DI and unit testing.

Example 1 (Helper method with delegate)

...in controller

var myObject = CacheDataHelper.Get(thisID, () =>
WebServiceServiceWrapper.GetMyObjectBythisID(thisID));

Example 2 (check for cache in model class) in controller

var myObject =   WebServiceServiceWrapper.GetMyObjectBythisID(thisID));

then in model class..............

if (!CacheDataHelper.Get(cachekey, out myObject)) {

//do some repository processing

// Add obect to cache CacheDataHelper.Add(myObject, cachekey);

}

Both use a static cache helper class but the first example uses a method signature with a delegate method passed in that has the name of the repository method being called. If the data is not in cache the method is called and the cache helper class handles the adding or updating to the current cache.

In the second example the cache check is part of the repository method with an extra line to call the cache helper add method to update the current cache.

Due to my lack of experience and knowledge I am not sure which one is best suited to MVC. I like the idea of calling the cache helper with the delegate method name in order to remove any cache code in the repository but I am not sure if using the static method in the controller is ideal?

The second example deals with the above but now there is no separation between the caching check and the repository lookup. Perhaps that is not a problem as you know it requires caching anyway?

+1  A: 

I have a fairly large project where we are doing Example 1 - Cache static class with retrieval delegate used from controllers. Actually, in our case we have a service class layer that handles caching and the controllers reference the service layer. The service layer deals with data retrieval, caching, permission checking, etc, while the controllers deal mainly with assembling data from the services into models.

Per your question, you don't necessarily need a static cache helper. You could use DI to inject an instance of your cache helper, so then you could mock it out for testing, etc.

John Bledsoe
A: 

I would certainly not put the caching code in the model. It has no business knowing about the caching characteristics of the web application. You also don't need to use a static instance in your controllers. You could achieve the same effect and retain testability by making your CacheHelper a regular class (wrapped around the web cache, presumably) or a singleton. In either case, you would use injection to supply an instance to your controller.

A simple way to do this, without a DI framework, is to have the constructor that takes an instance of the helper create a suitable default if the supplied parameter is null. Your default constructor, which the controller factory uses, calls this constructor with a null instance and so you get your default. Your tests call it with a mock instance and thus you maintain testability.

If you use a regular class for your helper -- I'd strongly recommend that you try to make this work -- you can use the same technique to inject a Cache object. To it so that it can be tested as well.

tvanfosson
With a regular class I can do that no problem as we have been using IOC Factory to pass in an interface object and set the private variable like so:private readonly IConfirmEnquiryServiceWrapper confirmEnquiryServiceWrapper;public EnquiriesController(IConfirmEnquiryServiceWrapper confirmEnquiryServiceWrap){ confirmEnquiryServiceWrapper = confirmEnquiryServiceWrap; } However I have tried to do same with singleton but get run time errors to with IOC factory.Do I really need to use a singleton? Any examples would be appreciated.
Euston