在使用Spark模板引擎时,防止Nancy中的视图缓存

本文关键字:Nancy 防止 缓存 视图 Spark 引擎 | 更新日期: 2023-09-27 17:58:41

我使用的是带有Spark模板的自托管Nancy。我已经专门禁用了缓存(尽管在DEBUG中,默认情况下应该禁用)。

    protected override void ApplicationStartup(Nancy.TinyIoc.TinyIoCContainer container, IPipelines pipelines)
    {
        base.ApplicationStartup(container, pipelines);
        ...
        StaticConfiguration.Caching.EnableRuntimeViewDiscovery = true;
        StaticConfiguration.Caching.EnableRuntimeViewUpdates = true;
    }

然而,在应用程序运行时对模板进行更改似乎不起作用,因为模板更改没有被拾取。

禁用视图缓存还需要什么吗?

在使用Spark模板引擎时,防止Nancy中的视图缓存

由于您的应用程序是自托管的,我猜您要么已经重写了视图位置约定以在程序集中查找作为嵌入资源的视图,要么已经将Visual Studio项目配置为在编译时将视图复制到输出目录中。在这两种情况下,应用程序都不是在Visial Studio项目中的视图文件上运行,而是在它们的副本上运行。在这种情况下,缓存不是问题所在。

好的,通过在引导程序中添加一个自定义ViewCache:来实现这一点

public class MyBootstrapper : DefaultNancyBootstrapper
{
#if DEBUG
    protected override IRootPathProvider RootPathProvider
    {
        get
        {
            // this sets the root folder to the VS project directory
            // so that any template updates in VS will be picked up
            return new MyPathProvider();
        }
    }
    protected override NancyInternalConfiguration InternalConfiguration
    {
        get
        {
            return NancyInternalConfiguration.WithOverrides(
                x =>
                    { x.ViewCache = typeof(MyViewCache); });
        }
    }
#endif

新的ViewCache只是在每次请求时重新加载模板:

public class MyViewCache : IViewCache
{
...
    public TCompiledView GetOrAdd<TCompiledView>(
        ViewLocationResult viewLocationResult, Func<ViewLocationResult, TCompiledView> valueFactory)
    {
        //if (viewLocationResult.IsStale())
        //    {
                object old;
                this.cache.TryRemove(viewLocationResult, out old);
        //    }
        return (TCompiledView)this.cache.GetOrAdd(viewLocationResult, x => valueFactory(x));
    }
}

不知怎的,viewLocationResult.IsStale()总是返回false

默认情况下,这是FileSystemViewLocationResult的一个实例,它只比较视图的最后更新时间,但时间戳this.lastUpdated在从DefaultViewCache调用IsStale()之前已经更新,因此模板从未从缓存中删除

public override bool IsStale()
{
    return this.lastUpdated != this.fileSystem.GetLastModified(this.fileName);
}