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

Я получаю следующее исключение: «Экземпляры не могут быть разрешены, и вложенные времена жизни не могут быть созданы из этого 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 ();}

1 Ответ

6 голосов
/ 23 февраля 2012

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

Вам необходимо либо

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

ИЛИ

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

ИЛИ

  • Создайте класс диспетчера сеансов с 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();
    }
...