使用asp.net webforms的autofac实例无法解析,嵌套生命周期也无法解析

时间:2012-02-18 11:40:25

标签: autofac

我得到以下异常“实例无法解析,并且无法从此LifetimeScope中创建嵌套生命周期,因为它已经被处理掉了。”当我尝试从global.asax Application_EndRequest事件中解析对象时。我在2.5.2.830版本中使用Autofac

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 =&gt; x.Resolve()。OpenSession())。As()。InstancePerHttpRequest();     }

1 个答案:

答案 0 :(得分:6)

Autofac通过名为Autofac.Integration.Web.ContainerDisposalModule的HttpModule进行会话处理。

你需要

  • 将您自己的会话清理放在容器处理之前运行的模块中。 这可能是一个问题,因为无法保证HttpModules的顺序。

OR

  • 从web.config中删除Container处理HttpModule,并在Application 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();
    }