首先,我想说我是Asp.net Core的新手,并且还具有依赖项注入(DI)的概念。我正在阅读很多试图理解的文章,所以我需要耐心。
我正在尝试Razor页面(不是MVC),我的目标是将“ _layout.cshtml”呈现为局部视图,在该视图中所有页面上都可以使用Entity Framework获取信息。
我将DBContext添加到Startup.cs文件中,如下所示:
services.AddDbContext <AppDBContext> (options =>
options.UseSqlServer (Configuration.GetConnectionString ("AppDBContext")
在MenuPartial.cshtml.cs的“ PageModel”中
public class MenuPartialModel: PageModel
{
private readonly AppDBContext _db;
public MenuPartialModel (AppDBContext db)
{
_db = db;
}
}
在_layout.cshtm文件中,我尝试了几种使用新模型实例调用PartialAsync的方法:
如果像下面这样设置新的实例模型,我将使用没有参数的构造函数,因此不会注入DbContext
@await Html.PartialAsync ("MenuPartial", new MenuPartialModel ())
我还考虑过使用:
@await Html.PartialAsync ("MenuPartial", new MenuPartialModel (new AppDBContext ())
我认为这不是正确的方法。因为如果DbContext是自动注入的,为什么我应该通过再次传递连接参数来执行新实例?
实现我的目标的最佳方法是什么?我考虑过使用ViewComponents,但是,起初我想了解是否可以实例化模型并使用注入DBContext的构造函数。
答案 0 :(得分:4)
我想了解是否可以实例化模型并使用注入DBContext的构造函数。
在ASP.NET Core MVC中,普通的旧CLR类(POCO)不参与ASP.NET Core依赖注入。 MenuPartialModel
是POCO(与大多数MVC模型一样)。结果,该框架不会自动将依赖项注入其中。
一些内置的ASP.NET Core MVC类被连接到依赖项注入中。其中包括(但不限于):
MVC中的规范方法是将依赖项(也称为服务)注入其中之一,然后将任何数据手动传递给POCO模型。
什么是[好的]方法来实现我的目标?
我将使用View Component而不是部分视图。视图组件就像具有模型,视图和控制器的局部视图。
控制器是InvokeAsync
,它没有暴露给HTTP,但是它仍然是控制器in the traditional sense,因为它负责将模型绑定到视图。
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using MyApplication.Data;
public class MenuModel
{
public string MyProperty { get; set; }
public string MyOtherProperty { get; set; }
}
public class MenuViewComponent : ViewComponent
{
private readonly ApplicationDbContext dbContext;
public MenuViewComponent(ApplicationDbContext dbContext)
{
this.dbContext = dbContext;
}
public async Task<IViewComponentResult> InvokeAsync()
{
var data = await dbContext...
var model = new MenuModel
{
MyProperty = data.FirstValue,
MyOtherProperty = data.OtherValue,
};
return View(model);
}
}
您还将需要在这些位置之一中使用Razor文件作为视图。
/Pages/Shared/Components/Menu/Default.cshtml
/Views/Shared/Components/Menu/Default.cshtml
该Default.cshtml
文件将包含以下内容:
@model MenuModel
<p>@Model.MyProperty</p>
<p>@Model.MyOtherProperty</p>
@await Component.InvokeAsync("Menu")
开箱即用,View组件不公开给HTTP。要通过AJAX访问它们,我们需要add an ASP.NET Core MVC Controller to reach them。
[Route("component/[action]")]
public class ViewComponentController : Controller
{
// ~/component/menu
public IActionResult Menu() => ViewComponent("Menu");
}