Проблема времени жизни контекста пользовательского членства MVC и поставщика ролей

У меня проблемы с пользовательским членством в MVC 4. Я продолжаю получать ошибку, связанную с временем жизни контекста, когда я делаю вызов ajax для получения частичного результата от сервера (контроллера), ошибка всегда {"Поставщик был закрыт"} или {"Уже есть открытый объект чтения данных, связанный с этой командой, который необходимо сначала закрыть."} ошибка всегда возникает в пользовательском поставщике ролей. Я попытаюсь объяснить текущую настройку, которую я использую.

Я унаследовал от Membership и RoleProvier и переопределил все подобные методы.

public class CustomRoleProvider : RoleProvider
{
        private IAccountService _accountService;

        public CustomRoleProvider()
        {
            _accountService = new AccountService();
        }
        public override string[] GetRolesForUser(string username)
        {
             return _accountService.GetRolesForUser(username);
        }
}

Провайдер членства реализован так же, как вышеприведенный IAccountService — это уровень службы, который имеет дело со всеми учетными записями и ролями пользователей. Все классы уровня службы реализуют базовый класс службы, называемый ServiceBase, который создает контекст БД.

public class ServiceBase
{
    protected Context Context;

    protected ServiceBase() : this("Context") {}

    protected ServiceBase(string dbName)
    {
        IDatabaseInitializer<Context> initializer = new DbInitialiser();
        Database.SetInitializer(initializer);
        Context = new Context(dbName);
    }
}

Контроллер, который имеет ajax для него

[Authorize(Roles = "Administrator,Supplier")]
public class AuctionController : Controller
{
    private IAuctionService _service;

    public AuctionController()
    {
        _service = new AuctionService();
    }
    public AuctionController(IAuctionService service)
    {
        _service = service;
    }
    [CacheControl(HttpCacheability.NoCache), HttpGet]
    public ActionResult RefreshAuctionTimes(int auctionId)
    {
        return PartialView("_AuctionTimer", BusinessLogic.Map.ConvertAuction(_service.GetAuction  (auctionId)));
     }

}

Проблема началась только тогда, когда я добавил атрибут [Authorize(Roles = "Administrator,Supplier")] к контроллеру, который обрабатывал вызов ajax, я знаю, что это время жизни DbContext для жизни приложения, а уровень обслуживания контроллеров уничтожается и воссоздается в каждом сообщении, но я' Я не уверен, как лучше всего справиться с этим, я использовал эту настройку раньше, но с DI и Windsor, и у меня никогда не было этой проблемы, поскольку IOC контролировал контекст.

Было бы лучше создать поставщикам свой собственный контекст БД или это конфликт между двумя поставщиками, и действительно ли им нужно использовать один и тот же контекст БД?

Любая помощь будет большой спасибо


person Troublesum    schedule 18.02.2014    source источник


Ответы (2)


Проблема именно в том, что вы подозреваете. Это связано с тем, что вы создаете один экземпляр DbContext, и поэтому у вас возникают проблемы с подключением. Если вы используете его со схемой IOC/DI, вы это исправите. Другой вариант — вручную обрабатывать соединения.

Примером того, как это сделать с помощью Ninject в качестве контейнера IOC, является здесь Они должны использовать один и тот же контекст, чтобы решить проблему.

person lopezbertoni    schedule 18.02.2014
comment
Ура, как я и ожидал, я на самом деле мог бы использовать метод Джо ниже в качестве обходного пути, поскольку у меня нет времени для реализации IOC в банкомате приложения, но это, безусловно, более чистый вариант. - person Troublesum; 18.02.2014

Я бы посоветовал вам создать класс уровня обслуживания при каждом вызове GetRolesForUser:

public override string[] GetRolesForUser(string username)
{
     return new AccountService().GetRolesForUser(username);
}
person Joe    schedule 18.02.2014
comment
Спасибо, Джо, просто, но не подумал об этом :) нужно было просто найти время, чтобы внедрить IOC ранее в проект... Я отметил приведенный выше ответ как лучшее решение, как мне кажется, но я мог бы просто использовать ваша идея для быстрого исправления. Спасибо! - person Troublesum; 18.02.2014
comment
@Troublesum, я не уверен, что использования IOC для внедрения вашего сервиса будет достаточно для решения вашей проблемы. Метод GetRolesForUser вашего провайдера можно вызывать из нескольких потоков, поэтому он должен быть потокобезопасным. - person Joe; 18.02.2014