Работа с несколькими арендаторами на MVC

Я хотел бы спросить ваше мнение о том, как я справляюсь с MultiTenancy. Я использую MVC3 (переключение на MVC4) и EF в качестве моего бэкэнда. Я использую одно приложение, общую схему MultiTenancy. Ниже приведен код:

public abstract class Service<T> where T : Entity
{
    private Repository<T> _repo;
    public Service()
    {
        _repo = new Repository<T>();
    }

    public bool Authenticate(int id)
    {
        //var companyInfo = _authorizationRepository.GetApiKey(apiKey);
        int tenantId = 0; // replaced by companyInfo using repository
        var entity = _repo.GetQuery(tenantId).Where(e => e.Id == id).First();

        if (tenantId != entity.TenantId)
            throw new ArgumentException();

        return true;
    }
}

public class EmployeeService : Service<Employee>
{
    private EmployeeRepository employeeRepository;
    public EmployeeService()
    {
        employeeRepository = new EmployeeRepository();
    }

    public Employee GetEmployeeById(int employeeId)
    {
        this.Authenticate(employeeId);
        return employeeRepository.GetById(employeeId);
    }
}

public class Entity
{
    public int Id { get; set; }
    public int TenantId { get; set; }
}

Конечно, я тоже буду там, но для простоты я удалил их здесь (временно). Я использовал Generics (чувствуя себя грязно из-за этого) на уровне обслуживания, так как у меня возникли проблемы при сравнении TenantId с правильным Entity, который будет передан в классе. Я планирую перекодировать это с помощью FilterAttributes, но я понятия не имею, как это сделать. Как вы, ребята, справляетесь со своей арендой? Есть ли в дизайне некоторые существенные недостатки, с которыми я могу столкнуться в долгосрочной перспективе? Если у вас есть несколько примеров, использующих FilterAttributes, это очень поможет.

Спасибо!

1 ответ

Решение

В настоящее время мы создаем довольно большое многопользовательское веб-приложение. Ну, это не так просто, как кажется, но как только вы построите свою архитектуру, все будет просто. Наш проект находится в глубокой разработке, но вы можете проверить часть с открытым исходным кодом на сайте nanocms.codeplex.com (мы не загрузили тестовую версию базы данных через несколько дней)

Поскольку это довольно широкий вопрос, я постараюсь обобщить некоторые проблемы и пути их решения.

Сначала вам нужно определить арендатора для каждого запроса. У нас есть глобальный фильтр действий, который анализирует URL и сравнивает его с данными в базе данных. Конечно, вы должны кэшировать все данные, чтобы не было обращений к базе данных. Вы не должны сохранять что-либо из этого в файле cookie или сеансе, потому что пользователь может посетить более одного клиента одновременно. Я предлагаю вам поместить эти данные в элементы HttpRequest, чтобы вы делали это только один раз в запросе, но эти данные всегда были доступны.

Для аутентификации пользователи должны быть уникальными. Вы должны подумать, хотите ли вы дать некоторым пользователям разные права на каждого арендатора. Если это так, вы должны написать свой код аутентификации и даже атрибут, чтобы вы могли проверить его роль в текущем арендаторе. В нашем приложении, когда пользователь аутентифицируется, мы создаем объект сеанса. В объекте у нас есть статические методы, которые проверяют права у арендатора.

Я предлагаю, чтобы вы держали элементы HttpRequest строго типизированными. У нас есть:

public static int TenantID {
    get { return System.Web.HttpContext.Current.Items.Contains("TenantID") ? Convert.ToInt32(System.Web.HttpContext.Current.Items["TenantID"]) : -1; }
    set {
        if (!System.Web.HttpContext.Current.Items.Contains("TenantID"))
            System.Web.HttpContext.Current.Items.Add("TenantID", value);
        System.Web.HttpContext.Current.Items["TenantID"] = value;
    }
}
Другие вопросы по тегам