1

Our Application makes heavy use of Autofac Per-Request-Dependencies. This works quite well and fits our needs.

Now we have an requirement to listen on AzureWebJobs.

Since im quite new to Azure WebJobs i followed this tutorial (Here the git-sources)

Now the tricky part.
Even though i followed all the instructions and created an AutofacActivator Autofac seems not to be able to resolve my Per-Request registered dependencies

DependencyResolutionException: No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.

Question

Is there any way i can under above requirements make Autofac work together with Azure-WebJobs?

To be clear, my Autofaclistener resolves just one service. That cannot be registered as SingleInstance since it gets resolved on other services too. Also i can not change my Per-Request-Stuff to InstancePerLifetimeScope as suggested here

I hope my issue and my question are self-explaining. If not , please let me know

lokusking
  • 7,396
  • 13
  • 38
  • 57

1 Answers1

1

Azure webjobs are not web applications, they are more like console applications. They don't have a request/response semantic. They don't have http session contexts, nor request scopes. So you should not use per-request registrations, they are meaningless inside a webjob. If you insist on using per-request dependencies you will have to simulate a request context for your webjob, and this is a risky approach. You can easily introduce memory leaks and undesired side effects. Be aware that you are forcing an unnatural way to deal with dependency scopes in webjobs. See this page about implementing custom per-request scopes for more info.

A simple way to deal with this is to get a dependency scope only for the lifetime of your event handler methods. You explicitly define your scope inside a using block (as the scopes will not be automatically created in a webjob in the way that they are automatically created in a MVC or ASP.NET application). You have to register your types as .InstancePerLifetimeScope(). The instances will be disposed when you exit the using block.

So in your event handlers you define a lifetime scope for each execution of the handler method:

private void OnEvent(...)
{
    using (var scope = container.BeginLifetimeScope())
    {
        ...
        var myService = scope.Resolve<IMyService>();
        ...
    }
}

This example uses explicit Resolve calls to get the instances of your service. There are better ways to do it, like using autofac factory methods.

A more advanced solution would be to implement your own IJobActivator. This way you can use constructor injection in your Functions class, and the lifetime scope of those instances will be the lifetime of your handler method execution. This answer contains code examples. You still will need to register your types as .InstancePerLifetimeScope() though.

Diana
  • 2,186
  • 1
  • 20
  • 31
  • Thanks for your reply. Unfortunately your answer aint helping me. As i already mentioned, i CANNOT change the `InstancePerRequest`. As it seems what im trying to do is either impossible or really tricky – lokusking May 07 '18 at 07:25
  • Looks like you will have to use custom per-request scopes. I hope the link above helps you. It's tricky but not impossible. Good luck! – Diana May 07 '18 at 19:50