抽象的依赖注入 class,ASP.NET 核心

Dependency Injection in abstract class, ASP.NET Core

在我的 ASP.NET Core 2 项目中,我创建了新的 class 来继承 RazorPage class 添加一些额外的 属性 的浏览量。

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>
{

}

_ViewImport.cshtml 文件更改为:

@inherits MyProject.WebViewPage<TModel>
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

在挑战代码被标记为评论之前,该项目运行良好。但是,如何将依赖项注入抽象 class?或如何抽象解析服务 class?

这是我的 StartUp.cs 文件:

public void ConfigureServices(IServiceCollection services)
{
        services.AddMemoryCache();
        services.AddMvc();
        services.AddTransient<IUserService, UserService>();
        //services.AddScoped<IRazorPage<?>, WebViewPage<?>(); // ?: challenge!
}

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

var userService = Context.RequestServices.GetRequiredService<IUserService>();

一个可能更好的选择是拥有一个将 IUserService 作为依赖项的构造函数。因此,您的类型的实现必须传递该依赖项,本质上要求它们具有自己的构造函数依赖项(这是一个很好的显式设计)。


至于那个依赖注册部分,注意一般不能注册abstract 类 因为它们不能被实例化

但一般来说,为了注册泛型类型,您必须使用更详细的 AddScoped 重载,它需要实际的 Type 个参数:

services.AddScoped(typeof(IRazorPage<>), typeof(WebViewPage<>)); 

进行泛型方法调用需要一个真实类型作为泛型类型参数,因此您必须在 IRazorPage<T>WebViewPage<T> 中为类型参数 T 指定一个具体类型.由于您明确不想在那里使用具体类型,而是想告诉依赖注入容器支持 any 类型,因此您不能在那里使用此语法。

由于 typeof 运算符可以确定实际的 generic 类型,您可以使用它而不必使用特定类型参数,这会将注册限制为单个类型。