简体   繁体   English

ASP.Net Core RouteBuilder和依赖注入

[英]ASP.Net Core RouteBuilder and Dependency Injection

I'm experimenting with routing in ASP.NET Core 2.0. 我正在尝试在ASP.NET Core 2.0中进行路由。 I have a class that wraps the System.DateTime.UtcNow functionality (for simpler Unit Testing) 我有一个包装System.DateTime.UtcNow功能的类(用于更简单的单元测试)

public interface IDateTimeWrapper
{
    DateTime UtcNow();
}

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

This is used by a class that has a single method Execute which writes the result of the DateTimeWrapper to the HttpResponse 该类由具有单个方法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());
    }
}

In Startup I want any requests going to /whatisthetime/ to be handled by the WhatIsTheTimeHandler (see the !!! comment). Startup我希望通过WhatIsTheTimeHandler处理去往/whatisthetime/所有请求(请参阅!!!注释)。

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);
    }
}

I can't do what I want above because WhatIsTheTimeHandler.Execute is an instance method. 我不能做上面想要的事情,因为WhatIsTheTimeHandler.Execute是一个实例方法。 Ie the error: 即错误:

An object reference is required for the non-static field, method or property 'WhatIsTheTimeHandler.Execute(HttpContext)' Cannot access non-static method in static context). 非静态字段,方法或属性'WhatIsTheTimeHandler.Execute(HttpContext)'不能使用对象引用。在静态上下文中无法访问非静态方法)。

If I make it static then I won't be able to use the _dateTimeWrapper instance member. 如果我将其设置为static则将无法使用_dateTimeWrapper实例成员。

Any ideas? 有任何想法吗?

ASP.NET Core routing maps routes to delegates. ASP.NET Core路由将路由映射到委托。 ASP.NET MVC Core routing maps routes to objects (commonly referred to as controllers). ASP.NET MVC核心路由将路由映射到对象(通常称为控制器)。 So the latter is probably the better solution to your particularly needs. 因此,后者可能是满足您特定需求的更好解决方案。

However, to make your current solution work you would need to add the handler as a service: 但是,要使当前解决方案正常工作,您需要将处理程序添加为服务:

services.AddScoped<WhatIsTheTimeHandler>();

then invoke this from within the route, eg: 然后从路由中调用它,例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM