1

I'm using PerWebRequestLifestyle with Castle.Windsor, and getting:

HttpContext.Current is null. PerWebRequestLifestyle can only be used in ASP.Net

It's a long stack trace, but it does definitely start in a controller. The stack trace for the exception doesn't show that, it shows the command handler which is invoked from the controller asynchronously.

Why might this be?

Exception stack trace:

   at Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule.GetScope()
   at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.GetScope(CreationContext context)
   at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy)
   at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden)
   at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired)
   at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
   at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context)
   at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context)
   at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context)
   at Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden)
   at Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, Boolean trackedExternally)
   at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.<>c__DisplayClass4_0.<Resolve>b__0(Action`1 afterCreated)
   at Castle.MicroKernel.Lifestyle.Scoped.CallContextLifetimeScope.GetCachedInstance(ComponentModel model, ScopedInstanceActivationCallback createInstance)
   at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy)
   at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden)
   at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired)
   at Castle.MicroKernel.Resolvers.DefaultDependencyResolver.Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
   at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context)
   at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context)
   at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context)
   at Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden)
   at Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, Boolean trackedExternally)
   at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.<>c__DisplayClass4_0.<Resolve>b__0(Action`1 afterCreated)
   at Castle.MicroKernel.Lifestyle.Scoped.CallContextLifetimeScope.GetCachedInstance(ComponentModel model, ScopedInstanceActivationCallback createInstance)
   at Castle.MicroKernel.Lifestyle.ScopedLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy)
   at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden)
   at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired)
   at Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy)
   at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy)
   at Castle.Windsor.WindsorContainer.Resolve[T]()
   at RedactedCustomer.MyFrameworkTech.TriggerableFactory.Create[TTriggerType]() in C:\BuildAgent\work\6c87fea77042db3f\backend\RedactedCustomer.MyFrameworkTech\TriggerableFactory.cs:line 17
   at Redacted.MyFramework.Workflow.TriggerExecutor.<LockAndExecuteAsync>d__13`2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Redacted.MyFramework.Workflow.TriggerExecutor.<ExecuteSingleAsync>d__12`2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Redacted.MyFramework.Workflow.TriggerExecutor.<ExecuteSingleAsync>d__12`2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Redacted.MyFramework.Workflow.WorkflowExecutionContext.<ExecuteCapturedActionsAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Redacted.MyFramework.Workflow.MultiAsyncWorkflowExecutionContext.<ExecuteCapturedActionsAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Redacted.MyFramework.Workflow.TriggerExecutor.<ExecuteSingleAsync>d__12`2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at RedactedCustomer.Core.BusinessLogic.CommandHandlers.MyCommandHandler.<ExecuteAsync>d__12.MoveNext() in C:\BuildAgent\work\6c87fea77042db3f\backend\core\RedactedCustomer.Core.BusinessLogic\CommandHandlers\MyCommandHandler.cs:line 282
Kieren Johnstone
  • 41,277
  • 16
  • 94
  • 144
  • Can you show us the code? – Roman Marusyk Jan 08 '19 at 11:21
  • Which code specifically? I'm guessing `await _commandExecutor.ExecuteAsync(command);` isn't super helpful! – Kieren Johnstone Jan 08 '19 at 11:29
  • How we can help you without any code? What about other Lifestyles? How do you configure DI? Did you try to find out why HttpContext.Current is null? – Roman Marusyk Jan 08 '19 at 14:20
  • See [this](https://stackoverflow.com/questions/29913941/castle-windsor-lifestyle-issue) – Roman Marusyk Jan 08 '19 at 14:34
  • I am experiencing the same issue also. It is super weird as it occurs from AutoMappers expression extensions of the AfterMap processing... for some reason the dependency management figures out it needs the HttpContext.Current (which is unavailable due to ConfigureAwait(false) in action) and fails. My IOC config is huge, so it might be due to the fact that some dependency somewhere needs something from HttpContext. E.g. I was injecting a PerWebRequest service in the AfterMap class processor. – Vedran Mandić Jan 20 '21 at 18:52

1 Answers1

0

This might be an issue due to async / await code in combination with ConfigrueAwait(false).

You are executing IOC/DI code after a ConfigureAwait(false) call which effectively discards the current HttpContext instance. More precisely you might be invoking DI somewhere to construct a class which is (or has deps) configured to be PerWebRequest in lifestyle but the current request is gone due to aforementioned ConfigureAwait(false). I had that issue with AutoMapper's implementation of IMappingAction which was injecting a PerWebRequest dep to its constructor.

Vedran Mandić
  • 1,084
  • 11
  • 21