Question

I am using ASP.NET MVC WebApi 2 and injecting concrete types into controllers using Unity 3 and this Unity MVC bootstrapper.

The issue here is that one the registered types initialises an Entity Framework 6 DbContext for every resolve:

public sealed class EntityFrameworkUnitOfWork : IUnitOfWork
{
    internal DbContext Context { get; private set; }

    public EntityFrameworkUnitOfWork()
    {
        Context = new SomeContext();
    }

    public void Commit()
    {
        Context.SaveChanges();
    }

    public void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (Context != null)
            {
                Context.Dispose();
                Context = null;
            }
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

For example, the EntityFrameworkUnitOfWork would be constructor injected into a controller like this:

public class UserController : ApiController
{
    public UsersController(IUserRepository userRepository, IUnitOfWork unitOfWork)
    {
        // unitOfWork is a EntityFrameworkUnitOfWork
    }

    // ...
}

When the relevant MVC controller disposes, I need the Dispose() method to be called on the above EntityFrameworkUnitOfWork type, which in turn will dispose of the underlying DbContext.

Registering this type with Unity:

Container.RegisterType<IUnitOfWork, EntityFrameworkUnitOfWork>(
    new DisposingTransientLifetimeManager()
);

I am using the DisposingTransientLifetimeManager lifetime manager, as suggested in this article, thinking that it would automatically dispose of my IDisposable types. It seems that I still need to call on Container.Teardown(someInstance). This is not possible for me to do as the MVC Bootstrapper is handling all DI resolving.

Where and how can I perform the teardown of these initialised types?

It would be ideal to perform this teardown when the relevant MVC controller destructs, but perhaps this can also occur at the end of the HTTP request?

EDIT:

The IDisposables that are injected aren't necessarily accessible from the controller. For example, I could also inject a IUserService into a controller which itself (the IUserService class) is injected with an IUserRepository and an IUnitOfWork. I could chain Dispose methods from the IUserService to dispose of them, but this would requires changes to hundreds of controllers and services. Ideally I should be able to call container.Dispose() somewhere to have Unity dispose all injected disposables.

EDIT 2:

RaraituL brought something else to mind. IUnitOfwork does not implement IDisposable, only EntityFrameworkUnitOfWork does. This essentially means that the an MVC controller wouldn't be able to call on a dispose method as it only knows of IUnitOfWork. This is another reason why Unity should do this - it created the IDisposables so it should dispose of them too.

Was it helpful?

Solution

Sounds like you want a PerRequestTransientLifetimeManager. That will be something you will have to build. It's not hard and since you are using Unity 3 most of the work is already done for you.

public class PerRequestTransientLifetimeManager : ILifetimePolicy
{
    public object GetValue()
    {
        // will always create a new object (Transient)
        return null;
    }

    public void SetValue(object newValue)
    {
        // No point in saving to http context if not disposable
        if (newValue is IDisposable)
        {
            var perRequestLifetimeManager = new PerRequestLifetimeManager();
            perRequestLifetimeManager.SetValue(newValue);
        }
    }


    public void RemoveValue()
    {
        // can't remove since transient didn't keep a reference
    }
}

You'll need Unity.Mvc nuget package if the PerRequestLifetimeManager class is missing. You'll also need to register the UnityPerRequestHttpModule using Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule

I should point out from MS site

Although the PerRequestLifetimeManager lifetime manager works correctly and can help in working with stateful or thread-unsafe dependencies within the scope of an HTTP request, it is generally not a good idea to use it when it can be avoided, as it can often lead to bad practices or hard to find bugs in the end-user's application code when used incorrectly. It is recommended that the dependencies you register are stateless and if there is a need to share common state between several objects during the lifetime of an HTTP request, then you can have a stateless service that explicitly stores and retrieves this state using the Items collection of the Current object.

OTHER TIPS

You could use the UnityHierarchicalDependencyResolver in the same NuGet package you already reference (Unity.AspNet.WebApi). Then register your services you want disposed with the HierarchicalLifetimeManager. This dependency resolver creates and disposes a new child container on every Web Api request. When a Unity container is disposed, all built up objects in that container are also disposed.

IUnityContainer rootContainer = new UnityContainer();

GlobalConfiguration.Configuration.DependencyResolver =
    new UnityHierarchicalDependencyResolver(rootContainer);

rootContainer.RegisterType<IUnitOfWork, EntityFrameworkUnitOfWork>
    (new HierarchicalLifetimeManager());
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top