ASP.Net 核心 RouteBuilder 和依赖注入
ASP.Net Core RouteBuilder and Dependency Injection
我正在 ASP.NET Core 2.0 中试验路由。我有一个 class 包装了 System.DateTime.UtcNow
功能(用于更简单的单元测试)
public interface IDateTimeWrapper
{
DateTime UtcNow();
}
public sealed class DateTimeWrapper : IDateTimeWrapper
{
public DateTime UtcNow()
{
return DateTime.UtcNow;
}
}
这由具有单一方法 Execute
的 class 使用,该方法将 DateTimeWrapper
的结果写入 HttpResponse
public class WhatIsTheTimeHandler
{
private readonly IDateTimeWrapper _dateTimeWrapper;
public WhatIsTheTimeHandler(
IDateTimeWrapper dateTimeWrapper)
{
this._dateTimeWrapper = dateTimeWrapper;
}
public async Task Execute(Microsoft.AspNetCore.Http.HttpContext httpContext)
{
httpContext.Response.StatusCode = 200;
await httpContext.Response.WriteAsync(this._dateTimeWrapper.UtcNow().ToString());
}
}
在 Startup
中,我希望 /whatisthetime/
的任何请求都由 WhatIsTheTimeHandler
处理(参见 !!! 评论)。
public sealed class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder();
builder.SetBasePath(env.ContentRootPath);
builder.AddJsonFile("appsettings.json", false, true);
// we must lowercase the json file path due to linux file name case sensitivity
builder.AddJsonFile($"appsettings.{env.EnvironmentName.ToLower()}.json", false, true);
builder.AddEnvironmentVariables();
this.Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddRouting();
services.AddScoped<IDateTimeWrapper, DateTimeWrapper>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
var routeBuilder = new Microsoft.AspNetCore.Routing.RouteBuilder(app);
// !!!
// I want to do something like
// routeBuilder.MapGet("whatisthetime", WhatIsTheTimeHandler.Execute);
var routes = routeBuilder.Build();
app.UseRouter(routes);
}
}
我不能做上面我想做的,因为WhatIsTheTimeHandler.Execute
是一个实例方法。 IE。错误:
An object reference is required for the non-static field, method or property 'WhatIsTheTimeHandler.Execute(HttpContext)'
Cannot access non-static method in static context).
如果我做到了 static
那么我将无法使用 _dateTimeWrapper
实例成员。
有什么想法吗?
ASP.NET 核心路由将路由映射到委托。 ASP.NET MVC 核心路由将路由映射到对象(通常称为控制器)。所以后者可能是满足您特殊需求的更好解决方案。
但是,要使您当前的解决方案正常工作,您需要将处理程序添加为服务:
services.AddScoped<WhatIsTheTimeHandler>();
然后从路由中调用它,例如:
routeBuilder.MapGet("whatisthetime", async (context) => {
await context.RequestServices.GetRequiredService<WhatIsTheTimeHandler>().Execute(context);
});
我正在 ASP.NET Core 2.0 中试验路由。我有一个 class 包装了 System.DateTime.UtcNow
功能(用于更简单的单元测试)
public interface IDateTimeWrapper
{
DateTime UtcNow();
}
public sealed class DateTimeWrapper : IDateTimeWrapper
{
public DateTime UtcNow()
{
return DateTime.UtcNow;
}
}
这由具有单一方法 Execute
的 class 使用,该方法将 DateTimeWrapper
的结果写入 HttpResponse
public class WhatIsTheTimeHandler
{
private readonly IDateTimeWrapper _dateTimeWrapper;
public WhatIsTheTimeHandler(
IDateTimeWrapper dateTimeWrapper)
{
this._dateTimeWrapper = dateTimeWrapper;
}
public async Task Execute(Microsoft.AspNetCore.Http.HttpContext httpContext)
{
httpContext.Response.StatusCode = 200;
await httpContext.Response.WriteAsync(this._dateTimeWrapper.UtcNow().ToString());
}
}
在 Startup
中,我希望 /whatisthetime/
的任何请求都由 WhatIsTheTimeHandler
处理(参见 !!! 评论)。
public sealed class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder();
builder.SetBasePath(env.ContentRootPath);
builder.AddJsonFile("appsettings.json", false, true);
// we must lowercase the json file path due to linux file name case sensitivity
builder.AddJsonFile($"appsettings.{env.EnvironmentName.ToLower()}.json", false, true);
builder.AddEnvironmentVariables();
this.Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddRouting();
services.AddScoped<IDateTimeWrapper, DateTimeWrapper>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
var routeBuilder = new Microsoft.AspNetCore.Routing.RouteBuilder(app);
// !!!
// I want to do something like
// routeBuilder.MapGet("whatisthetime", WhatIsTheTimeHandler.Execute);
var routes = routeBuilder.Build();
app.UseRouter(routes);
}
}
我不能做上面我想做的,因为WhatIsTheTimeHandler.Execute
是一个实例方法。 IE。错误:
An object reference is required for the non-static field, method or property 'WhatIsTheTimeHandler.Execute(HttpContext)' Cannot access non-static method in static context).
如果我做到了 static
那么我将无法使用 _dateTimeWrapper
实例成员。
有什么想法吗?
ASP.NET 核心路由将路由映射到委托。 ASP.NET MVC 核心路由将路由映射到对象(通常称为控制器)。所以后者可能是满足您特殊需求的更好解决方案。
但是,要使您当前的解决方案正常工作,您需要将处理程序添加为服务:
services.AddScoped<WhatIsTheTimeHandler>();
然后从路由中调用它,例如:
routeBuilder.MapGet("whatisthetime", async (context) => {
await context.RequestServices.GetRequiredService<WhatIsTheTimeHandler>().Execute(context);
});