Hangfire: inject PerformContext into task

Created on 1 Feb 2017  路  7Comments  路  Source: HangfireIO/Hangfire

It would be convenient to be able to inject PerformContext into an enqueued or scheduled task. I haven't figured out if there is a way to do this and if I'm just missing it. I'm using AutoFac, so I think I'd have to somehow get PerformContext into the AutoFac container. Any thoughts on how this might be possible?

Thanks!

Most helpful comment

A good way of doing this is to have a IPerformContext base interface. So instead of

public async Task<Bar> FooAsync(PerformContext context, IJobCancellationToken jobCancellationToken)
{ 
    // ....
}

we could write

public async Task<Bar> FooAsync(IPerformContext context, IJobCancellationToken jobCancellationToken)
{ 
    // ....
}

which would allow for easy unit testing. The existing syntax of creating jobs would be unaffected.

All 7 comments

PerformContext is a special argument type, which is handled even before JobActivator and IoC containers. Usually you just pass it a null in your job definition, and it is automatically substituted with a correct instance later.

Yeah, that totally makes sense and is how I'm doing it now, it would just be slightly more convenient to have that dependency injected with the rest of the dependencies for that job. If there isn't a way to do that, I'll stick with what I've got.

I personally doubt that making PerformContext a service is a good idea. PerformContext is only valid inside the method it was passed to, and making it accessible anywhere else is error-prone.

It would be nice if PerformContext can be injected into a class constructor, so you don't need to pass null when scheduling a job. But it is not always possible, because the job class itself may be a singleton, so you cannot inject a scoped service there.

It could make sense if registered in a InstancePerBackgroundJob() scope. But yes, it would become very error prone

If people had the ability to somehow registerPerformContext however they wanted, then at least they would be aware of the risks/pitfalls of singletons and DI scoping

A good way of doing this is to have a IPerformContext base interface. So instead of

public async Task<Bar> FooAsync(PerformContext context, IJobCancellationToken jobCancellationToken)
{ 
    // ....
}

we could write

public async Task<Bar> FooAsync(IPerformContext context, IJobCancellationToken jobCancellationToken)
{ 
    // ....
}

which would allow for easy unit testing. The existing syntax of creating jobs would be unaffected.

While coding tests we might want to avoid the hassle of creating a PerformContext and just pass an interface, that would make testing easier. Would it be possible to have an interface such as IPerformContext?

This is a old isssue, but i would still like a way to unit test my tasks that use the PerformContext.
Any updates on this?

Was this page helpful?
0 / 5 - 0 ratings