抽象的依赖注入 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 类型,您可以使用它而不必使用特定类型参数,这会将注册限制为单个类型。
在我的 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 类型,您可以使用它而不必使用特定类型参数,这会将注册限制为单个类型。