如何在DbContext中注入作用域服务?Net Core

9

我正在构建多租户应用并尝试实现数据安全性。 使用选项和UserContext创建上下文的单元测试效果很好,但是在装配中难以实现,因为需要注入userContext。

我无法像其他内容一样使用标准控制器注入,因为如果这样做,上下文创建将失败:

services.AddEntityFrameworkNpgsql()
                .AddDbContext<MultiTenantContext>(o =>
                    o.UseNpgsql(Configuration.GetConnectionString("DbContext")

我不知道如何或者我不会通过这种方式注入我的UserContext...

你收到了什么错误信息? - Isaac Kleinman
是的。它正在创建DbContext,但没有作用域为UserContext。 - Marek Urbanowicz
EF Core 的数据库上下文的默认生命周期是作用域。- 你能展示一下你实际想要做什么以及你遇到了什么错误吗? - poke
UserContext 是否是不同的 DbContext?您的代码只展示了添加 MultiTenantContext - Brad
@MU 你在DbContext构造函数中使用UserContext吗?你能分享一下如何实现“使用选项和UserContext创建上下文”吗?UserContext的构造函数有参数吗?如果像DbContext一样,你可以尝试注入,例如services.AddDbContext<UserContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); - Edward
显示剩余2条评论
3个回答

12

简单使用构造函数注入。它的工作方式与控制器中的方式相同。

public class MultiTenantContext : DbContext
{
    private UserContext _userContext;

    public MultiTenantContext(DbContextOptions options, UserContext userContext) : base(options)
    {
        _userContext = userContext;
    }
}

在注册实体框架之前,您需要确保先注册UserContext服务。例如:

您需要确保,在注册实体框架之前,您已经注册了UserContext服务。

services.AddScoped<UserContext, UserContext>();
services.AddEntityFrameworkNpgsql()
                .AddDbContext<MultiTenantContext>(o =>
                    o.UseNpgsql(Configuration.GetConnectionString("DbContext")

1
不行,这样做不起作用。我确切地按照这种方式做了,但它并没有起作用。 - Marek Urbanowicz
那请详细说明一下“不工作”的情况。我已经测试过了,对我来说是可以工作的。@MU - Christian Gollhardt
5
这对于数据库上下文池化不起作用。例如:services.AddDbContextPool,您需要具有一个带有DbContextOptions的单个构造函数,因此在这种情况下无法使用构造函数依赖注入。 - Panayiotis Savva

5
我假设您正在为多租户应用程序查找基于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


3

接受的答案对我也没有用,最终我采取了与原始答案非常相似的方法,感谢@Christian的指导。

我想将一个服务注入到DbContext中,该服务负责根据某些HTTP请求标头动态加载连接字符串,以下是使用的代码

在启动时:

  services.AddScoped<IConnectionService, ConnectionService>();
  services.AddDbContext<MyDbContext>(); //Connection string will be set on event OnConfiguring

在我的DbContext中:

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);
        }
    }

希望这能有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接