I am rewriting/ moving a website from ASP MVC to ASP MVC Core. This application has a dynamic menu which depends on the logged in user. In order to build the menu, each controller derives from a custom BaseController
who sets in ViewBag
menu items, an later, in Layout, those items are retrieved and passed as arguments to a PartialView
.
public BaseController:Controller
{
public BaseController()
{
...
ViewBag.Menu=Utils.GetMenu();
...
}
}
I don't want to use the same logic as the lads who wrote the old code. So I thought to use a ViewComponent
to render the menu. But I have a problem with this approach. In Invoke method I need to query for the menu items. Right now I get a DbContext instance from the service provider (HttpContext.RequestServices
), and I use it to query whatever data I need. But the Invoke function is called asynchronously from Layout
and I know that it is not very good to send DbContext to async
methods:
<cache expires-after="@TimeSpan.FromHours(2)" enabled="true">
@await Component.InvokeAsync(typeof(Admin.ViewComponents.MeniuViewComponent))
</cache>
Is this a good approach? Is it safe to get a DbContext (registered as Scoped in Startup) in Invoke method (or any other async
method or action) and use it? And if it is not a good idea, how should I deal with this kind of situations where I need data from db in async
methods?
I had the case in my project to get the DbContext inside a HostedService from asp.net core.
I injected the IServiceProvider inside the constructor and build my own scope, to get the registered DbContext: