8

I'm implementing email sending module and need to build URLs. My intention was to use IUrlHelper, but I really struggle to build this object due to the enormous amount of dependencies it needs to provide.

At the current moment I'm at this step:

ActionContext actionCtx = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
_urlHelper = new UrlHelper(actionCtx);

but constructed that way urlHelper still fails with an exception when trying to build URL.

Exception is:

Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) at System.Collections.Generic.List`1.get_Item(Int32 index) at Microsoft.AspNetCore.Mvc.Routing.UrlHelper.get_Router()

So probably now it's required to create and set IRouter instance, but as I could see it's again required to set tons of deps

So how this should be done correctly?

Bernard Vander Beken
  • 4,848
  • 5
  • 54
  • 76
silent_coder
  • 6,222
  • 14
  • 47
  • 91
  • 1
    See also https://stackoverflow.com/questions/46096068/asp-net-core-2-0-creating-urlhelper-without-request – Bernard Vander Beken Feb 01 '18 at 12:15
  • I'm assuming you are running a task in the background (not as part of a request)? If so, the post linked by @BernardVanderBeken was the most relevant I found when trying to achieve something similar. – SpruceMoose Feb 01 '18 at 12:30
  • 1
    yep, it's even standalone project - just a scheduled work. so not a web app at all. – silent_coder Feb 01 '18 at 12:31

1 Answers1

2

As you've discerned, it's going to be next to impossible to achieve this in a completely disconnected library. More to the point, you need routes to even make it worthwhile, which are going to be cleanly confined in a separate web application, your library would have to have a hard dependency on to access. In case it's not obvious, that would be a very poor design choice to make.

I think you need to step back and re-evaluate. If your goal is to simply send an email through an external process, then whatever is scheduling a task there (presumably your web application) should pass it the information it needs for that email, including any URLs. That shifts the responsibility of creating those URLs away from your email library (which really shouldn't have this responsibility anyways - do one thing and do it well) back to a source that likely already has the necessary ability.

If this cannot be done for some reason. I'd say your next best bet is to set up one or more endpoints on the web application you're trying to generate URLs for and have those return the URLs you need and/or any other additional information the email library needs to send an email. This still externalizes the email sending functionality, but gives your library a clean way to get access to information from the web application when it needs it.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444