【问题标题】:ASP.Net Core RouteBuilder and Dependency InjectionASP.Net Core RouteBuilder 和依赖注入
【发布时间】:2017-12-06 11:42:53
【问题描述】:

我正在 ASP.NET Core 2.0 中试验路由。我有一个包含System.DateTime.UtcNow 功能的类(用于更简单的单元测试)

public interface IDateTimeWrapper
{
    DateTime UtcNow();
}

public sealed class DateTimeWrapper : IDateTimeWrapper
{
    public DateTime UtcNow()
    {
        return DateTime.UtcNow;
    }
}

这由具有单个方法Execute 的类使用,该方法将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。错误:

非静态字段、方法或属性“WhatIsTheTimeHandler.Execute(HttpContext)”需要对象引用 无法在静态上下文中访问非静态方法)。

如果我将其设为static,那么我将无法使用_dateTimeWrapper 实例成员。

有什么想法吗?

【问题讨论】:

  • 创建一个中间件docs.microsoft.com/en-us/aspnet/core/fundamentals/…,它也允许DI
  • 想知道为什么WhatIsTheTimeHandler 不是Controller
  • @CamiloTerevinto 提出了一个非常有效的观点,现在我已经对这个问题进行了更多思考。
  • @CamiloTerevinto 这只是一个实验。它可能是一个控制器。但我想更深入地了解路由的工作原理。我想了解 UseMvc(...) 做了多少。我还在研究在不使用属性的情况下实现 api 功能。之所以称为“处理程序”,是因为这是MapGet(this IRouteBuilder builder, string template, Func&lt;HttpRequest, HttpResponse, RouteData, Task&gt; handler) 声明的参数的名称:)

标签: c# asp.net-core url-routing


【解决方案1】:

ASP.NET Core 路由将路由映射到委托。 ASP.NET MVC Core 路由将路由映射到对象(通常称为控制器)。所以后者可能是满足您特殊需求的更好解决方案。

但是,要使您当前的解决方案正常工作,您需要将处理程序添加为服务:

services.AddScoped<WhatIsTheTimeHandler>();

然后从路由中调用它,例如:

routeBuilder.MapGet("whatisthetime", async (context) => {
    await context.RequestServices.GetRequiredService<WhatIsTheTimeHandler>().Execute(context);
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    相关资源
    最近更新 更多