2011-11-09 2 views
1

우리는 외부 캐시를 사용하도록 사이트를 리팩터링하고 있으며 사용자 지정 OutputCacheProvider을 사용하여 첫 번째 단계를 수행했습니다. 먼저 우리는 MemoryCache을 감싸는 단순한 공급자를 만들었고 우리가 의존 관계를 관리하는 방식에 문제가 있음을 발견했습니다.ASP.NET 사용자 지정 OutputCacheProvider를 사용하여 엔터티 변경시 페이지 무효화

우리는 사용자 정의 여분의 키 의존성 특정 기관이 변경 될 때 페이지 세트를 무효화 할 수 있도록이 기능을 유지하기 위해 나는 몇 가지 옵션 참조 추가 OutputCacheAttribute가 수동으로 CachedVary을 제거

  1. 을 그 ASP.NET은 키가 "a2" + query"이라고 가정하고 캐시에 저장합니다. 이것은 효과가있는 것처럼 보이지만 신뢰성에 대해서는 확신하지 못합니다.

  2. 캐시에서 제거해야하는 페이지 배열을 포함하는 캐시 키를 추가 한 다음 키가 제거됩니다. 외부 캐시 키 종속성 기능이있는 경우이를 사용하십시오. 이것은 우리가 사용하는 핵심 의존성을 에뮬레이트하기에 충분해야하지만보다 복잡한 방식으로 이루어져야합니다.

  3. 이 점을 잊어 버리면 캐시 기간을 줄이고 걱정하지 말고 만료 시키십시오.

  4. 우리 자신의 페이지 캐싱을 수행하고 ASP.NET 출력 캐시를 잊어 버리지 마세요.별로 매력이 없습니다.

다른 방법이있을 것입니다. 모든 팁, 경험 또는 권장 사항?

답변

1

나는 우리가 기록을 위해 채택한 해결책으로 내 자신의 질문에 답합니다.

우리는 OutputCacheAttribute에서 요청 된 URL과 일부 매개 변수에 따라 키가있는 빈 캐시 객체를 추가합니다. 이 옵션은 페이지를 외부 적으로 무효화하는 데 사용됩니다.

그런 다음 현재 요청에 종속되고 이전 cacheKey를 포함하는 키가있는 다른 개체도 추가합니다.

마지막으로 정적 ValidationCallback이 설정됩니다. 콜백은 현재 요청에 대한 키 값 (의존성 키)을 가져옵니다. null이 아닌 경우 종속성의 값을 가져오고, null이면 종속성이 제거되고 validationStatusHttpValidationStatus.Invalid으로 설정합니다.

일부 코드를 설명하기 :

public override void OnResultExecuting(ResultExecutingContext filterContext) 
{ 
    base.OnResultExecuting(filterContext); 

    // Build dependencies 
    BuildDependencies(paramsToDepend, filterContext.Controller, this.Duration); 
} 

private void BuildDependencies(IEnumerable<string> paramsToDepend, ControllerBase controller, int duration) 
{ 
    string[] valuesToInclude = GetValuesToInclude(paramsToInclude, controller.ControllerContext); 

    // Build the caché key for the current request 
    var cacheKey = CacheKeyProvider.GetCacheKeyFor(controller, paramsToDepend); 

    var cache = controller.ControllerContext.HttpContext.Cache; 
    var cacheValue = cache.Get(cacheKey); 

    if (cacheValue == null) 
    { 
     // The key is created if not exists 
     Provider.Add(cacheKey, new object(), Context.CurrentDateTime.AddSeconds(duration).ToUniversalTime()); 
    } 

    // Add the dependency 
    Provider.Set(CachePrefix + controller.ControllerContext.HttpContext.Request.Path, cacheKey, Context.CurrentDateTime.AddSeconds(duration).ToUniversalTime()); 

    // Register callback 
    controller.ControllerContext.HttpContext.Response.Cache.AddValidationCallback(new HttpCacheValidateHandler(ValidationCallback), null); 
} 

public static void ValidationCallback(HttpContext context, object data, ref HttpValidationStatus validationStatus) 
{ 
    var provider = OutputCache.Providers[OutputCache.DefaultProviderName]; 

    var dependency = provider.Get(CachePrefix + context.Request.RawUrl) as string; 

    if (dependency == null) return; 

    var depValue = provider.Get(dependency); 

    // If it's null, someone has invelidated the caché (an entity was modified) 
    if (depValue == null) 
    { 
     validationStatus = HttpValidationStatus.Invalid; 
    } 
}