Autofac、用户和日志记录
Autofac, Users and Logging
我在我的项目中使用 Autofac,大部分情况下它工作正常。不久前,我需要访问当前用户,并被告知最好的方法是创建一个包装器 class,如下所示:
public class PrincipalProvider : IPrincipalProvider
{
public IPrincipal User => HttpContext.Current?.User;
}
这在我的应用程序中没有任何问题。
我现在有一个新的提供商,如下所示:
public class WmsProvider : IWmsProvider
{
private readonly Lazy<ILogProvider> _logProvider;
private readonly Lazy<IMessageProvider> _messageProvider;
private readonly CormarConfig _config;
private readonly ClaimsIdentity _identity;
public WmsProvider(IPrincipalProvider principalProvider, Lazy<ILogProvider> logProvider, Lazy<IMessageProvider> messageProvider)
{
_messageProvider = messageProvider;
_logProvider = logProvider;
_identity = (ClaimsIdentity)principalProvider.User.Identity;
}
/// <summary>
/// Sends the order to WMS
/// </summary>
/// <param name="model">The order model</param>
public async Task SendAsync(OrderViewModel model)
{
var request = WmsFactory.Create(model);
await _logProvider.Value.TraceAsync($"This is a test", _identity);
await _messageProvider.Value.CreateAsync(request, model.OrderNumber, MessageType.Wms, "ORD", Method.POST, null);
}
}
(为简洁起见,我删除了其余代码)
在这种情况下,用户为空并抛出错误(Object 未找到实例)。
但是我有另一个 class 具有类似的构造函数:
public OrderProvider(CormarConfig config, IOrderService orderSerivce, IPrincipalProvider principalProvider, Lazy<IAccountProvider> accountProvider, Lazy<ICollectionManagerProvider> collectionManagerProvider, Lazy<IEmailProvider> emailProvider, Lazy<IJournalProvider> journalProvider, Lazy<IOrderLineProvider> orderLineProvider, Lazy<IStockProvider> stockProvider, Lazy<webServices> webService, Lazy<ITroposOrderLineService> troposOrderLineService, Lazy<ITroposOrderService> troposOrderService, Lazy<ITroposUnitOfWork> troposUnitOfWork, Lazy<IWmsProvider> wmsProvider)
{
//Assign our config
_config = config;
// Add our services to our class
_connectionType = config.ConnectionType;
_orderService = orderSerivce;
// Add our providers to our class
_identity = (ClaimsIdentity)principalProvider.User.Identity;
// Add our optional providers
_accountProvider = accountProvider;
_collectionManagerProvider = collectionManagerProvider;
_emailProvider = emailProvider;
_journalProvider = journalProvider;
_orderLineProvider = orderLineProvider;
_stockProvider = stockProvider;
_webService = webService;
_wmsProvider = wmsProvider;
_troposOrderLineService = troposOrderLineService;
_troposOrderService = troposOrderService;
_troposUnitOfWork = troposUnitOfWork;
}
这很好用。
两者在我的 Module:
中的注册方式相同
builder.RegisterType<OrderProvider>().As<IOrderProvider>().InstancePerRequest();
builder.RegisterType<WmsProvider>().As<IWmsProvider>().InstancePerRequest();
builder.RegisterType<PrincipalProvider>().As<IPrincipalProvider>();
需要注意的一点是,WmsProvider 被注入到 OrderProvider 中,因此它不是直接注入到控制器中。控制器构造函数如下所示:
public OrdersController(IOrderProvider provider)
{
_provider = provider;
}
这可能就是问题所在。在依赖中,上下文不可用吗?如果不是,解决方案是什么?有没有办法从 child?
获取上下文
如有任何帮助,我们将不胜感激。
我想通了。正如我所说,context 在嵌套 类 中不可用,所以为了解决这个问题,我更改了 PrincipalProvider[=21= 的注册] 每个请求的实例:
builder.RegisterType<PrincipalProvider>().As<IPrincipalProvider>().InstancePerRequest();
然后我将 PrincipalProvider 更改为如下所示:
public class PrincipalProvider : IPrincipalProvider
{
// Readonly fields
private readonly HttpContext _current;
/// <summary>
/// Default constructor
/// </summary>
public PrincipalProvider()
{
_current = HttpContext.Current;
}
/// <summary>
/// Gets the current user
/// </summary>
public IPrincipal User => _current?.User;
}
这解决了我的问题。
我在我的项目中使用 Autofac,大部分情况下它工作正常。不久前,我需要访问当前用户,并被告知最好的方法是创建一个包装器 class,如下所示:
public class PrincipalProvider : IPrincipalProvider
{
public IPrincipal User => HttpContext.Current?.User;
}
这在我的应用程序中没有任何问题。 我现在有一个新的提供商,如下所示:
public class WmsProvider : IWmsProvider
{
private readonly Lazy<ILogProvider> _logProvider;
private readonly Lazy<IMessageProvider> _messageProvider;
private readonly CormarConfig _config;
private readonly ClaimsIdentity _identity;
public WmsProvider(IPrincipalProvider principalProvider, Lazy<ILogProvider> logProvider, Lazy<IMessageProvider> messageProvider)
{
_messageProvider = messageProvider;
_logProvider = logProvider;
_identity = (ClaimsIdentity)principalProvider.User.Identity;
}
/// <summary>
/// Sends the order to WMS
/// </summary>
/// <param name="model">The order model</param>
public async Task SendAsync(OrderViewModel model)
{
var request = WmsFactory.Create(model);
await _logProvider.Value.TraceAsync($"This is a test", _identity);
await _messageProvider.Value.CreateAsync(request, model.OrderNumber, MessageType.Wms, "ORD", Method.POST, null);
}
}
(为简洁起见,我删除了其余代码)
在这种情况下,用户为空并抛出错误(Object 未找到实例)。 但是我有另一个 class 具有类似的构造函数:
public OrderProvider(CormarConfig config, IOrderService orderSerivce, IPrincipalProvider principalProvider, Lazy<IAccountProvider> accountProvider, Lazy<ICollectionManagerProvider> collectionManagerProvider, Lazy<IEmailProvider> emailProvider, Lazy<IJournalProvider> journalProvider, Lazy<IOrderLineProvider> orderLineProvider, Lazy<IStockProvider> stockProvider, Lazy<webServices> webService, Lazy<ITroposOrderLineService> troposOrderLineService, Lazy<ITroposOrderService> troposOrderService, Lazy<ITroposUnitOfWork> troposUnitOfWork, Lazy<IWmsProvider> wmsProvider)
{
//Assign our config
_config = config;
// Add our services to our class
_connectionType = config.ConnectionType;
_orderService = orderSerivce;
// Add our providers to our class
_identity = (ClaimsIdentity)principalProvider.User.Identity;
// Add our optional providers
_accountProvider = accountProvider;
_collectionManagerProvider = collectionManagerProvider;
_emailProvider = emailProvider;
_journalProvider = journalProvider;
_orderLineProvider = orderLineProvider;
_stockProvider = stockProvider;
_webService = webService;
_wmsProvider = wmsProvider;
_troposOrderLineService = troposOrderLineService;
_troposOrderService = troposOrderService;
_troposUnitOfWork = troposUnitOfWork;
}
这很好用。 两者在我的 Module:
中的注册方式相同builder.RegisterType<OrderProvider>().As<IOrderProvider>().InstancePerRequest();
builder.RegisterType<WmsProvider>().As<IWmsProvider>().InstancePerRequest();
builder.RegisterType<PrincipalProvider>().As<IPrincipalProvider>();
需要注意的一点是,WmsProvider 被注入到 OrderProvider 中,因此它不是直接注入到控制器中。控制器构造函数如下所示:
public OrdersController(IOrderProvider provider)
{
_provider = provider;
}
这可能就是问题所在。在依赖中,上下文不可用吗?如果不是,解决方案是什么?有没有办法从 child?
获取上下文如有任何帮助,我们将不胜感激。
我想通了。正如我所说,context 在嵌套 类 中不可用,所以为了解决这个问题,我更改了 PrincipalProvider[=21= 的注册] 每个请求的实例:
builder.RegisterType<PrincipalProvider>().As<IPrincipalProvider>().InstancePerRequest();
然后我将 PrincipalProvider 更改为如下所示:
public class PrincipalProvider : IPrincipalProvider
{
// Readonly fields
private readonly HttpContext _current;
/// <summary>
/// Default constructor
/// </summary>
public PrincipalProvider()
{
_current = HttpContext.Current;
}
/// <summary>
/// Gets the current user
/// </summary>
public IPrincipal User => _current?.User;
}
这解决了我的问题。