I've set up Unity for dependency injection for our project. The project itself is an ASP.NET application that uses both MVC and Web API.
For the database context, I'm using the PerRequestLifetimeManager
. This is done so that the different bits of business logic are using the same context (and thus the same transaction).
In order to be able to use the PerRequestLifetimeManager
, I've added references to the nuget packages Unity bootstrapper for ASP.NET MVC and Unity bootstrapper for ASP.NET Web API.
For use of this lifetime manager in Web API, the following line has been added to the startup code:
Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
The Unity container is set up for both MVC and Web API:
var container = BuildUnityContainer();
GlobalConfiguration.Configuration.DependencyResolver = new Microsoft.Practices.Unity.WebApi.UnityDependencyResolver(container);
System.Web.Mvc.DependencyResolver.SetResolver(new Microsoft.Practices.Unity.Mvc.UnityDependencyResolver(container));
In building the Unity container, the database context is set up to be resolved per request in the following way:
container.RegisterType<IDataContext>(new PerRequestLifetimeManager(),
new InjectionFactory(c =>
{
// Some code
return new DataContext(/* params */);
}
));
However, it seems that this code is not giving me a new DataContext
for each request. It is giving me the same context in different places within a single request (which is fine). However, subsequent (web api) requests are being given the same instance of DataContext
where I would expect a new one to be created for each new request. I also would expect the DataContext
to be properly disposed of after the request is finished (the class implements IDisposable
).
What's going on here? Am I missing a bit of configuration to make this work properly? Or isn't this supposed to work the way I expect it to?
The problem turned out to be that the UnityDependencyResolver
was caching the resolved items over several requests. I had to change it to the UnityHierarchicalDependencyResolver
and then it started resolving my items properly according to the associated LifetimeManager
. The problem initially became more confusing when it appeared that even when using a TransientLifetimeManager
, it would still return the same instance.
I found the answer in a different (yet somewhat related) question: using a Handler in Web API and having Unity resolve per request
So all I did was change
GlobalConfiguration.Configuration.DependencyResolver = new Microsoft.Practices.Unity.WebApi.UnityDependencyResolver(container);
to
GlobalConfiguration.Configuration.DependencyResolver = new Microsoft.Practices.Unity.WebApi.UnityHierarchicalDependencyResolver(container);
and all my problems were solved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With