2014-05-22 2 views
0

MvcSiteMapProvider 4.6.3, MVC 4를 사용 중입니다. DI를 사용하여 Sitemap을 구성하십시오.XML이 변경되면 캐시를 새로 고치는 방법은 무엇입니까?

this.For<System.Runtime.Caching.ObjectCache>() 
    .Use(s => System.Runtime.Caching.MemoryCache.Default); 

this.For(typeof (ICacheProvider<>)).Use(typeof (RuntimeCacheProvider<>)); 
var rootCacheDependency = this.For<ICacheDependency>().Use<RuntimeFileCacheDependency>() 
    .Ctor<string>("fileName").Is(rootFileName); 

var rootCacheDetails = this.For<ICacheDetails>().Use<CacheDetails>() 
    .Ctor<TimeSpan>("absoluteCacheExpiration").Is(absoluteCacheExpiration) 
    .Ctor<TimeSpan>("slidingCacheExpiration").Is(TimeSpan.MinValue) 
    .Ctor<ICacheDependency>().Is(rootCacheDependency); 

var cacheDetails = new List<SmartInstance<CacheDetails>>(); 
var xmlSources = new List<SmartInstance<FileXmlSource>>(); 

Sitemap xml이 업데이트되면 캐시를 자동으로 업데이트하는 방법은 무엇입니까?

MvcSitemapProvider를 v3에서 v4로 업그레이드 중입니다. 버전 3에서는 사이트 맵이 자동으로 새로 고쳐집니다.

캐시 만료 시간을 5 분으로 설정했는데, 문제가 있습니까?

TimeSpan absoluteCacheExpiration = TimeSpan.FromMinutes(5); 

var rootCacheDetails = this.For<ICacheDetails>().Use<CacheDetails>() 
      .Ctor<TimeSpan>("absoluteCacheExpiration").Is(absoluteCacheExpiration) 
      .Ctor<TimeSpan>("slidingCacheExpiration").Is(TimeSpan.MinValue) 
      .Ctor<ICacheDependency>().Is(rootCacheDependency); 

UPDATE

내가 사이트 맵 XML 캐시는 캐시가 만료 5 분까지 업데이트되지 않은 파일을 변경. 여러 개의 sitemap xml 파일을 사용하고 있습니다.

 var sitmapPath = HostingEnvironment.MapPath("~/Sitemaps"); 
     var sitemaps = new List<string>(); 
     if (sitmapPath != null) 
     { 
      sitemaps.AddRange(Directory.GetFiles(sitmapPath, "*.sitemap")); 
     } 

     foreach (var sitemapFileName in sitemaps) 
     { 
      var cacheDependencie = 
       this.For<ICacheDependency>() 
       .Use<RuntimeFileCacheDependency>() 
       .Ctor<string>("fileName") 
       .Is(sitemapFileName); 

      cacheDetails.Add(this.For<ICacheDetails>().Use<CacheDetails>() 
      .Ctor<TimeSpan>("absoluteCacheExpiration").Is(absoluteCacheExpiration) 
      .Ctor<TimeSpan>("slidingCacheExpiration").Is(TimeSpan.MinValue) 
      .Ctor<ICacheDependency>().Is(cacheDependencie)); 

      xmlSources.Add(this.For<IXmlSource>().Use<FileXmlSource>() 
       .Ctor<string>("fileName").Is(sitemapFileName)); 
     } 

이것이 작동하지 않는 이유입니까?

+0

답변을 업데이트했습니다. – NightOwl888

답변

0

내가 게시 한 코드에 문제가 보이지 않습니다. 그러나 XML이 변경 될 때 다시로드되는 것은 RuntimeFileCacheDependency입니다.

RuntimeFileCacheDependency는 fileName 인수가 절대 경로가 될 것으로 예상합니다. RuntimeFileCacheDependency 생성자에 제공하기 전에 HostingEnvironment.MapPath를 사용하여 변환해야합니다.

cacheDetails의 목적은 개체를 귀하의 업데이트에

var rootFileName = HostingEnvironment.MapPath("~/root.sitemap"); 

응답은 하나의 SiteMapBuilderSet 인스턴스에 대한 캐싱 정책을 지정하는 것입니다. (원래) DI 모듈을 더 내려다 본다면 변수가이 클래스의 생성자에 전달된다는 것을 알 수 있습니다.

// Configure the builder sets 
this.For<ISiteMapBuilderSetStrategy>().Use<SiteMapBuilderSetStrategy>() 
    .EnumerableOf<ISiteMapBuilderSet>().Contains(x => 
    { 
     x.Type<SiteMapBuilderSet>() 
      .Ctor<string>("instanceName").Is("default") 
      .Ctor<bool>("securityTrimmingEnabled").Is(securityTrimmingEnabled) 
      .Ctor<bool>("enableLocalization").Is(enableLocalization) 
      .Ctor<bool>("visibilityAffectsDescendants").Is(visibilityAffectsDescendants) 
      .Ctor<bool>("useTitleIfDescriptionNotProvided").Is(useTitleIfDescriptionNotProvided) 
      .Ctor<ISiteMapBuilder>().Is(builder) 
      .Ctor<ICacheDetails>().Is(cacheDetails); // <- caching specified here explicitly. 
    }); 

이 캐시를 만료하는 데 사용되는 것입니다,하지만이 사이트 맵 구축하기 위해 여러 개의 파일을 사용하도록 지정하는 부분에서 완전히 분리 메커니즘입니다 : 방법을 지정하는

// Register the sitemap node providers 
var siteMapNodeProvider = this.For<ISiteMapNodeProvider>().Use<CompositeSiteMapNodeProvider>() 
    .EnumerableOf<ISiteMapNodeProvider>().Contains(x => 
    { 
     x.Type<XmlSiteMapNodeProvider>() 
      .Ctor<bool>("includeRootNode").Is(true) 
      .Ctor<bool>("useNestedDynamicNodeRecursion").Is(false) 
      .Ctor<IXmlSource>().Is(rootXmlSource); 

     // NOTE: Each additional XmlSiteMapNodeProvider instance for the same SiteMap instance must 
     // specify includeRootNode as "false" 
     x.Type<XmlSiteMapNodeProvider>() 
      .Ctor<bool>("includeRootNode").Is(false) 
      .Ctor<bool>("useNestedDynamicNodeRecursion").Is(false) 
      .Ctor<IXmlSource>().Is(childXmlSource1); 
     x.Type<XmlSiteMapNodeProvider>() 
      .Ctor<bool>("includeRootNode").Is(false) 
      .Ctor<bool>("useNestedDynamicNodeRecursion").Is(false) 
      .Ctor<IXmlSource>().Is(childXmlSource2); 

     // Add additional XmlSiteMapNodeProviders here (with includeRootNode as "false")... 

     // You only need this if you intend to use MvcSiteMapNodeAttribute in your application 
     x.Type<ReflectionSiteMapNodeProvider>() 
      .Ctor<IEnumerable<string>>("includeAssemblies").Is(includeAssembliesForScan) 
      .Ctor<IEnumerable<string>>("excludeAssemblies").Is(new string[0]); 
    }); 

// Register the sitemap builders 
var builder = this.For<ISiteMapBuilder>().Use<SiteMapBuilder>() 
    .Ctor<ISiteMapNodeProvider>().Is(siteMapNodeProvider); 

이것은을 단일 SiteMap에 대해 여러 개의 XML 파일을 만들지 만 Multiple SiteMaps in One Application에 설명 된대로 XmlSiteMapNodeProvider의 각 인스턴스를 별도의 SiteMapBuilder 및 별도의 SiteMapBuilderSet에 전달하여 각 XML 파일을 자체 SiteMap 인스턴스로 만들 수도 있습니다. 중요

: 여러 XML 파일을 하나의 사이트 맵 인스턴스에서 작동하려면 this answer의 하단에 같이, 각 사이트 맵의 루트 노드에 대해 동일한 키를 지정해야합니다. 그러나 둘 이상의 XML 파일 (루트 노드 제외)에서 동일한 컨트롤러 조치를 나타내는 노드를 지정할 수는 없습니다.

이보다 더 융통성이 필요한 경우 ISiteMapNodeProvider 또는 IDynamicNodeProvider를 사용하면 훨씬 더 유연하므로 자신의 XmlSiteMapNodeProvider를 구현하거나 XML을 사용하는 아이디어를 포기할 것을 제안합니다.

이제 캐싱으로 돌아갑니다. 동일한 SiteMap 인스턴스에서 여러 XML 파일을 실제로 사용하는 경우 RuntimeCompositeCacheDependency를 사용하여 각 파일을 동일한 캐시에 대한 종속성으로 간주해야하지만 CacheDetails의 단일 인스턴스를 사용해야합니다.

var rootCacheDependency = 
    this.For<ICacheDependency>().Use<RuntimeFileCacheDependency>() 
     .Ctor<string>("fileName").Is(rootAbsoluteFileName); 

var childCacheDependency1 = 
    this.For<ICacheDependency>().Use<RuntimeFileCacheDependency>() 
     .Ctor<string>("fileName").Is(childAbsoluteFileName1); 

var childCacheDependency2 = 
    this.For<ICacheDependency>().Use<RuntimeFileCacheDependency>() 
     .Ctor<string>("fileName").Is(childAbsoluteFileName2); 


var cacheDependency = 
    this.For<ICacheDependency>().Use<RuntimeCompositeCacheDependency>() 
     .Ctor<ICacheDependency[]>().Is(new ICacheDependency[] 
     { 
      (ICacheDependency)rootCacheDependency, 
      (ICacheDependency)childCacheDependency1, 
      (ICacheDependency)childCacheDependency2    
     }); 


var cacheDetails = 
    this.For<ICacheDetails>().Use<CacheDetails>() 
     .Ctor<TimeSpan>("absoluteCacheExpiration").Is(absoluteCacheExpiration) 
     .Ctor<TimeSpan>("slidingCacheExpiration").Is(TimeSpan.MinValue) 
     .Ctor<ICacheDependency>().Is(cacheDependency); 
관련 문제