container
container copied to clipboard
Error: Resolution failed with error: Cannot access a disposed object.
I just did a production release and I'm getting intermittent errors like this.
Resolution failed with error: Cannot access a disposed object. Object name: 'Container[546].Child[0]'.
For more detailed information run Unity in debug mode: new UnityContainer().AddExtension(new Diagnostic())
It's happening when trying to Resolve an type that is not based on an interface and is not registered. I'm calling Container.Resolve<T>()
Any idea. It's not even a disposable object. It does not implement IDisposable.
It's looking like I'm going to rollback by deployment until I get a better understanding of what's going on, but any help would be appreciated.
I'm starting to investigate. I think somehow our container seems to be getting disposed and we wind up using it afterwards.
We're using WebApi We have an IDependencyScope created by an IDependencyResolver. Here's the set up.
In global.asax.cs in Application_Start we call this.
_Container = BuildUnityContainer();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(_Container);
UnityDependencyResolver.cs looks like this.
public class UnityDependencyResolver : UnityDependencyScope, IDependencyResolver
{
public UnityDependencyResolver(IUnityContainer container)
: base(container)
{
}
public IDependencyScope BeginScope()
{
var childContainer = Container.CreateChildContainer();
return new UnityDependencyScope(childContainer);
}
}
and finally UnityDependencyScope.cs looks like this.
public class UnityDependencyScope : IDependencyScope
{
protected IUnityContainer Container { get; private set; }
public UnityDependencyScope(IUnityContainer container)
{
Container = container;
}
public object GetService(Type serviceType)
{
if (typeof(IHttpController).IsAssignableFrom(serviceType))
{
return Container.Resolve(serviceType);
}
try
{
return Container.Resolve(serviceType);
}
catch
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
return Container.ResolveAll(serviceType);
}
public void Dispose()
{
Container.Dispose();
}
}
We haven't seen any issues in our previous version of Unity which was version 5.8.11. We are now using 5.11.7 and seeing the issue.
If anyone can give me some clues on where to look that would be great. I need to get this resolved ASAP and I suspect I'm going to have a difficult time recreating this in lower environments since it seems very intermittent. It must be a timing issue.
I wonder if we have issues with Async. Maybe the Dispose is getting called prior to completing an async operation?
It is known issue and will be fixed in v6. I'd suggest to go back to working version for now. If you could locate the issues and create repeatable test case, I would appreciate it. It would help a great deal.
@ENikS , Thanks. Any idea on how far I need to go back? I made lots of changes to support 5.11.7, would hate to go all the way back to 5.8.11.
Look at this issue, this been going on for a while. Check the other issues in that repo.
I was looking through your source and found this WebApi resolver. It seems to be setup different from mine. It has a SharedDependencyScope that doesn't dispose the container. Can you explain why this is different and do you think this is the correct way to use it? Also, I'm using .Net Framework 4.7.2, not .Net Core.
using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;
namespace Unity.AspNet.WebApi
{
/// <summary>
/// An implementation of the <see cref="IDependencyResolver"/> interface that wraps a Unity container.
/// </summary>
public sealed class UnityDependencyResolver : IDependencyResolver
{
private readonly IUnityContainer _container;
private readonly SharedDependencyScope _sharedScope;
/// <summary>
/// Initializes a new instance of the <see cref="UnityDependencyResolver"/> class for a container.
/// </summary>
/// <param name="container">The <see cref="IUnityContainer"/> to wrap with the <see cref="IDependencyResolver"/>
/// interface implementation.</param>
public UnityDependencyResolver(IUnityContainer container)
{
_container = container ?? throw new ArgumentNullException(nameof(container));
_sharedScope = new SharedDependencyScope(container);
}
/// <summary>
/// Reuses the same scope to resolve all the instances.
/// </summary>
/// <returns>The shared dependency scope.</returns>
public IDependencyScope BeginScope()
{
return _sharedScope;
}
/// <summary>
/// Disposes the wrapped <see cref="IUnityContainer"/>.
/// </summary>
public void Dispose()
{
_container.Dispose();
_sharedScope.Dispose();
}
/// <summary>
/// Resolves an instance of the default requested type from the container.
/// </summary>
/// <param name="serviceType">The <see cref="Type"/> of the object to get from the container.</param>
/// <returns>The requested object.</returns>
public object GetService(Type serviceType)
{
try
{
return _container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
/// <summary>
/// Resolves multiply registered services.
/// </summary>
/// <param name="serviceType">The type of the requested services.</param>
/// <returns>The requested services.</returns>
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return _container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
private sealed class SharedDependencyScope : IDependencyScope
{
private readonly IUnityContainer _container;
public SharedDependencyScope(IUnityContainer container)
{
_container = container;
}
public object GetService(Type serviceType)
{
return _container.Resolve(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _container.ResolveAll(serviceType);
}
public void Dispose()
{
// NO-OP, as the container is shared.
}
}
}
}
It's possible the reason mine is different is that I want to create a new child container for each request. That way I can have a HeirarchialLifetime Manager that will be per request.
Perhaps this is the reason?
public void Dispose()
{
// NO-OP, as the container is shared.
}