I\'m working on creating a UrlHelper for a background worker to create callback urls, which means it\'s not part of a normal request where I could just ask for it through DI
Browsing the sources it seems there is no less hacky solution.
In the UseMvc() method the IRouter object being built is passed to the RouterMiddleware, which stores it in a private field and exposes it only to the requests. So reflection would be your only other option, which is obviously out of the running.
However, if you need to generate only static paths using IUrlHelper.Content() you won't need the router as the default implementation won't use it. In this case you can create the helper like this:
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var urlHelper = new UrlHelper(actionContext);
With ASP.NET Core 2.2 releasing today, they've added a LinkGenerator class that sounds like it will solve this problem (the tests look promising). I'm eager to try it, but as I'm not actively working on the project where I needed this at the moment, it will have to wait a bit. But I'm optimistic enough to mark this as a new answer.