Как добавить службы IActionResultExecutor, такие как IActionResultExecutor <NotFoundResult>, в приложение маршрутизации на основе конечных точек? - PullRequest
0 голосов
/ 17 июня 2020

Как добавить службы IActionResultExecutor, которые доступны для действий контроллера, например IActionResultExecutor<NotFoundResult>, в приложение маршрутизации на основе конечных точек?

Я пишу ASP. NET Core 3.1, это не обычное приложение на основе действий контроллера, а настраиваемое через app.UseEndpoints: https://github.com/zwcloud/NancyFxViaAspNetCore/blob/646f9d820369d8fc78cf0c1f2cb18307e1851081/Nancy/NancyModule.cs#L176

И это вызвало исключение в моем реализация внутри endpoints.Map:

System.InvalidOperationException: 'Нет службы для типа' Microsoft.AspNetCore. Mvc .Infrastructure.IActionResultExecutor`1 [Microsoft.AspNetCore. Mvc .NotFoundResult] 'был зарегистрирован.'

public static Task WriteActionResult<TResult>(HttpContext context, TResult result) where TResult : IActionResult
{
    var executor = context.RequestServices.GetRequiredService<IActionResultExecutor<TResult>>();
    //**exception thrown here** System.InvalidOperationException
    if (executor == null)
    {
        throw new InvalidOperationException($"No action result executor for {typeof(TResult).FullName} registered.");
    }
    var routeData = context.GetRouteData() ?? new RouteData();
    var actionContext = new ActionContext(context, routeData, new ActionDescriptor());
    return executor.ExecuteAsync(actionContext, result);
}

public dynamic GetResult()//main logic is written here
{
    //other logic omitted
    return new NotFoundResult();
}

//this function is called in Startup.Configure()
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseEndpoints((endpoints) =>
    {
        endpoints.Map(route, async context =>
        {
            dynamic result = GetResult(context);
            await WriteActionResult(context, result);
        });
    });
}

Итак, я хочу добавить IActionResultExecutor<StatusCodeResult>, IActionResultExecutor<NotFoundResult> и многие другие исполнители результатов действий, которые доступны в действиях контроллера, в службы в Startup.ConfigureServices.

Я уже добавил MvcCore и Mvc в Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    //...
    services.AddMvcCore();
    services.AddMvc()
    //...
}

Но я не знаю, какой класс и сборка содержат этот тип. И никакая документация не указывает на это.

Неудачные попытки, которые я сделал:

  • Не удалось найти в исходном коде ASP. NET Core, но не получил ничего, кроме определения NotFoundResult , et c.

  • попробовал

    services.TryAddSingleton(typeof(IActionResultExecutor<StatusCodeResult>));
    

    Но это вызвало исключение, когда HostBuilder.Build() в Main:

    System.ArgumentException: 'Cannot instantiate implementation type
    'Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor`1[Microsoft.AspNetCore.Mvc.StatusCodeResult]'
    for service type
    'Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor`1[Microsoft.AspNetCore.Mvc.StatusCodeResult]'.'
    

    exception

  • пробовал

    services.Add(new ServiceDescriptor(typeof(IActionResultExecutor<NotFoundResult>),
        typeof(IActionResultExecutor<NotFoundResult>)));
    

    Но это вызвало исключение, когда HostBuilder.Build() в Main: exception

1 Ответ

0 голосов
/ 19 июня 2020

Я узнал.

public static Task WriteActionResult(HttpContext context, NotFoundResult result)
{
   context.Response.StatusCode = result.StatusCode;
   return context.Response.Body.FlushAsync();
}

Для StatusCodeResult например NotFoundResult, мы не должны запрашивать IActionResultExecutor, а писать напрямую в Response.

Изучено WebApiContrib.Core s реализация .

...