[英]Autofac same injected instance not received when manually resolving an InstancePerRequest type
I'm trying to have a transaction ID which will be used for logging throughout the request. 我正在尝试使用一个事务ID,该ID将用于记录整个请求。 Trasaction ID is a property in AuditContext, which in turn will be a singleton per request.
事务ID是AuditContext中的属性,而每个请求又是一个单例。 I've the below code in Global.asax.cs
我在Global.asax.cs中有以下代码
builder.RegisterType<AuditContext>().As<IAuditContext>().InstancePerRequest();
....
GlobalContainer = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(GlobalContainer);
Transaction ID is set in a base api class. 交易ID是在基本api类中设置的。
public BaseApiController(IAuditContext auditContext, IDispatcher dispatcher = null)
{
auditContext.TransactionID = Guid.NewGuid().ToString();
}
AuditContext object with the correct transaction ID is injected, in below constructor injection usage. 在构造函数注入用法下方,注入具有正确事务ID的AuditContext对象。
public class SapEventLogger : ISapEventLogger
{
private IAuditContext auditContext;
public SapEventLogger(IAuditContext auditContext)
{
this.auditContext = auditContext; //this auditContext object has correct transaction ID
}
}
In case of any exception I want to retrieve the transaction ID and log it. 如有任何例外,我想检索交易ID并记录下来。 But when I try to manually resolve, I get a new AuditContext object in which the transaction ID is null.
但是,当我尝试手动解决时,我得到一个新的AuditContext对象,其中事务ID为null。
public class ServiceExceptionHandler : ExceptionHandler
{
public override void Handle(ExceptionHandlerContext context)
{
using (var scope = GlobalContainer.BeginLifetimeScope(Autofac.Core.Lifetime.MatchingScopeLifetimeTags.RequestLifetimeScopeTag))
{
var auditContext = scope.Resolve<FDP.Services.Common.IAuditContext>();
transactionID = auditContext.TransactionID; //Transaction ID is null here
}
}
}
Not sure why a new object is created when resolving AuditContext manually. 不确定手动解决AuditContext时为什么要创建新对象。 Am I missing something?
我想念什么吗?
With the BeginLifetimeScope
call you're manually creating a second request lifetime rather than using the existing request lifetime. 通过
BeginLifetimeScope
调用,您将手动创建第二个请求生存期,而不是使用现有的请求生存期。 Two request lifetimes equals two instances. 两个请求生存期等于两个实例。
The solution to this is outlined in the Autofac docs in more detail but the short version is to get the request lifetime from the request message in the handler context: Autofac文档中更详细地概述了此问题的解决方案,但简短的版本是从处理程序上下文中的请求消息中获取请求生存期:
// Get the request lifetime scope so you can resolve services.
var requestScope = context.Request.GetDependencyScope();
// Resolve the service you want to use.
var auditContext = requestScope.GetService(typeof(IAuditContext)) as IAuditContext;
// Do the rest of the work in the filter.
auditContext.DoWork();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.