问题
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