Browser Cache için JS ve CSS File Versiyonlama

Sitemizdeki js,css gibi dosyalar üzerinde değişiklikler yaptığımızda sitemizi güncelleriz fakat bazen browser cachesinden eski file’ı kullanabilir. Ve durum sıkıntı yaratabilir. Bunun önüne geçmek için File Versioning kullanılmalıdır.  versiyonlama işlemine versiyon değerini kendimiz set edebiliriz v=1.0 gibi. fakat bunu her değişiklikte elle yazmak yerine otomatize etmek çok daha mantıklı. Yapmak istediğimiz şey değişiklik yapılan dosyanın son değişiklik zamanını alıp dosya sonuna version olarak eklemek. Tabi Saniyede 50.000 request aldığımızı düşünürsek, her gelen istekte gidip sitede kullanılan css & js dosyalarının son değiştirilme tarihini almaya kalkarsak, bir süre sonra serverlarımız bu yükü kaldıramayabilir. Bunun için ise Data cache kullanılabilir. Bu dosyayı 5dk kadar cachelemek server işlem yükünü azaltacaktır.

Öncelikle Interfacemizi ekliyoruz;

public interface IDefaultCacheManager
{
    object Get(string key);
    void Set(string key, object data, int cacheTime);
    bool IsSet(string key);
    void Invalidate(string key);
}

Cache işlemleri methodlarım

public class DefaultCacheManager : IDefaultCacheManager
{
    private ObjectCache Cache { get { return MemoryCache.Default; } }

    public object Get(string key)
    {
        return Cache[key];
    }

    public void Set(string key, object data, int cacheTime)
    {
        CacheItemPolicy policy = new CacheItemPolicy();
        policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime);
        Cache.Add(new CacheItem(key,data),policy);
    }

    public bool IsSet(string key)
    {
        return (Cache[key] != null);
    }

    public void Invalidate(string key)
    {
        Cache.Remove(key);
    }
}

Helper’ım

public static class HtmlHelpers
{
    public static IDefaultCacheManager Cache = new DefaultCacheManager();

    public static string FileVersioning(this HtmlHelper helper, string fileName)
    {
        string cacheKey = fileName;
        object cachedVersion = Cache.Get(cacheKey);
        if (cachedVersion != null)
        {
            return cachedVersion as string;
        }
        else
        {
            var serverFilePath = HttpContext.Current.Server.MapPath(fileName);
            var version = File.GetLastWriteTime(serverFilePath).ToString("yyyyMMddhhmmss");
            Cache.Set(cacheKey, string.Format("{0}?v={1}", fileName, version),5);
            return string.Format("{0}?v={1}", fileName,version);
        }  
    }
}

View içerisinde kullanımı

<script src="@Html.FileVersioning("/Content/jquery-1.8.3.js")"></script>

Asp.net Cache Class

public class CacheHelper
{
    private static Cache cache;
    private static object obj;

    static CacheHelper()
    {
        cache = HttpContext.Current.Cache;
        obj = new object();
    }

    public static DataTable GetProductsThreadSafe()
    {
        //Bu desende ise Cache nesnesine eş zamanlı gelecek birden fazla talepten sadece ilk gelen talep
        //Cache nesnesini olusturacaktir
        if (cache["Products"] == null)
        {
            lock (obj) //Burada obj nesnesi kilitlenerek farklı thread'lerin blok içerisine erişimi engellenmektedir
            {
                if (cache["Products"] == null)
                {
                    SqlConnection con = new SqlConnection("data source=localhost; database=Northwind; integrated security=true");
                    SqlDataAdapter da = new SqlDataAdapter(" Select * From Products; Waitfor delay '00:00:20'", con);
                    DataTable dt = new DataTable();
                    da.Fill(dt);
                    cache.Insert("Products", dt, null, DateTime.Now.AddMinutes(5),System.Web.Caching.Cache.NoSlidingExpiration);
                 }
             }
    }

    return (DataTable) cache["Products"];
    }
}