Как передать параметр конструктору DbContext с помощью инъекции зависимостей

Я нахожусь в середине переработки моего 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от моих контроллеров. Как передать tenantId из Controller > Service layer > > Constructor?

1 ответ

  1. Unity не может передатьtenantId, поскольку это переменная, которая будет зависеть от текущего использования, например, или любого другого условия, tenantIdбудет определяться во время выполнения, поэтому не делайте его инъекционным.

    Все еще, вы можете сделать фабрику для его и injecet эта фабрика.

    бывший:

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

    Вот оно.