Q:

ASP.NET Core ControllerContext vs ActionContext in UrlHelper

I am trying to implement pagination in my Asp.net core 2 API. To create pagination links, I am using UrlHelper. The constructor for UrlHelper requires the context in which the action runs.
The examples I've seen have been using below configuration in startup and then injecting IUrlHelper into the controller where it is needed.
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
services.AddScoped<IUrlHelper>(x => {
    var actionContext = x.GetRequiredService<IActionContextAccessor>().ActionContext;
    var factory = x.GetRequiredService<IUrlHelperFactory>();
    return factory.GetUrlHelper(actionContext);
});

But controllers also have ControllerContext which derives from ActionContext (https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllercontext?view=aspnetcore-2.1). 
I am able to do the following:
 public Object GetAll() //ignore object return, for test purposes
    {
        var urlHelper = new UrlHelper(ControllerContext);
        var nextLink = urlHelper.Link("GetPosts", new { page = 1, pageSize = 3 });
        //return _context.Posts;
        return new
        {
            NextPageLink = nextLink,
            Results = _context.Posts,
            test = ControllerContext.RouteData.Values
        };
    }

The code above is able to create the links correctly. I don't have a firm grasp on the nuances of the framework so I am wondering if above is a correct way to initialize UrlHelper. Will this lead to problems? If you can point me in the direction of some documentation around this or explain the reason behind if the approach is good/bad, that would be very helpful.

A:

What you have can work.
It does however tightly couple the controller to an implementation concern.
If you have need for the helper you can follow a similar format to what was configured at startup by injecting the IUrlHelperFactory into the controller and getting the helper using the controller's ControllerContext, which as you have already discovered, derives from ActionContext
public class MyController : Controller {
    private readonly IUrlHelperFactory factory;
    //...other dependencies

    public MyController(IUrlHelperFactory factory) {
        this.factory = factory;
        //...other dependencies
    }

    public IActionResult GetAll() {
        var urlHelper = factory.GetUrlHelper(ControllerContext);
        var nextLink = urlHelper.Link("GetPosts", new { page = 1, pageSize = 3 });
        return Ok(new {
            NextPageLink = nextLink,
            Results = _context.Posts,
            test = ControllerContext.RouteData.Values
        });
    }

    //...other actions
}

