autofac with asp.net webforms Instances cannot be resolved and nested lifetimes cannot be

放肆的年华 提交于 2019-12-08 08:48:54

问题


I get following exception "Instances cannot be resolved and nested lifetimes cannot be created from this LifetimeScope as it has already been disposed." when i try to resolve object from global.asax Application_EndRequest event. I use Autofac in version 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>();
    }

I register in that way:

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


回答1:


Autofac does its session disposal through an HttpModule called Autofac.Integration.Web.ContainerDisposalModule.

You need to either

  • Put your own session cleanup in a module that is run before the container disposal. This can be a problem as the order of HttpModules is not guaranteed.

OR

  • Remove the Container disposal HttpModule from the web.config and do your own lifetime scope cleanup in your Application EndRequest
private void Application_EndRequest(object sender, EventArgs e)
{
    ISession session = ContainerProvider.RequestLifetime.Resolve();
    //cleanup transaction etc...
    ContainerProvider.EndRequestLifetime();     
}

OR

  • Create a session manager class that is IDisposable and lifetime scoped, take your ISession as a constructor dependency and do your session cleanup when it is Disposed at the end of the lifetime.

    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
    }

You must make sure to initialize your session manager.


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


来源:https://stackoverflow.com/questions/9340828/autofac-with-asp-net-webforms-instances-cannot-be-resolved-and-nested-lifetimes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!