Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Commit

Permalink
Extensibility for executors
Browse files Browse the repository at this point in the history
We have all of these executors but they aren't really
documented/supported for extensibility today. This change introduces a
pattern for action result executors so we can make them extensible.
  • Loading branch information
rynowak committed Sep 21, 2017
1 parent b47fa1c commit 410e738
Show file tree
Hide file tree
Showing 55 changed files with 227 additions and 92 deletions.
Expand Up @@ -243,17 +243,17 @@ internal static void AddMvcCoreServices(IServiceCollection services)
services.TryAddSingleton<IHttpResponseStreamWriterFactory, MemoryPoolHttpResponseStreamWriterFactory>();
services.TryAddSingleton(ArrayPool<byte>.Shared);
services.TryAddSingleton(ArrayPool<char>.Shared);
services.TryAddSingleton<ObjectResultExecutor>();
services.TryAddSingleton<PhysicalFileResultExecutor>();
services.TryAddSingleton<VirtualFileResultExecutor>();
services.TryAddSingleton<FileStreamResultExecutor>();
services.TryAddSingleton<FileContentResultExecutor>();
services.TryAddSingleton<RedirectResultExecutor>();
services.TryAddSingleton<LocalRedirectResultExecutor>();
services.TryAddSingleton<RedirectToActionResultExecutor>();
services.TryAddSingleton<RedirectToRouteResultExecutor>();
services.TryAddSingleton<RedirectToPageResultExecutor>();
services.TryAddSingleton<ContentResultExecutor>();
services.TryAddSingleton<IActionResultExecutor<ObjectResult>, ObjectResultExecutor>();
services.TryAddSingleton<IActionResultExecutor<PhysicalFileResult>, PhysicalFileResultExecutor>();
services.TryAddSingleton<IActionResultExecutor<VirtualFileResult>, VirtualFileResultExecutor>();
services.TryAddSingleton<IActionResultExecutor<FileStreamResult>, FileStreamResultExecutor>();
services.TryAddSingleton<IActionResultExecutor<FileContentResult>, FileContentResultExecutor>();
services.TryAddSingleton<IActionResultExecutor<RedirectResult>, RedirectResultExecutor>();
services.TryAddSingleton<IActionResultExecutor<LocalRedirectResult>, LocalRedirectResultExecutor>();
services.TryAddSingleton<IActionResultExecutor<RedirectToActionResult>, RedirectToActionResultExecutor>();
services.TryAddSingleton<IActionResultExecutor<RedirectToRouteResult>, RedirectToRouteResultExecutor>();
services.TryAddSingleton<IActionResultExecutor<RedirectToPageResult>, RedirectToPageResultExecutor>();
services.TryAddSingleton<IActionResultExecutor<ContentResult>, ContentResultExecutor>();

//
// Route Handlers
Expand Down
1 change: 1 addition & 0 deletions src/Microsoft.AspNetCore.Mvc.Core/FileContentResult.cs
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Net.Http.Headers;
Expand Down
1 change: 1 addition & 0 deletions src/Microsoft.AspNetCore.Mvc.Core/FileStreamResult.cs
Expand Up @@ -4,6 +4,7 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Net.Http.Headers;
Expand Down
Expand Up @@ -21,6 +21,7 @@ public ContentResultExecutor(ILogger<ContentResultExecutor> logger, IHttpRespons
_httpResponseStreamWriterFactory = httpResponseStreamWriterFactory;
}

/// <inheritdoc />
public virtual async Task ExecuteAsync(ActionContext context, ContentResult result)
{
if (context == null)
Expand Down
Expand Up @@ -7,15 +7,16 @@
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Mvc.Internal
namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
public class FileContentResultExecutor : FileResultExecutorBase
public class FileContentResultExecutor : FileResultExecutorBase, IActionResultExecutor<FileContentResult>
{
public FileContentResultExecutor(ILoggerFactory loggerFactory)
: base(CreateLogger<FileContentResultExecutor>(loggerFactory))
{
}

/// <inheritdoc />
public virtual Task ExecuteAsync(ActionContext context, FileContentResult result)
{
if (context == null)
Expand Down
Expand Up @@ -10,10 +10,11 @@
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Http.Headers;
using Microsoft.AspNetCore.Internal;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Mvc.Internal
namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
public class FileResultExecutorBase
{
Expand Down
Expand Up @@ -6,15 +6,16 @@
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Mvc.Internal
namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
public class FileStreamResultExecutor : FileResultExecutorBase
public class FileStreamResultExecutor : FileResultExecutorBase, IActionResultExecutor<FileStreamResult>
{
public FileStreamResultExecutor(ILoggerFactory loggerFactory)
: base(CreateLogger<FileStreamResultExecutor>(loggerFactory))
{
}

/// <inheritdoc />
public virtual Task ExecuteAsync(ActionContext context, FileStreamResult result)
{
if (context == null)
Expand Down
Expand Up @@ -2,15 +2,17 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Mvc.Internal
namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
public class LocalRedirectResultExecutor
public class LocalRedirectResultExecutor : IActionResultExecutor<LocalRedirectResult>
{
private readonly ILogger _logger;
private readonly IUrlHelperFactory _urlHelperFactory;
Expand All @@ -31,7 +33,8 @@ public LocalRedirectResultExecutor(ILoggerFactory loggerFactory, IUrlHelperFacto
_urlHelperFactory = urlHelperFactory;
}

public virtual void Execute(ActionContext context, LocalRedirectResult result)
/// <inheritdoc />
public virtual Task ExecuteAsync(ActionContext context, LocalRedirectResult result)
{
if (context == null)
{
Expand Down Expand Up @@ -64,6 +67,8 @@ public virtual void Execute(ActionContext context, LocalRedirectResult result)
{
context.HttpContext.Response.Redirect(destinationUrl, result.Permanent);
}

return Task.CompletedTask;
}
}
}
Expand Up @@ -11,17 +11,18 @@
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.Formatters.Internal;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Mvc.Internal
namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
/// <summary>
/// Executes an <see cref="ObjectResult"/> to write to the response.
/// </summary>
public class ObjectResultExecutor
public class ObjectResultExecutor : IActionResultExecutor<ObjectResult>
{
/// <summary>
/// Creates a new <see cref="ObjectResultExecutor"/>.
Expand Down
Expand Up @@ -10,15 +10,16 @@
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Mvc.Internal
namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
public class PhysicalFileResultExecutor : FileResultExecutorBase
public class PhysicalFileResultExecutor : FileResultExecutorBase, IActionResultExecutor<PhysicalFileResult>
{
public PhysicalFileResultExecutor(ILoggerFactory loggerFactory)
: base(CreateLogger<PhysicalFileResultExecutor>(loggerFactory))
{
}

/// <inheritdoc />
public virtual Task ExecuteAsync(ActionContext context, PhysicalFileResult result)
{
if (context == null)
Expand Down
Expand Up @@ -2,14 +2,16 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Mvc.Internal
namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
public class RedirectResultExecutor
public class RedirectResultExecutor : IActionResultExecutor<RedirectResult>
{
private readonly ILogger _logger;
private readonly IUrlHelperFactory _urlHelperFactory;
Expand All @@ -30,7 +32,8 @@ public RedirectResultExecutor(ILoggerFactory loggerFactory, IUrlHelperFactory ur
_urlHelperFactory = urlHelperFactory;
}

public virtual void Execute(ActionContext context, RedirectResult result)
/// <inheritdoc />
public virtual Task ExecuteAsync(ActionContext context, RedirectResult result)
{
if (context == null)
{
Expand Down Expand Up @@ -63,6 +66,8 @@ public virtual void Execute(ActionContext context, RedirectResult result)
{
context.HttpContext.Response.Redirect(destinationUrl, result.Permanent);
}

return Task.CompletedTask;
}
}
}
Expand Up @@ -2,15 +2,17 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Mvc.Internal
namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
public class RedirectToActionResultExecutor
public class RedirectToActionResultExecutor : IActionResultExecutor<RedirectToActionResult>
{
private readonly ILogger _logger;
private readonly IUrlHelperFactory _urlHelperFactory;
Expand All @@ -31,7 +33,8 @@ public RedirectToActionResultExecutor(ILoggerFactory loggerFactory, IUrlHelperFa
_urlHelperFactory = urlHelperFactory;
}

public virtual void Execute(ActionContext context, RedirectToActionResult result)
/// <inheritdoc />
public virtual Task ExecuteAsync(ActionContext context, RedirectToActionResult result)
{
if (context == null)
{
Expand Down Expand Up @@ -69,6 +72,8 @@ public virtual void Execute(ActionContext context, RedirectToActionResult result
{
context.HttpContext.Response.Redirect(destinationUrl, result.Permanent);
}

return Task.CompletedTask;
}
}
}
Expand Up @@ -2,15 +2,17 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Mvc.Internal
namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
public class RedirectToPageResultExecutor
public class RedirectToPageResultExecutor : IActionResultExecutor<RedirectToPageResult>
{
private readonly ILogger _logger;
private readonly IUrlHelperFactory _urlHelperFactory;
Expand All @@ -31,7 +33,8 @@ public RedirectToPageResultExecutor(ILoggerFactory loggerFactory, IUrlHelperFact
_urlHelperFactory = urlHelperFactory;
}

public virtual void Execute(ActionContext context, RedirectToPageResult result)
/// <inheritdoc />
public virtual Task ExecuteAsync(ActionContext context, RedirectToPageResult result)
{
if (context == null)
{
Expand Down Expand Up @@ -69,6 +72,8 @@ public virtual void Execute(ActionContext context, RedirectToPageResult result)
{
context.HttpContext.Response.Redirect(destinationUrl, result.Permanent);
}

return Task.CompletedTask;
}
}
}
Expand Up @@ -2,15 +2,17 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Mvc.Internal
namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
public class RedirectToRouteResultExecutor
public class RedirectToRouteResultExecutor : IActionResultExecutor<RedirectToRouteResult>
{
private readonly ILogger _logger;
private readonly IUrlHelperFactory _urlHelperFactory;
Expand All @@ -31,7 +33,8 @@ public RedirectToRouteResultExecutor(ILoggerFactory loggerFactory, IUrlHelperFac
_urlHelperFactory = urlHelperFactory;
}

public void Execute(ActionContext context, RedirectToRouteResult result)
/// <inheritdoc />
public virtual Task ExecuteAsync(ActionContext context, RedirectToRouteResult result)
{
var urlHelper = result.UrlHelper ?? _urlHelperFactory.GetUrlHelper(context);

Expand All @@ -58,6 +61,8 @@ public void Execute(ActionContext context, RedirectToRouteResult result)
{
context.HttpContext.Response.Redirect(destinationUrl, result.Permanent);
}

return Task.CompletedTask;
}
}
}
Expand Up @@ -12,9 +12,9 @@
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Mvc.Internal
namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
public class VirtualFileResultExecutor : FileResultExecutorBase
public class VirtualFileResultExecutor : FileResultExecutorBase , IActionResultExecutor<VirtualFileResult>
{
private readonly IHostingEnvironment _hostingEnvironment;

Expand All @@ -29,6 +29,7 @@ public VirtualFileResultExecutor(ILoggerFactory loggerFactory, IHostingEnvironme
_hostingEnvironment = hostingEnvironment;
}

/// <inheritdoc />
public virtual Task ExecuteAsync(ActionContext context, VirtualFileResult result)
{
if (context == null)
Expand Down
8 changes: 5 additions & 3 deletions src/Microsoft.AspNetCore.Mvc.Core/LocalRedirectResult.cs
Expand Up @@ -2,7 +2,9 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Core;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.Extensions.DependencyInjection;

Expand Down Expand Up @@ -89,15 +91,15 @@ public string Url
public IUrlHelper UrlHelper { get; set; }

/// <inheritdoc />
public override void ExecuteResult(ActionContext context)
public override Task ExecuteResultAsync(ActionContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

var executor = context.HttpContext.RequestServices.GetRequiredService<LocalRedirectResultExecutor>();
executor.Execute(context, this);
var executor = context.HttpContext.RequestServices.GetRequiredService<IActionResultExecutor<LocalRedirectResult>>();
return executor.ExecuteAsync(context, this);
}
}
}

0 comments on commit 410e738

Please sign in to comment.