C# Autofac Web Api多租户未获取HTTPContext.Current
我很难让Autofac.Extras.Multitenance包在两种接口实现之间进行选择 我正试图根据租户Id连接到单独的数据库,但我从Autofac的示例中获取的C# Autofac Web Api多租户未获取HTTPContext.Current,c#,autofac,C#,Autofac,我很难让Autofac.Extras.Multitenance包在两种接口实现之间进行选择 我正试图根据租户Id连接到单独的数据库,但我从Autofac的示例中获取的ItenantIdentificationsStrategy没有获得HttpContext.Current设置,因此我无法从HTTP调用中获得任何信息来做出决定。我有两个这样的配置 var mtc = new MultitenantContainer(tenantIdStrategy, builder.Build()); mtc.
ItenantIdentificationsStrategy
没有获得HttpContext.Current
设置,因此我无法从HTTP调用中获得任何信息来做出决定。我有两个这样的配置
var mtc = new MultitenantContainer(tenantIdStrategy, builder.Build());
mtc.ConfigureTenant(Guid.Parse("00000000-0000-0000-0000-000000000001"), b => b.RegisterInstance<DatabaseConnection>(connectionOne).As<IDatabaseConnection>().SingleInstance());
mtc.ConfigureTenant(Guid.Parse("00000000-0000-0000-0000-000000000002"), b => b.RegisterInstance<DatabaseConnection>(connectionTwo).As<IDatabaseConnection>().SingleInstance());
var resolver = new AutofacWebApiDependencyResolver(mtc);
config.DependencyResolver = resolver;
appBuilder.UseWebApi(config);
我添加了一个简单的控制器来测试它,它应该在ASP.NET管道中
public IHttpActionResult Get(IMongoDBAdapter adapter, string memberId= null) {
return Ok()
}
这是Autofac网站上的示例。但是HttpContext.Current始终为null,并且未设置租户Id,然后它会抱怨我的控制器没有获得数据库连接
编辑
我想我的问题可能是这个项目没有托管在IIS中。它是一个自托管的windows服务,甚至在控制器HttpContext中也是如此。Current为null。似乎这种想法在自托管服务中不可能实现?你是对的-
您可以将其放在自托管请求管道中的第一位,并以类似的方式设置上下文变量
也就是说,您的DelegatingHandler
必须
- 阅读您感兴趣的各种基于请求的参数
- 使用
CallContext.LogicalSetData
CallContext.LogicalGetData
读取该值
看看ASP.NET核心也不支持HttpContext.Current
,因此如何
这实际上可能是一些需要更正的棘手代码,因此我将在这里放置一个非常非常粗糙的样本,但是不要复制/粘贴它,并假设它将是100%完美的。我不是在做广泛的测试,我只是想给你一个想法
以下是处理程序的外观:
public class TenantIdentityHandler : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var id = request.Headers.GetValues("X-Tenant-ID").FirstOrDefault();
CallContext.LogicalSetData("TenantIdentification" + AppDomain.CurrentDomain.Id, new ObjectHandle(id));
return await base.SendAsync(request, cancellationToken);
}
}
public class CallContextStrategy : ITenantIdentificationStrategy
{
public bool TryIdentifyTenant(out object tenantId)
{
var handle = CallContext.LogicalGetData("TenantIdentification" + AppDomain.CurrentDomain.Id) as ObjectHandle;
var tenantId = handle?.Unwrap() as string;
return tenantId != null;
}
}
再说一次,我还没有试过,所以你可能需要调整一下,但希望它能让你开始。你是对的-
您可以将其放在自托管请求管道中的第一位,并以类似的方式设置上下文变量
也就是说,您的DelegatingHandler
必须
- 阅读您感兴趣的各种基于请求的参数
- 使用
CallContext.LogicalSetData
CallContext.LogicalGetData
读取该值
看看ASP.NET核心也不支持HttpContext.Current
,因此如何
这实际上可能是一些需要更正的棘手代码,因此我将在这里放置一个非常非常粗糙的样本,但是不要复制/粘贴它,并假设它将是100%完美的。我不是在做广泛的测试,我只是想给你一个想法
以下是处理程序的外观:
public class TenantIdentityHandler : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var id = request.Headers.GetValues("X-Tenant-ID").FirstOrDefault();
CallContext.LogicalSetData("TenantIdentification" + AppDomain.CurrentDomain.Id, new ObjectHandle(id));
return await base.SendAsync(request, cancellationToken);
}
}
public class CallContextStrategy : ITenantIdentificationStrategy
{
public bool TryIdentifyTenant(out object tenantId)
{
var handle = CallContext.LogicalGetData("TenantIdentification" + AppDomain.CurrentDomain.Id) as ObjectHandle;
var tenantId = handle?.Unwrap() as string;
return tenantId != null;
}
}
同样,我还没有尝试过这个方法,因此您可能需要调整它,但希望它能让您开始。您何时/何地解决失败的对象?(请更新问题的主体。)如果它不在请求中(例如,ASP.NET管道尚未设置HttpContext.Current),那么就没有什么可以做的了。那个doc示例只是一个示例,它周围的免责声明多得让人难以接受。您可能需要根据个人需要进行一些修改,以处理自己的特殊情况。@TravisIllig感谢您的回复和对文档的更新。然而,我没有想到要提到的一件大事是,它是在Windows服务中自托管的。不是通过IIS。似乎HttpContext.Current将始终为空,因此。。。糟糕……您何时/何地解决出现故障的对象?(请更新问题的主体。)如果它不在请求中(例如,ASP.NET管道尚未设置HttpContext.Current),那么就没有什么可以做的了。那个doc示例只是一个示例,它周围的免责声明多得让人难以接受。您可能需要根据个人需要进行一些修改,以处理自己的特殊情况。@TravisIllig感谢您的回复和对文档的更新。然而,我没有想到要提到的一件大事是,它是在Windows服务中自托管的。不是通过IIS。似乎HttpContext.Current将始终为空,因此。。。糟糕……太棒了。看来我至少可以走上正轨了。太棒了。看来我至少可以走上正轨了。