我正在构建多租户应用,并试图让数据安全性正常运行。 Context的单元测试工作得很好,因为我用options和UserContext创建了上下文,但是我很难让它在程序集中工作,因为它需要注入userContext。
我无法使用标准控制器注入,就像我拥有它一样,上下文创建失败:
services.AddEntityFrameworkNpgsql()
.AddDbContext<MultiTenantContext>(o =>
o.UseNpgsql(Configuration.GetConnectionString("DbContext")
我不能或者我不知道如何以这种方式注入我的UserContext ......
答案 0 :(得分:6)
简单使用构造函数注入。它的工作方式与控制器相同。
public class MultiTenantContext : DbContext
{
private UserContext _userContext;
public MultiTenantContext(DbContextOptions options, UserContext userContext) : base(options)
{
_userContext = userContext;
}
}
您需要确保在注册实体框架之前注册UserContext
服务。即克。
services.AddScoped<UserContext, UserContext>();
services.AddEntityFrameworkNpgsql()
.AddDbContext<MultiTenantContext>(o =>
o.UseNpgsql(Configuration.GetConnectionString("DbContext")
答案 1 :(得分:3)
我假设您在多租户应用程序中尝试根据来自HttpRequest的登录用户找出Tenant
。你可以做这样的事情
public class UserContext
{
private readonly IHttpContextAccessor _accessor;
public RequestContextAdapter(IHttpContextAccessor accessor)
{
this._accessor = accessor;
}
public string UserID
{
get
{
// you have access to HttpRequest object here
//this._accessor.HttpContext.Request
}
}
}
ASP.NET Core会自动将IHttpContextAccessor
注入UserContext
您还必须注册UserContext
services.AddScoped<UserContext, UserContext>();
然后使用构造函数注入在任何需要的地方注入UserContext
答案 2 :(得分:0)
被接受的答案对我也不起作用,我最终采取了与原始答案非常相似的方法,感谢@Christian的指导。
我想将服务注入到DbContext中,该服务负责根据以下HTTP请求标头动态加载连接字符串,以下是使用的代码
在启动中:
services.AddScoped<IConnectionService, ConnectionService>();
services.AddDbContext<MyDbContext>(); //Connection string will be set on event OnConfiguring
在MyDbContext中:
public class MyDbContext : DbContext
{
private readonly IConnectionService _connectionService;
public MyDbContext(DbContextOptions<MyDbContext> options, IConnectionService connectionService) : base(options)
{
_connectionService = connectionService;
}
public DbSet<Customer> Customers { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connectionString = _companyConnectionService.ConnectionString; //Custom logic to read from http request header certain value and switch connection string
optionsBuilder.UseSqlServer(connectionString);
}
}
希望这会有所帮助。