ASP.NET Core抽象类中的依赖注入

Sal*_*eri 3 c# asp.net-core razor-pages

在我的ASP.NET Core 2项目中,我创建了继承RazorPage类的新类,以便在视图中添加一些其他属性。

public abstract class WebViewPage<TModel> : Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>
{
    public string Version
    {
        get
        {
            return "1.00.100";
        }
    }
    public User CurrentUser
    {
        get
        {
            //challenge is here:
            //return _services.GetRequiredService<IUserService>().GetCurrentUser();
        }
    }
}

public abstract class WebViewPage : WebViewPage<dynamic>
{

}
Run Code Online (Sandbox Code Playgroud)

并将_ViewImport.cshtml文件更改为此:

@inherits MyProject.WebViewPage<TModel>
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Run Code Online (Sandbox Code Playgroud)

在挑战代码标记为注释之前,该项目可以正常工作。但是,如何将依赖项注入抽象类呢?或如何解析抽象类中的服务?

这是我的StartUp.cs文件:

@inherits MyProject.WebViewPage<TModel>
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Run Code Online (Sandbox Code Playgroud)

pok*_*oke 5

如果您需要访问剃须刀页面内的服务提供商,则可以HttpContext通过Context属性访问,例如:

var userService = Context.RequestServices.GetRequiredService<IUserService>();
Run Code Online (Sandbox Code Playgroud)

可能更好的替代方法是让构造函数将IUserService视为依赖。因此,您的类型的实现必须传递该依赖关系,本质上要求它们自己具有构造函数依赖关系(这是一个很好的显式设计)。


至于依赖项注册部分,请注意,您通常无法注册抽象类,因为它们无法实例化。

但是总的来说,为了注册一个泛型类型,您必须使用更冗长的重载,AddScoped该重载需要实际Type参数:

services.AddScoped(typeof(IRazorPage<>), typeof(WebViewPage<>)); 
Run Code Online (Sandbox Code Playgroud)

制作一个通用的方法调用需要一个真正的类型,泛型类型参数,所以你必须指定类型参数的具体类型T里面IRazorPage<T>WebViewPage<T>。由于您明确不想在此处使用具体类型,而是想告诉依赖项注入容器支持任何类型,因此您不能在此处使用此语法。

由于typeof操作员可以确定实际的通用类型,因此您可以使用它而不必使用特定的类型参数,该参数会将注册限制为单个类型。