-
Notifications
You must be signed in to change notification settings - Fork 6
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
Remove AutofacWebApiDependencyScope from HttpRequestMessage after we leave the handler #17
Remove AutofacWebApiDependencyScope from HttpRequestMessage after we leave the handler #17
Conversation
… leave the handler
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks!
Hi, I ran into an issue caused by this change:
If the base.SendAsync returns a task (from awaiting), then the dependency scope is removed. When the await is resumed, then the dependency scope is no longer present and you get a "An error occurred when trying to create a controller of type 'XXX'". Need to add an await there to prevent this:
|
@russellfoster , you're right, this is a rookie mistake on my part. |
Let me see if I can get a quick fix out for this. |
It turns out you can't have an async/await method marked by I'll see what I can do using something like |
The fix will be released in 6.2.1 which is going out right now. |
Hello, Sorry for bringing this up again, but the changes in this PR are a breaking change for anyone who is using Autofac in a combination with a global exception handler/logger in WebApi. If someone has the following setup: config.Services.Add(typeof(IExceptionLogger), new MyExceptionLogger());
config.Services.Replace(typeof(IExceptionHandler), new MyExceptionHandler()) and inside those Services, one is using the Request DependencyScope to resolve dependencies: public class MyExceptionLogger : ExceptionLogger
{
public override void Log(ExceptionLoggerContext context)
{
var dependencyScope = context.Request.GetDependencyScope(); // this will return an EmptyResolver since the AutofacWebApiDependencyScope has been removed already
var otherLogger = dependencyScope.GetService(typeof(IOtherLogger)) as IOtherLogger; // this will be null
var lifetimeScope = dependencyScope.GetRequestLifetimeScope(); // this will be null
var logger = lifetimeScope.Resolve<ILogger>(); // throws
}
} This happens, because the Exception Logger/Handler is called at a later point from the top-most DelegatingHandler ( I'm not sure what the right approach would be here. Some ideas:
Thanks! |
We can't revert to the old way because we need to be able to garbage collect, so it'd possibly need to be removed later. We'd be happy to take a PR to fix it, but I won't lie, this isn't something I'll personally be actively working on. |
Given the discussion in #15, it doesn't look like there is a simple solution. But since we're in an Owin scenario, there is a nice workaround: public class MyExceptionLogger : ExceptionLogger
{
public override void Log(ExceptionLoggerContext context)
{
var lifetimeScope = context.Request.GetOwinContext().GetAutofacLifetimeScope(); // get the lifetimeScope from the OwinContext rather than getting it from the DependencyScope
var logger = lifetimeScope.Resolve<ILogger>();
}
} |
In the same vein as autofac/Autofac.Owin#26, we remove created
AutofacWebApiDependencyScope
fromHttpRequestMessage
's properties when we leave the handler to allow for earlier garbage collection. Should work better in pair with #16, which also removesAutofacWebApiDependencyScope
from the finalizer queue.