Я пытаюсь создать общий тип авторизации поверх DbContext, чтобы моим разработчикам не нужно было заботиться об авторизации в репозитории / домене.
Простой пример, такой как
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>().Property<string>("TenantId").HasField("_tenantId");
// Configure entity filters
modelBuilder.Entity<Blog>().HasQueryFilter(b => EF.Property<string>(b, "TenantId") == _tenantId);
modelBuilder.Entity<Post>().HasQueryFilter(p => !p.IsDeleted);
}
Какой пример MS работает. _tenantId будет использоваться для создания выражения, и для каждого экземпляра DbContext будет использоваться правильное значение _tenantId.
Но я не хочу, чтобы все наши авторизаторы были настроены из контекста нашей БД, я хочу внедрить его. Что-то вроде
public class AgreementAuthorization : IEntityAuthorization
{
private readonly string _legalEntityNumber;
public AgreementAuthorization(IAuthScope scope)
{
_legalEntityNumber = scope.LegalEntityNumber;
}
public void Build(ModelBuilder builder)
{
builder
.Entity<Agreement>()
.HasQueryFilter(a => _legalEntityNumber == null || a.LegalEntity.Number == _legalEntityNumber);
}
}
public class MyDbContext : DbContext
{
private IEnumerable<IEntityAuthorization> _entityAuthorization;
MyDbContext(IEnumerable<IEntityAuthorization> entityAuthorization)
{
_entityAuthorization = entityAuthorization;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
builder.ApplyConfigurationsFromAssembly(typeof(MyDbContext).Assembly);
_entityAuthorization.ForEach(a => a.Build(builder));
}
}
Это не работает, каждый раз запрашивать тест на нуль и проходить. Если я переместу код непосредственно в DbContext, он будет работать. Значение _entityAuthorization лежит непосредственно на DbContext.