在web开发中,很多局部部分,友情链接、推荐阅读、热点标签等等基本上几个小时甚至几天内都不会更新,完全不用每次从数据库读取,频繁消耗资源,这是时候就可以用到组件ViewComponent和内存缓存MemoryCache一起配合。
首先NuGet安装Microsoft.Extensions.Caching.Memory
Startup.cs页面里注册MemoryCache
public void ConfigureServices(IServiceCollection services)
{
//...这里注册其他组件我省略了
services.AddMemoryCache();
}
然后创建ViewComponents文件夹,在创建xxxViewComponent.cs文件。
我们以TagViewComponent.cs为例
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Shuanghei.Com.Interface;
using Shuanghei.Com.Models;
using System;
using Microsoft.Extensions.Caching.Memory;
using System.Collections.Generic;
namespace Shuanghei.Com.Web.ViewComponents
{
//必须继承ViewComponent类
public class TagViewComponent : ViewComponent
{
readonly IMemoryCache memoryCache;
readonly ITagRepository tagRepository;
public TagViewComponent(ITagRepository tagRepository,IMemoryCache memoryCache)
{
this.tagRepository = tagRepository;
this.memoryCache = memoryCache;
}
//这里必须是异步的InvokeAsync方法,返回对应的view,使用起来和控制器大致相同
public async Task<IViewComponentResult> InvokeAsync()
{
var key = "TagViewComponent";
// 如果有缓存,则直接取值
if (memoryCache.TryGetValue<IEnumerable<Tag>>(key,
out IEnumerable<Tag> obj))
{
return View(obj);
}
// 如果没有缓存,则添加缓存,设置缓存时间
else
{
var result = await tagRepository.FindAll();
memoryCache.Set<IEnumerable<Tag>>(key, result,
DateTimeOffset.Now.AddMinutes(80));
return View(result);
}
}
}
}
好了cs代码算写好了,到view页面,看看如何使用。
在Shared文件下新建Components文件夹(必须是这个名字),然后新建Tag文件夹,这个Tag必须是 前面TagViewComponent类,ViewComponent前面的那个Tag,比如是FriendLinkViewComponent那么,这个文件夹必须是FriendLink文件夹。然后再文件下面创建Default.cshtml也一定要是Default这个名字,上一步的return view()会自动寻找这个寻找这个view,所以命名一定要符合规范。以下是官方的寻找顺序。
/Views/{Controller Name}/Components/{View Component Name}/{View Name}
/Views/Shared/Components/{View Component Name}/{View Name}
/Pages/Shared/Components/{View Component Name}/{View Name}
然后这个view里,就跟正常的视图写的内容一样。
@model IEnumerable<Shuanghei.Com.Models.Tag>
<div class="card">
<div class="card-header">
<h6>热点标签</h6>
</div>
<div class="card-body" id="biaoqian">
@foreach (var item in Model)
{
<a href="/tag/@item.Name">@item.Name</a>
}
</div>
</div>
最后,再需要使用这个 ViewComponent的地方,比如首页Index.cshtml中,插入以下代码即可实现缓存,name后面跟着的就是TagViewComponent类中的Tag。
<div class="col-md-3">
@await Component.InvokeAsync(name: "Tag")
</div>
另外InvokeAsync()方法也可以传参数,实际运用中,比如“推荐阅读”,数据源都是相同的,但是在不同页面展示的view是不同的,所以可以根据参数返回不同的view,如下:
public async Task<IViewComponentResult> InvokeAsync(Boolean isDone)
{
var key = "RecommendViewComponent";
var myView = "default";
if (!isDone)
{
myView = "detail";
}
return View(myView,result);
}
页面引用
@await Component.InvokeAsync(name: "Recommend", new { isDone = true })