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.
Related
Working on an MVC application with the below architecture. Bootstrapped with Castle Windsor.
Controller -> Service -> Repository (uses DbContext).
Now certain flows in the application require that I run some part of the flow in a thread.
For example:
Controller -> service ->Repo1 -> control returns to service -> new
Thread() started-> Repo2
The issue I face is the dbcontext is disposed as it is declared as LifestylePerWebRequest().I have tried using LifestyleTransient() that didnt seem to work. What am I missing?
There are similar dependencies which i have to sometimes use in a separate thread and sometimes in a single request. How do i configure Windsor to handle these dependencies?
There is a nuget package that i use to extend the lifestyles for Castle Windsor and it is called: Castle.Windsor.Lifestyles.
It has hybrid lifestyles which are handy for web requests and threads.
container.Register
(
Classes.FromAssemblyContaining<IServiceFactory>()
.BasedOn<IServiceFactory>()
.WithServiceAllInterfaces()
.Configure(c => c.LifeStyle.HybridPerWebRequestPerThread())
);
The important functionality is HybridPerWebRequestPerThread() which creates a new instance for the initial web request and then for every new thread it will create a new instance.
In the new ASP.NET 5.0 (vNext), the startup code relies on the IApplicationBuilder interface. The Use method is used to add a handler to the builder, while Build is used to construct the final delegate. But I can't figure out what is the purpose of New. I've been digging in GitHub, but can't find any place where that's used.
Anyone understand what is the purpose of that method?
New() creates a second ApplicationBuilder, sharing all the ApplicationServices and ServerFeatures of the first one, but none of the middleware. It is used internally by the branching extensions (Map, MapWhen, UseWhen) to create the new 'branch'.
You can find the implementation here: ApplicationBuilder.cs.
In some cases, it is also useful in higher-level frameworks.
For exemple, the [MiddlewareFilter] attribute in MVC Core uses New() internally to execute a piece of ASP.NET Core middleware inside the MVC framework (i.e. as a filter). MVC Core creates a small pipeline around the middleware, builds it into a RequestDelegate, then runs the HttpContext through it. Just like ASP.NET Core does with your 'main' pipeline built in Startup.cs.
Thanks to this feature, we can reuse a piece of general-purpose ASP.NET Core middleware, from inside MVC.
For more information, see MiddlewareFilterBuilder.cs in ASP.NET MVC Core.
It appears to be there to branch [clone] the original instance (as can be demonstrated in src/Microsoft.AspNet.Http/Extensions/MapExtensions.cs). There was also a previous MapWhenExtensions.cs, but it appears to have been removed from the dev branch.)
I suspect it's an artifact of a previous design that would provide the ability to bind middleware based on circumstances without affecting the root's configuration. The fact that it's been there since before IBuilder was refactored to IApplicationBuilder and that most dependencies were in files that have since been removed from the dev branch, I would venture a guess that it's old news.
Of course it's hard to tell given neither the interface nor the base implementation are commented.
Using the Unity.Mvc3 with a Mvc 3 application, i could register my IDummyService as follows:
container.RegisterType<IDummyService, DummyService>(new HierarchicalLifetimeManager());
On each web request, a new instance of my IDummyService is created (as explained in this article), but since I upgraded Mvc 3 to Mvc 4 and hense Unity.Mvc3 to Unity.Mvc, an single instance is created and used across all web requests, untill restarting the app. Basically, IDummyService is a singleton in a Mvc 4 application when using HierarchicalLifetimeManager. For me this is hard to believe this is intended new behavior in Unity.Mvc.
Is there a better explanations for this?
Unity.Mvc3 and Unity.Mvc are created by two different organizations and have different implementations.
Unity.Mvc3 creates a child container per web request. This works well with the built-in HierarchicalLifetimeManager.
Unity.Mvc does not create a child container, but instead chose to create a new LifetimeManager called PerRequestLifetimeManager.
Please let me preface this by saying I am not very familiar with Unity. I understand it is an dependency injection container and I understand to a limited degree what that means. I inherited an application that uses Unity throughout although it does not seem to me to be implemented correctly. In session_start of the global.asa the previous developer uses the following code to instantiate the unity object then persists it through the entire session:
var unity = new UnityManager(new UnityContainer());
Session["UnityManager"] = unity;
As I understand it wouldn't this inherently cause concurrency issues? Can anyone provide an example of how to correctly implement unity or if this is correct explain to me why this is so?
If you're using mvc you could just remove the session and install unity.mvc3 from nuget package manager. It's compatible with mvc4 and sets it all up for you in a correct way. You can put the existing mappings in bootstrapper.cs (automatically installed)
Basically you want to have 1 static variable in the global.asax to access unity. So you can replace all those
var unitycontainer = Session["UnityManager"];
unitycontainer.resolve<>...
with
MVCApplication.Container.Resolve<> ..
My small Web API project (hosted via SelfHostHttpServer) has a few dependencies I want to inject into the controllers. In order to do this, I have implemented IDependencyResolver and called httpConfig.ServiceResolver.SetResolver.
This would work fine, except it seems I need to satisfy the internal dependencies the Web API requires. The first time I ran it, I saw that it needed to resolve the controller factory, so I added an instance of DefaultHttpControllerFactory to my container. Now every damn time I refresh the page, it crashes with the next unresolved dependency the framework is trying to resolve.
Am I going about this the wrong way, or am I really supposed to try and guess all of the default implementations and be forced through this crash-fix-refresh cycle of discovering what dependencies are required for the Web API framework to work correctly?
What your resolver is doing in case it can't resolve the dependency? The proper behaviour should be returning null. ASP.NET Web API DependencyResolver (httpConfig.ServiceResolver) is internally using two resolvers:
The one you set through SetResolver (user rosolver)
The built in DefaultServiceResolver
If user resolver returns null for dependency then Web API falls back to DefaultServiceResolver which can handle all built-in dependencies.