我正在将网站从ASP MVC重写/移动到ASP MVC Core。该应用程序具有一个动态菜单,该菜单取决于已登录的用户。为了构建菜单,每个控制器都从一个自定义BaseController
派生而来,后者在ViewBag
菜单项中进行设置,稍后,在Layout中,这些项被检索并作为参数传递给PartialView
public BaseController:Controller
{
public BaseController()
{
...
ViewBag.Menu=Utils.GetMenu();
...
}
}
我不想使用与编写旧代码的家伙相同的逻辑。因此,我想使用ViewComponent
来渲染菜单。但是我对这种方法有疑问。在调用方法中,我需要查询菜单项。现在,我从服务提供商(HttpContext.RequestServices
)获得了一个DbContext实例,并使用它来查询所需的任何数据。但是从Layout
异步调用了Invoke函数,我知道将DbContext发送到async
方法不是很好:
<cache expires-after="@TimeSpan.FromHours(2)" enabled="true">
@await Component.InvokeAsync(typeof(Admin.ViewComponents.MeniuViewComponent))
</cache>
这是一个好方法吗?在Invoke方法(或任何其他async
方法或操作)中使用DbContext(在Startup中注册为Scoped)并使用它是否安全?而且如果不是一个好主意,我该如何处理需要async
方法从db获取数据的这种情况?
答案 0 :(得分:0)
在我的项目中,我有一个案例要从asp.net内核中的HostedService中获取DbContext。
我将IServiceProvider注入了构造函数中并构建了自己的作用域,以获取注册的DbContext:
private readonly IServiceProvider _serviceProvider;
public BaseController(IServiceProvider provider){
_serviceProvider = provider;
}
private void DoSth(){
using var scope = _serviceProvider.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<YOUR_DbContext_CLASS>();
... //do something great stuff here with the database
}
答案 1 :(得分:0)
我认为您可以直接在ViewComponent中依赖注入DbContext
function high(scorel)
local record, leaders = 0, {}
for name, score in pairs(scorel) do
if score > record then
record = score
leaders = {name}
elseif score == record then
table.insert (leaders, name)
end
end
return leaders, record
end
local leaders, record = high(score)
if #leaders > 0 then
print ('Highest score (' .. tostring(record) .. ') belongs to ' .. concat (leaders, ', '))
end
有关更多详细信息,请参阅doc。