我试图在我的DBContext中获取有关当前用户的详细信息,以便在更新记录时可以存储CreatedByUserId
和ModifiedByUserId
。
我发现注入的IPrincipal实例对控制器有效,但在注入我的数据库上下文时是空的,这是在一个单独的程序集中。
我按照以下方式使用Autofac进行注射:
builder.Register(c => HttpContext.Current.User).As<IPrincipal>().InstancePerRequest();
builder.Register<AppDbContext>(c => new AppDbContext(GlobalHost.DependencyResolver.Resolve<IPrincipal>())).InstancePerLifetimeScope();
我的控制器构造函数看起来像这样,user
将在此处按预期生效:
public class ProductsController : Controller
{
private readonly IProductService _productService;
public ProductsController(IProductService productService, IPrincipal userPrincipal)
{
var user = userPrincipal;
_productService = productService;
}
我的DBContext构造函数看起来像这样,user
在这里将为null:
public partial class AppDbContext : System.Data.Entity.DbContext, IAppDbContext
{
public AppDbContext(IPrincipal principal)
: this("Name=SqlConnection", principal)
{
var user = principal;
}
在DB上下文代码之前调用控制器代码,因此它不是时间问题,所以我在这里猜测问题是DB上下文代码在与控制器不同的线程上运行可能有不同的身份?
如果我使用此代码在我的数据库上下文中获取身份,我可以成功地获取用户:
var user = System.Threading.Thread.CurrentPrincipal;
但似乎我可能遇到在同一个应用程序中以两种不同的方式获取用户的问题,并且我需要想办法让DI将HTTPContext的用户返回到网络项目和线程的另一个组件的主体,所有这些都是错误的解决方案?
任何人都可以帮助我理解为什么我会看到上述行为,并建议在mvc应用程序的不同程序集中获取主体的最佳方法吗?
答案 0 :(得分:1)
所以,这里的问题结果是我在这行中设置数据库上下文时使用了错误的依赖关系解析器:
builder.Register<AppDbContext>(c => new AppDbContext(GlobalHost.DependencyResolver.Resolve<IPrincipal>())).InstancePerLifetimeScope();
GlobalHost.DependencyResolver
正在给我SignalR解析器,而不是MVC的解析器。删除GlobalHost位然后给我System.Web.MVC.DependencyResolver
然后我可以使用它来获取IPrincipal如下:
builder.Register<AppDbContext>(c => new AppDbContext(DependencyResolver.Current.GetService<IPrincipal>())).InstancePerRequest();