Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Resolution failed with error: Cannot access a disposed object. #290

Open
markdemich opened this issue Oct 30, 2020 · 7 comments
Open
Assignees
Labels
Milestone

Comments

@markdemich
Copy link

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()

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.

@markdemich
Copy link
Author

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?

@ENikS
Copy link
Contributor

ENikS commented Oct 30, 2020

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.

@markdemich
Copy link
Author

@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.

@ENikS
Copy link
Contributor

ENikS commented Oct 30, 2020

Look at this issue, this been going on for a while. Check the other issues in that repo.

@markdemich
Copy link
Author

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.
            }
        }
    }
}

@markdemich
Copy link
Author

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.

@ENikS
Copy link
Contributor

ENikS commented Oct 30, 2020

Perhaps this is the reason?

 public void Dispose()
            {
                // NO-OP, as the container is shared.
            }

@ENikS ENikS transferred this issue from unitycontainer/unity Nov 17, 2020
@ENikS ENikS self-assigned this Nov 17, 2020
@ENikS ENikS added the Bug 🐛 label Nov 17, 2020
@ENikS ENikS added this to the 6.0.0 milestone Nov 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants