我正在使用MvcSiteMapProvider 4.6.3,MVC 4.使用DI配置站点地图。
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);
更新
当我更改站点地图xml文件时,缓存不会更新,直到5分钟缓存过期。 我正在使用多个站点地图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 :(得分:0)
我发现您发布的代码没有问题。但是,当XML发生更改时,RuntimeFileCacheDependency将重新加载。
RuntimeFileCacheDependency期望fileName参数是绝对路径。因此,在将其提供给RuntimeFileCacheDependency构造函数之前,必须使用HostingEnvironment.MapPath对其进行转换。
var rootFileName = HostingEnvironment.MapPath("~/root.sitemap");
对您的更新的回复
cacheDetails对象的目的是为单个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.
});
这是用于使缓存过期的内容,但它与指定使用多个文件构建SiteMap的部分完全分开:
// 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文件的方法,但也可以通过将每个XmlSiteMapNodeProvider实例传递到单独的SiteMapBuilder和单独的SiteMapBuilderSet来将每个XML文件放入其自己的SiteMap实例中,如{{ 3}}
重要信息:要使多个XML文件在单个SiteMap实例上运行,必须为每个SiteMap的根节点指定相同的密钥,如Multiple SiteMaps in One Application底部所示。但是,您无法在多个XML文件(根节点除外)中指定表示相同控制器操作的节点。
如果您需要更多的灵活性,我建议您实现自己的XmlSiteMapNodeProvider或放弃使用XML的想法,因为使用ISiteMapNodeProvider或IDynamicNodeProvider要灵活得多。
现在,回到缓存。如果您确实在同一个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);