【问题标题】:How to pass a parameter to DbContext constructor using Dependency Injection如何使用依赖注入将参数传递给 DbContext 构造函数
【发布时间】:2016-11-07 14:57:04
【问题描述】:

我正在修改我的 DbContext 以通过要求一个tenantId 来支持多租户:

public AppContext(int tenantId)            
    {
        _tenantId = tenantId;
    }

以前是没有参数的。

在我的服务类中,我使用 DI 实例化了上下文:

    private readonly AppContext db;
    private CommService _commService;

    public AdminService(AppContext db, CommService commService)
    {
        this.db = db;
        _commService = commService;
    }

在我的控制器中,同样的事情:

    private readonly CommService _commService;
    public AdminController(CommService commService) {
         _commService = commService;
    }

我正在使用 Unity,但实际上并没有做太多配置 - 一切正常。

我将从我的控制器中检索tenantId。如何从 Controller > Service layer > Constructor 传递tenantId?

【问题讨论】:

  • 你应该注入DbContextFactory,并创建一个类似factory.CreateDbContextForTenant(int tenantId)的方法。

标签: c# entity-framework asp.net-web-api dependency-injection unity-container


【解决方案1】:

Unity 无法传递tenantId,因为这是一个变量,它取决于当前的使用情况或任何其他条件,tenantId 将在运行时确定,所以不要让它可注入。

不过,你可以为它建立一个工厂并注入这个工厂。

例如:

public Interface ITenantDiscovery
{
  int TenantId{get;}
}

public class UrlTenantDiscovery:ITenantDiscovery
{
 public int TenantId
 {
   get
    {
       var url = -- get current URL, ex: from HttpContext
       var tenant = _context.Tenants.Where(a=>a.Url == url);
       return tenant.Id; -- cache the Id for subsequent calls
    }
 }

在 UnityConfig 中,注册 ITenantDiscovery 及其实现 UrlTenantDiscovery

更改您的 AppContext 以接受 ITenantDiscovery 的实例

public AppContext(ITenantDiscovery tenantDiscovery)            
    {
        _tenantId = tenantDiscovery.TenantId;
    }

就是这样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 2015-12-17
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    相关资源
    最近更新 更多