简体   繁体   中英

Where to implement caching - Class Library or Windows Service

I have a Windows Service that calls a class library (on a worker thread) periodically using a timer. This class library has all the required application functionality and the Windows Service is nothing but a simple hosting environment. The library as part of its execution needs to make a call to the DB and fetch a bunch of records. These records don't change frequently (think weeks) and I'd like to cache them in memory. Should I implement the caching structure in the class library or the Windows Service?

Essentially what I am a bit unsure of is, once a Windows Service loads, and then makes periodic calls to this class library does the app domain that the library runs in remain the same for all executions of the library (via a worker thread every few minutes). Because if it isn't, the purpose of implementing the cache inside the library seems pointless.

Could someone help me understand this?

In similar situation I implemented cache in the library (since is your main code base) but made it independent from main call service do.

Something like this

class ServiceRun
{
    private MyLibrary.LibraryContext _context;
    private Timer _timer;

    public ServiceRun()
    {
        _context = MyLibrary.Core.InitializeBaseData();
        _timer = new Timer(10000);
        _timer.OnTick+= ()=> MyLibrary.Core.DoAction(_context);
    }
}

Should LibraryContext care about it's own integrity or service need to call something like _context.Refresh() with another timer is completely on your choice because hardly depends on data stored in it.

This is a valid design question, but I think you are approaching it from a wrong angle: rather than thinking about app domains and other things that may make it harder for you to implement the functionality, think where it belongs from the point of view of the logical design.

Here are some considerations that may influence your thinking:

  • Your class library presents a certain interface to its users. Does it make sense for all users that call your class library to sit behind a layer of an in-memory cache? If the answer to this question is "yes", then caching functionality belongs in the class library.
  • Since the class library is a separate entity, presumably you would like to hide some implementation details from the library's customers, such as the window's service. If the service is to cache the data for some period of time, then the service would possess the knowledge that the data changes infrequently. Should this be undesirable, put the caching functionality in the class library.
  • If the data by its nature can change more frequently than it does for the particular windows service that you are writing, then the caching belongs in the windows service.
  • If you plan to implement additional functionality in the future that would control the state of the cache, for example, a way to force cache invalidation, then the functionality belongs in the windows service (although you could also put it in the class library, and give its users explicit control over its state).

Your caching methods will be based on your implementation. From what you have described above your service is a simple wrapper. This wrapper calls a (I am assuming through threading) class library that does the actual process.

With this design I would suggest implementing your "caching services" in the class library. Although the classes in your library are being executed then disposed of, there is no reason why your class library can't keep references to cache after other classes in the library have finished.

Personally, because the class library requires the cached objects I don't see any reason why the service needs access to these objects. Additionally by maintaining the cache in your class library allows you to "hide" your cached objects. Finally, and another big positive would be debugging and bug fixing will be much easier. As you can run the class library inside any other application you are not bound to debugging in a windows service, which can be quite challenging itself.

I think the real question is what sort of caching should you use, this makes a big difference to the total memory being consumed. Now that is a different question all together.

For caching you have many implementation options. The most common in-memory caching is done using the MemoryCache feature as-part of the .Net framework. This supports expreration policies, and a full Cacheing wrapper similar to the ASP.Net web implementation.

MSDN for Memory Cache: http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx

In the end in my opinion I would probably wrap your caching system into another class using Singletons or through DependencyInjection to maintain the cached objects.

Hope this helps.

Nico

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM