Calling services scoped per request from reccuring background tasks using Autofac and Quartz in MVC 5
Calling services scoped per request from reccuring background tasks using Autofac and Quartz in MVC 5
Just as a heads up, my scenario is different for example from This link because it's a recurring job instead of a simple fire-and-forget.
I am using Quartz, Autofac (with Autofac extensions for Quartz), and MVC 5.
The problem is that single instance services are resolved just fine from IJob classes, but I don't have any way to resolve anything per-request scoped. For example lets say that happens every 5 minutes.
The services and repositories cannot and should not be rescoped.
So what is someone supposed to do with long running and recurring background tasks?
A code sample would require a whole VS project to convey the structure properly. Just think of an event that autofires every 15 minutes independently (using Quartz to fire it) in an MVC project. The problem is that it's life scope is outside a normal http request scope that is used for almost everything DB related
– Mihalis Bagos
Apr 21 '15 at 8:35
So the problem is that you register per http request and you need your registration outside of a HTTP request (I haven't read the title -_-). I avoid registering my component per http request and prefer to register them perLifetimeScope. Do you need to register them per request ?
– Cyril Durand
Apr 21 '15 at 9:25
Yes DB operations (as represented by a work item) are per-request as a standard. I don't have access to change it nor I would as this is best practice both for consistency and performance
– Mihalis Bagos
Apr 21 '15 at 12:07
1 Answer
1
I don't recommend using the .InstancePerRequest()
method because it requires to be inside a Http request scenario to resolve components. If you have a quite big application, you may want to resolve some component outside of a Http request scenario. In such a case it is often simpler to register them using the .InstancePerLifetimeScope()
method.
.InstancePerRequest()
.InstancePerLifetimeScope()
By the way, if you can't change the lifetime mode, you can simulate a Http request scenario.
static void Main(string args)
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Foo>().AsSelf().InstancePerRequest();
IContainer container = builder.Build();
using (ILifetimeScope scope = container.BeginLifetimeScope(
MatchingScopeLifetimeTags.RequestLifetimeScopeTag))
scope.Resolve<Foo>();
This is similar to what the Autofac.Integration.Mvc package does.
I don't know Quartz. I look at the source code of the Autofac integration for Quartz and it seems that you can specify the lifetimeScopeTag used by using this code :
builder.RegisterModule(new QuartzAutofacFactoryModule(
MatchingScopeLifetimeTags.RequestLifetimeScopeTag));
I had the same problem and your answer fixed it. The only minor adjustment I had to make was to add ToString to your last module registration:
builder.RegisterModule(new QuartzAutofacFactoryModule(MatchingScopeLifetimeTags.RequestLifetimeScopeTag.ToString()));
– b3hdad
5 hours ago
builder.RegisterModule(new QuartzAutofacFactoryModule(MatchingScopeLifetimeTags.RequestLifetimeScopeTag.ToString()));
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Not sure to understand what you want. Could you add a code sample to better define the problem ?
– Cyril Durand
Apr 19 '15 at 22:23