Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented job activation per lifetime scope #4

Closed
wants to merge 1 commit into from

Conversation

SevenSpikes
Copy link

Hangfire does not support per lifetime scope containers. This means that all
dependencies will be shared between jobs, which is far from ideal,
especially when you have IDbContext. This is on the road map of Hangfire 2.0.
We need a work around this. This is why we add our own
AutofacJobActivator and a JobFilter to manage a per job lifetime scope.

Hangfire does not support per request containers. This means that all
dependencies will be shared between jobs, which is far from ideal,
especially when you have IDbContext. This is on the road map of Hangfire
2.0.
We need a work around this. This is why we add our own
AutofacJobActivator and a JobFilter to manage a per job lifetime scope.
@odinserj
Copy link
Member

Nice! Have you thought about using the Instance per matching lifetime scope concept and implement the InstancePerBackgroundJob extension method?

{
public static class HangfirePerLifetimeScopeConfigurer
{
public static void Configure(IContainer container)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it is better to leverage the new GlobalConfiguration class and implement the UseScopedAutofacActivator (or so) extension method for IGlobalConfiguration interface? In this case configuration will be straight:

GlobalConfiguration.Configuration
    .UseSqlServerStorage()
    .UseScopedAutofacActivator();

@lorenpaulsen
Copy link

It would be nice to see this pull request merged. I've come to depend on this AutofacPerLifetimeScopeJobActivator. I've been adding it to all my projects that use Hangfire.

@cottsak
Copy link

cottsak commented Jun 12, 2015

@odinserj Is there a reason this is not being merged?

@cottsak
Copy link

cottsak commented Jun 12, 2015

@SevenSpikes Will this PR resolve my No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested exception when my job tries to start?

@feelingweird
Copy link

@cottsak That is a separate issue Matt. That says you are trying to use dependencies registered with .InstancePerHttpRequest. If you change those to instance per lifetime scope you end up here because we need a new lifetime scope per job.
you can fake that webRequest lifetime scope using
_container.BeginLifetimeScope("AutofacWebRequest")

but i am not sure of all the implications of doing this. The best solution is to have a lifetime scope per job and switch all dependencies to not use per http request.

cheers
kle

@odinserj
Copy link
Member

Hi there! I've just released Hangfire 1.5.0-beta1 and Hangfire.Autofac 1.2.0-beta1 (Hangfire.Ninject updated too) with child lifetime scope during the background job processing feature implemented.

Almost every IoC container supports instance re-use and deterministic disposal, and I decided to integrate this feature to Hangfire.Core to make it simpler to use. Hangfire 1.5.0 introduced a new class, JobActivatorScope, that can be implemented in integration libraries (it supports different methods of preserving a scope for other IoC containers), and virtual JobActivator.BeginScope method was added in a non-breaking manner.

Now Hangfire.Autofac resolves components in a child, tagged lifetime scope. You can register components in the following way:

builder.RegisterType<Database>().InstancePerBackgroundJob();

Please read the updated README.md and Release Notes for more details.

Now I'm closing this PR. Thank you @SevenSpikes, this PR helped to accelerate these features and helped other users! And sorry for the silence on this topic :-(

@odinserj odinserj closed this Jul 24, 2015
@lorenpaulsen
Copy link

Awesome! I see that a single container can now be shared by using both InstancePerHttpRequest and InstancePerBackgroundJob

builder.RegisterType<Database>()
    .InstancePerBackgroundJob()
    .InstancePerHttpRequest();

I also understand that HttpContext.Current is not available during the job, but why not support InstancePerHttpRequest, or better yet, InstancePerRequest, by treating it like InstancePerBackgroundJob?

I'm happy this is supported now, but it still means redoing my Autofac registrations when I'm trying to add Hangfire to an existing MVC project.

@odinserj
Copy link
Member

InstancePerHttpRequest method was not defined in Autofac's core assembly. I didn't want to introduce an unnecessary dependency. However, since Autofac 3.4, there is InstancePerRequest method, thanks for the highlighting. I don't like that web request semantic will be used for background jobs, however this simplify the registrations, agreed. I'll think what to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
5 participants