Prequel -Asp.net use caching (a) to you a brief introduction
- What is Cache
- Why use caching
- Simple
HttpRuntime.Cache
to use caching mechanisms
This program is to share the cache becomes more elastic
The second outline
- Proposed interface, improve exchangeability
- Use generic rewrite the cache read mode
- Use expansion method to rewrite the cache
- Proposed interface, improve exchangeability
Situation:
There are currently projects using HttpRuntime.Cache
objects
In addition to using the cache memory in Asp.Net HttpRuntime.Cache
outside class, there are many solutions such as using Memcache , Redis ...
If we use the original HttpRuntime.Cache
class but then they have to turn to other cache ways how to do?
public class HomeController : Controller
{
System.Web.Caching.Cache cacheContainer = HttpRuntime.Cache;
public ActionResult Index()
{
string cacheData = cacheContainer.Get("data") as string;
if (cacheData==null)
{
cacheContainer.Insert("test1", DateTime.Now.ToShortDateString());
}
return View(cacheData);
}
}
Although the use of different cache ways, but I remember my last article focused on the cache will have two actions, reading and writing , so there will be a basic reading and writing these two actions
OOP has a very important concept in multiple classes have to consider making repetitive movements parent
In order to facilitate understanding I put HttpRuntime.Cache
the package into a class
public class NetCache {
System.Web.Caching.Cache cacheContainer = HttpRuntime.Cache;
public object GetCacheObject(string key) {
return cacheContainer.Get(key);
}
public void SetCache(string key,object obj) {
cacheContainer.Insert(key, obj);
}
}
Here there is another Memcache
cache Class
public class MemeryCache {
private ObjectCache _cache = MemoryCache.Default;
public object GetCacheObject(string key)
{
return _cache[cacheKey];
}
public void SetCache(string key, object obj)
{
var policy = new CacheItemPolicy();
policy.RemovedCallback = OnFileContentsCacheRemove;
// 设定缓存时间2分钟
policy.AbsoluteExpiration = DateTimeOffset.Now.Minute(2);
_cache.Set(cacheKey, fileContents, policy);
}
}
To not focus on these two objects inside detail, we can see that they all have GetCacheObject
methods and SetCache
methods
Then we can propose in due course interface (interface) , as these two classes of contract
public interface ICache {
void Set(string key,object obj);
object Get(string key);
}
After their two class implements ICache
the interface
public class MemeryCache : ICache
{
private ObjectCache _cache = MemoryCache.Default;
public object Get(string key)
{
return _cache[cacheKey];
}
public void Set(string key, object obj)
{
var policy = new CacheItemPolicy();
policy.RemovedCallback = OnFileContentsCacheRemove;
// 设定缓存时间2分钟
policy.AbsoluteExpiration = DateTimeOffset.Now.Minute(2);
_cache.Set(cacheKey, fileContents, policy);
}
}
public class NetCache : ICache
{
System.Web.Caching.Cache cacheContainer = HttpRuntime.Cache;
public object Get(string key) {
return cacheContainer.Get(key);
}
public void Set(string key,object obj) {
cacheContainer.Insert(key, obj);
}
}
What are the benefits proposed interface?
We can change the program in front of IOC dependency injection way, do not use hard-coded in the program HttpRuntime.Cache
by the IOC container to help us to target injection program.
Note: I use constructor injection method
public class HomeController : Controller
{
//不用写死使用 HttpRuntime.Cache
//System.Web.Caching.Cache cacheContainer = HttpRuntime.Cache;
ICache cacheContainer;
public HomeController(ICache Container){
cacheContainer = Container;
}
public ActionResult Index()
{
string cacheData = cacheContainer.Get("data") as string;
if (cacheData==null)
{
cacheContainer.Insert("test1", DateTime.Now.ToShortDateString());
}
return View(cacheData);
}
}
ICache
Become caching program lubricant can make the program more flexible
- Use generic rewrite the cache read mode
My answer is the second way in StackOverFlow
The most important technique is the Get
method returns Object
into the use of generics
public T GetOrSetCache
(string key,T obj, int cacheTime) where T:class,new()
{
System.Web.Caching.Cache cacheContainer = HttpRuntime.Cache;
T cacheObj = cacheContainer.Get(key) as T;
if (cacheObj == null)
{
cacheContainer.Insert(key,
obj,
null,
DateTime.Now.AddMinutes(cacheTime),
System.Web.Caching.Cache.NoSlidingExpiration);
cacheObj = obj;
}
return cacheObj;
}
Let us use can become
var data = DateTime.Now.ToShortDateString();
int numberOfMinutes = 3;
data = GetOrSetCache("name1",data,numberOfMinutes );
We just need to call the GetOrSetCache
method, which the GetCache
and SetCache
packages up
- Use expansion method to rewrite the cache
.Net has provided a very convenient mechanism expansion method , this mechanism to help us solve a very important question.
We can expand the package but did not have the source code of the class ,
During this procedure, use may use the expression, to make the program more concise !!Func
lambda
public static TObj GetOrSetCache
(this Func
selector, string key, int cacheTime) where TObj : class
{
Cache cacheContainer = HttpRuntime.Cache;
//get cache Object
var obj = cacheContainer.Get(key) as TObj;
//if there isn't cache object add this object to cache
if (obj == null)
{
obj = selector();
cacheContainer.Insert(key, obj);
}
return obj;
}
When we use the following
Change concise action more beautiful
int numberOfMinutes = 3;
data = GetOrSetCache(()=> DateTime.Now.ToShortDateString(),"name1",data,numberOfMinutes );
Plus with the field mapping:
With the use of extension methods and interfaces
public class WebDefaultCache : ICache
{
Cache cacheContainer = HttpRuntime.Cache;
public object Get(string key)
{
return cacheContainer.Get(key);
}
public void Set(string key, object obj)
{
cacheContainer.Insert(key, obj);
}
}
public interface ICache{
void Set(string key, object obj);
object Get(string key);
}
public static class InfrastructureExtension
{
public static TObj GetOrSetCache
(this Func
selector, string key) where TObj : class {
return GetOrSetCache(selector, key,10);
}
public static TObj GetOrSetCache
(this Func
selector, string key, int cacheTime) where TObj : class
{
return GetOrSetCache(selector, key, cacheTime, new WebDefaultCache());
}
public static TObj GetOrSetCache
(this Func
selector, string key, int cacheTime, ICache cacheContainer) where TObj : class { //get cache Object var obj = cacheContainer.Get(key) as TObj; //if there isn't cache object add this object to cache if (obj == null) { obj = selector(); cacheContainer.Set(key, obj); } return obj; } }
Although the use of a third and as
yet we have much use method overloading more than pass a parameter ICache
interface allows us to decide which way you want to use cache, do not go there to change the program when writing programs.
Plus with the field mapping program I put my own common ExtenionTool project
If you found this article helpful, you can pay the corner stone ^^ encourage infighting
Original: Big Box Asp.net use caching (b)