如何使用依赖注入将UserId / TenantId传递给存储库构造函数?

asp.net-core asp.net-core-mvc asp.net-mvc dependency-injection entity-framework-core

我正在使用ASP.NET 5和EF7编写多租户Web服务。存储库数据特定于租户/用户。因为我将在所有调用中使用TenantId,所以我想用当前的TenantId初始化Repository。

public class MyRepository {
    private int tenantId;
    public MyRepository(MyDbContext context, int tenantId) { 
        this.tenantId = tenantId;
        // ...
    }

    public Task<List<Data>> GetAllAsync() {
        return this.context.Data.Where(d => d.TenantId == this.tenantId).ToListAsync();
    }
}

public class Startup {
    public void ConfigureServices(IServiceCollection services) {
        // How do I pass the TenantId to the constructor?
        services.AddScoped<MyRepository>();
    }
}

在用户通过身份验证后,是否可以初始化我的存储库一次?我如何通过构造函数传递TenantId?

热门答案

您的租户和用户ID值都是运行时数据,您不应该将运行时数据注入系统的组件 (在这种情况下是您的存储库),因为这极大地使您的组合根复杂化(正如您已经体验过的那样)并使其几乎不可能验证您的对象图。运行时数据应该流经已构建的对象图。实现这一点基本上有两种方法。您可以通过组件的公共API的方法调用来传递数据,也可以注入一个负责在请求时检索运行时值的组件。

在您的情况下,后一种选择是最好的。因此,我的建议是注入一个允许检索此上下文信息的组件:

public interface ITenantContext
{
    int CurrentTenantId { get; }
}

public interface IUserContext
{
    int CurrentUserId { get; }
}

public class MyRepository {
    private readonly Func<MyDbContext> contextProvider;
    private readonly ITenantContext tentantContext;

    public MyRepository(Func<MyDbContext> contextProvider, ITenantContext tentantContext){ 
        this.contextProvider = contextProvider;
        this.tentantContex = tentantContex;
    }

    public Task<List<Data>> GetAllAsync() {
        return this.contextProvider().Data
            .Where(d => d.TenantId == this.tenantContext.CurrentTenantId)
            .ToListAsync();
}

这样可以优雅地解决问题,因为现在您可以定义ITenantContext实现,该实现知道如何为当前请求检索正确的租户ID。例如:

public sealed class AspNetSessionTenantContext : ITenantContext {
    public int CurrentTenantId {
        get { return (int)HttpContext.Current.Session["tenantId"]; }
    }
}

这甚至允许您将所有组件注册为单例,这可以提高性能,并减少常见DI陷阱的更改,例如强制依赖性



Related

许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因