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

Design extensibility for executors #6822

Closed
wants to merge 1 commit into from
Closed

Design extensibility for executors #6822

wants to merge 1 commit into from

Conversation

rynowak
Copy link
Member

@rynowak rynowak commented Sep 14, 2017

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.

@rynowak
Copy link
Member Author

rynowak commented Sep 14, 2017

/cc @pranavkm

@rynowak rynowak requested a review from pranavkm September 14, 2017 06:15
@rynowak
Copy link
Member Author

rynowak commented Sep 14, 2017

I did one as an example. If we like the pattern I will go ahead and port the rest.

{
public interface IActionResultExecutor<TResult> where TResult : IActionResult
{
Task ExecuteAsync(ActionContext context, TResult result);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of the executors we have already follow this pattern, I'm just adding an interface.

I have big plans for these..... (trails off in a sinister way)

@khellang
Copy link
Contributor

I like it! 😍 I'm already using ObjectResultExecutor for conneg with WebSockets, so this might make it a bit less hacky to use.

The formatting pipeline infrastructure is still a bit too tightly coupled to MVC, IMO. Have you guys thought about decoupling it so it could be used in other MW as well? (I'm guessing aspnet/Diagnostics#346 (comment) is related to this?)

@rynowak
Copy link
Member Author

rynowak commented Sep 14, 2017

Have you guys thought about decoupling it so it could be used in other MW as well? (I'm guessing aspnet/Diagnostics#346 (comment) is related to this?)

Yes, but it's not planned for right now

The formatting pipeline infrastructure is still a bit too tightly coupled to MVC, IMO

conneg is one of a few things in MVC that has an opinion at all. There's no technical need for it to be coupled, but we'd have to re-examine those decisions.


namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
public interface IActionResultExecutor<TResult> where TResult : IActionResult
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any value in making this contravariant? Maybe for scenarios like IActionResultExecutor<NotFoundResult> = new StatusCodeResultExecutor();

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I don't think it can hurt.

@rynowak rynowak force-pushed the rynowak/executor branch 3 times, most recently from 602dd8a to 2dcc293 Compare September 20, 2017 22:35
@rynowak
Copy link
Member Author

rynowak commented Sep 21, 2017

@pranavkm ping

@rynowak rynowak force-pushed the rynowak/executor branch 4 times, most recently from 410e738 to 82c44cb Compare September 21, 2017 18:24
Copy link
Contributor

@pranavkm pranavkm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

public override void ExecuteResult(ActionContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

var executor = context.HttpContext.RequestServices.GetRequiredService<RedirectResultExecutor>();
executor.Execute(context, this);
var services = context.HttpContext.RequestServices;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have these call the executor and block on it? In the default case, it should be fine since the executor is entirely synchronous.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to put a .Result in the code. You could implement these interfaces and do some arbitrary stuff

@@ -145,5 +145,25 @@
"TypeId": "public class Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelMetadata : Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata",
"MemberId": "public override Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.IModelBindingMessageProvider get_ModelBindingMessageProvider()",
"Kind": "Removal"
},
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI @javiercn

{
await executor.ExecuteAsync(context, view, this);
}
var executor = context.HttpContext.RequestServices.GetRequiredService<IActionResultExecutor<ViewResult>>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

@@ -176,6 +178,29 @@ public virtual Task ExecuteAsync(ActionContext actionContext, IView view, ViewRe
viewResult.StatusCode);
}

/// <inheritdoc />
public async Task ExecuteAsync(ActionContext context, ViewResult result)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we remove the now unused overload since the type was in .Internal?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

using Microsoft.Extensions.Logging;

namespace Microsoft.AspNetCore.Mvc.Internal
namespace Microsoft.AspNetCore.Mvc.Infrastructure
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the namespace change to facilitate subclassing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

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.
@rynowak
Copy link
Member Author

rynowak commented Sep 22, 2017

3871260

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants