autofac с веб-формами asp.net. Экземпляры не могут быть разрешены, а вложенные сроки жизни не могут быть

Я получаю следующее исключение: «Экземпляры не могут быть разрешены, и вложенные сроки жизни не могут быть созданы из этого LifetimeScope, поскольку он уже был удален». когда я пытаюсь разрешить объект из события global.asax Application_EndRequest. Использую Autofac в версии 2.5.2.830

public class Global : System.Web.HttpApplication, IContainerProviderAccessor
{
    // Provider that holds the application container.
    static Autofac.Integration.Web.IContainerProvider _containerProvider;

    // Instance property that will be used by Autofac HttpModules
    // to resolve and inject dependencies.
    public Autofac.Integration.Web.IContainerProvider ContainerProvider
    {
        get { return _containerProvider; }
    }
    protected void Application_Start(object sender, EventArgs e)
    {
        var builder = new ContainerBuilder();
...
        _containerProvider = new ContainerProvider(builder.Build());
    }

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        ISession session = _containerProvider.RequestLifetime.Resolve<ISession>();
        session.BeginTransaction();
    }

    private void Application_EndRequest(object sender, EventArgs e)
    {
        ISession session = ContainerProvider.RequestLifetime.Resolve<ISession>();
    }

Я регистрируюсь таким образом:

builder.Register (x => x.Resolve (). OpenSession ()). As (). InstancePerHttpRequest (); }


person Adam Łepkowski    schedule 18.02.2012    source источник
comment
Почему вы разрешаете сессию в EndRequest? Планируете ли вы закрыть там сессию?   -  person Peter Lillevold    schedule 18.02.2012
comment
Да, я хочу совершить транзакцию и закрыть сеанс. Я пытаюсь создать шаблон предварительного запроса сеанса с помощью autofac.   -  person Adam Łepkowski    schedule 18.02.2012


Ответы (1)


Autofac выполняет удаление сеанса через HttpModule, называемый Autofac.Integration.Web.ContainerDisposalModule.

Вам нужно либо

  • Поместите собственную очистку сеанса в модуль, который запускается перед удалением контейнера. Это может быть проблемой, поскольку порядок HttpModules не гарантируется.

OR

  • Удалите HttpModule для утилизации контейнера из файла web.config и выполните собственную очистку области жизненного цикла в своем приложении EndRequest.
private void Application_EndRequest(object sender, EventArgs e)
{
    ISession session = ContainerProvider.RequestLifetime.Resolve();
    //cleanup transaction etc...
    ContainerProvider.EndRequestLifetime();     
}

OR

  • Создайте класс диспетчера сеансов, который является IDisposable и имеет область действия, возьмите свой ISession в качестве зависимости конструктора и выполните очистку сеанса, когда он будет удален в конце срока службы.

    public class SessionManager : IDisposable
    {
        private readonly ISession _session;
        private ITransaction _transaction;

        public SessionManager(ISession session)
        {
            _session = session;
        }

        public void BeginRequest()
        {
            _transaction = _session.BeginTransaction();
        }

        #region Implementation of IDisposable

        /// 
        /// Dispose will be called automatically by autofac when the lifetime ends
        /// 
        public void Dispose()
        {
            //commit rollback, whatever
            _transaction.Commit();
        }

        #endregion
    }

Обязательно инициализируйте диспетчер сеансов.


    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        SessionManager manager = _containerProvider.RequestLifetime.Resolve();
        manager.BeginRequest();
    }
person Danielg    schedule 22.02.2012