【问题标题】:How to inject a scoped service into DbContext? Net Core如何将作用域服务注入 DbContext?网络核心
【发布时间】:2018-02-08 23:50:25
【问题描述】:

我正在构建多租户应用程序并尝试让数据安全性现在正常工作。 Context 的单元测试运行良好,因为我使用选项和 UserContext 创建了上下文,但我很难让它在程序集中工作,因为它需要注入 userContext。

我不能像其他所有东西一样使用标准控制器注入,就像我拥有它一样,上下文创建失败:

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

我不能或者我不知道如何以这种方式注入我的 UserContext...

【问题讨论】:

  • 你得到什么错误信息?
  • 那里只是 null 并且实际上它导致了 stackoverflowexception...
  • 包含 DbContext 连接字符串的 web.config 是否可供代码访问?
  • 是的。它正在创建 DbContext 但没有范围内的 UserContext
  • 使用 EF Core 的数据库上下文的默认生命周期是有范围的。 – 你能展示你真正想要做什么以及你得到了什么错误吗?

标签: c# asp.net-core .net-core entity-framework-core


【解决方案1】:

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

public class MultiTenantContext : DbContext
{
    private UserContext _userContext;

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

您需要确保在注册实体框架之前注册UserContext 服务。 e. g.

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

【讨论】:

  • 不。它不是这样工作的。我就是这样做的,但它没有用。
  • 那么请详细说明不起作用。我已经测试过了,它对我有用。 @MU
  • 这不适用于 dbcontext 池。即:services.AddDbContextPool,你需要有一个带有 DbContextOptions 的构造函数,所以在这种情况下构造函数依赖注入将不起作用。
【解决方案2】:

我假设对于多租户应用程序,您正试图根据来自 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
    

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

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-16
      • 2020-09-26
      • 1970-01-01
      • 1970-01-01
      • 2018-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多