Так что мне нужно применить фильтр запросов на более позднем этапе, т.е.после аутентификации пользователя?Любые указатели, с чего начать с подхода среднего уровня / логического уровня?
Конечно, это мнение об архитектуре, но я разделяю его следующим образом:
Уровень данных- ответственность этого уровня за доступ к ресурсам (обычно) за пределами исполняемого приложения.Это включает;Базы данных, файловый ввод-вывод, веб-API и т. Д.
Business / Logic-Tier - ответственность этого уровня (которая может быть разбита далее) должна проходить проверку подлинности, авторизацию, проверку и создание объектов , представляющихбизнес нуждается.Для создания этих объектов он может использовать один или несколько объектов доступа к данным (например, он может использовать IO DA для получения изображения из локальной файловой системы или хранилища Azure и базу данных DA для получения метаданных об этом изображении).
Presentation / Exposure-Tier - ответственность этого уровня заключается в том, чтобы обернуть и преобразовать объект в потребности потребителя (winforms, wpf, html, json, xml, двоичная сериализация и т. Д.).
Оставив логику внена уровне данных (даже в мультитенантных системах) вы получаете возможность доступа к данным во всех системах (и, поверьте мне, здесь можно заработать много денег).
Это, вероятно, намного больше, чем я могу объяснить в таком коротком месте и очень мое мнение .Я собираюсь быть опущенным совсем немного , но здесь идет.
Уровень данных
namespace ProjectsData
{
public interface IProjectDA
{
IProjectDO GetProject(Guid projectId, Guid organizationId);
}
private class ProjectDA : DbContext, IProjectDA
{
public ProjectDA (...)
public IEnumerable<ProjectDO> Projects { get; set; }
protected override void OnModelCreating(ModelBuilder builder) {... }
public IProjectDO GetProject(Guid projectId, Guid organizationId)
{
var result = Projects
.FirstOrDefault(p => p.Id == projectId && OrganizationId = organizationId);
return result;
}
}
public interface IProjectDO{ ... }
private class ProjectDO: IProjectDO
{
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
public Guid CategoryId { get; set; }
}
}
Логика
namespace ProjectBusiness
{
public interface IProjectBO { .. }
public interface IOrganization
{
Guid OrganizationId { get; }
}
private class ProjectBA : IProjectBO
{
private readonly IProjectDA _projectDA;
private readonly IIdentity _identity;
private readonly IOrganization _organization;
public ProjectLogic(IProjectDA projectDA,
IIdentity identity,
IOrganizationContext organizationContext)
{
_projectDA = projectDA;
_identity = identity;
}
public IProjectBO GetProject(Guid id)
{
var do = _projectDA
.GetProject(id, _organization);
var result = map.To<ProjectBO>(do);
return result;
}
}
public interface IProjectBO { .. }
private class ProjectBO
{
public Guid Id { get; set; }
public Guid OrganizationId { get; set; }
public Guid CategoryId { get; set; }
}
}
Итакпри этих условиях уровень данных знает тип запроса, но не мультитенант .Это не ограничивает все запросы, основанные на чем-либо.Эта архитектура имеет ряд преимуществ.
Во-первых, в приведенном выше примере ваш продукт взлетает, и ваш руководитель хочет узнать, какие категории наиболее популярны.
namespace StatisticsBusiness
{
public interface IStatisticsBO
{
IEnumerable<ICategoryStatisticBO> CategoryStatistics { get; set; }
}
public interface ICategoryStaticBO
{
Guid CategoryId { get; }
int ProjectCount { get; }
}
private class StatisticsBA : IStatisticsBO
{
private readonly IProjectDA _projectDA;
private readonly IIdentity _identity;
public ProjectLogic(IProjectDA projectDA,
IIdentity identity)
{
_projectDA = projectDA;
_identity = identity;
}
public IEnumerable<IProjectBO GetOrderedCategoryPopularity()
{
var dos = _projectDA
.GetProjectCategoryCounts()
var result = map.To<IEnumerable<IStatisticsBO>>(dos);
return result;
}
}
public interface IStatisticsBO{ .. }
private class StatisticsBO
{
public Guid CategoryId { get; }
public int ProjectCount { get; }
}
}
Примечание. Некоторые люди предпочитают передавать выражение в качестве предиката.Оба имеют свои преимущества и недостатки.Если вы решите пойти по пути предиката, вам придется решить, используют ли все ваши типы доступа к данным предикаты или нет.Просто осознайте, что использование предикатов против IO или Web Api может потребовать больше усилий, чем оно того стоит.
Во-вторых, некоторые требования приводят к невозможности использования Entity Framework.Вы заменяете его Dapper или другой новой лучшей технологией / фреймворком.Все, что вам нужно, это создать новые классы I<whataver>DA
, потому что логика потребления ничего не знает, кроме этих интерфейсов ( программирование с использованием интерфейса , L в принципах программирования SOLID и Я в принципах твердого программирования ).
Я не использую этот шаблон все время, потому что для некоторых небольших веб-сайтов это слишком много работы для вознаграждения.