0

Having trouble scheduling/enqueuing an MVC action with Hangfire (1.6.5) (Custom IServices works just fine..)

No service for type 'Controllers.MyController' has been registered.

public class MyController : Controller
{
    public IActionResult RenderViewToString() 
    {
        return View();
    }

    public IActionResult Test() 
    {
        //Attempt 1
        Hangfire.BackgroundJob.Enqueue<MyController>(c => c.RenderViewToString());

        //Attempt 2
        Hangfire.BackgroundJob.Enqueue(() => c.RenderViewToString());

        return new EmptyResult();
    }
}
Tseng
  • 61,549
  • 15
  • 193
  • 205
  • Please note, that it's not called MVC6 anymore. The correct name is "ASP.NET Core MVC" with version 1.0 – Tseng Oct 17 '16 at 14:34
  • 1
    There's a much bigger issue here, and that is why you would want to use a controller for this sort of thing? For a start a background task will not return anything. Secondly, you shouldn't be relying on controller/request context to be available to you inside Hangfire tasks either. – DavidG Oct 17 '16 at 14:47
  • @DavidG I know this is not optimal. I am using MVC to render a view to PDF. I need the ControllerContext for that.. Not aware of any other way. –  Oct 17 '16 at 14:57
  • What are you using to generate the PDF? You cannot have access to the controller context, there is none for background tasks. – DavidG Oct 17 '16 at 14:58
  • @DavidG http://stackoverflow.com/questions/483091/render-a-view-as-a-string –  Oct 17 '16 at 15:04
  • Er, that's a string not a PDF - very different things! – DavidG Oct 17 '16 at 15:05
  • Yes, but that is what my question is all about. I am using Prince to render the string to a pdf. Works great. That is not the issue. –  Oct 17 '16 at 15:06
  • I'm not sure there is a nice way to do this. You may be better off converting the view to a string and the passing that to the background task to render as PDF. – DavidG Oct 17 '16 at 15:26

1 Answers1

2

By default, controllers aren't being registered with the dependency injection system in ASP.NET Core. You need to explicitly call AddControllersAsService to register them, as explained in this GitHub issue:

Hi,

Maybe I'm wrong but as I tested deeply (and checked Mvc source code), Controllers are not resolved from IServiceProvider, but only constructor arguments of them are resolved from IServiceProvider.

Is that by design? I'm very suprised. Because, I'm using a different DI framework which supports property injection. And I can not use property injection since Controller instances are not requested from IServiceProvider.

Have you added AddControllersAsServices in your Startup (https://github.com/aspnet/Mvc/blob/ab76f743f4ee537939b69bdb9f79bfca35398545/test/WebSites/ControllersFromServicesWebSite/Startup.cs#L37)

See also this answer to a related question for an example and more details.

poke
  • 369,085
  • 72
  • 557
  • 602
Tseng
  • 61,549
  • 15
  • 193
  • 205
  • Thank you! That takes me one step further. Now the controllers dependencies does not seem to get activated.. A alot of "Object reference not set to an instance of an object" Any ideas? –  Oct 17 '16 at 14:56
  • My bad. HttpContext does not get activated. For obvious reasons.. Have to work around that. –  Oct 17 '16 at 15:47