I am using Asp.Net MVC and NHibernate.
Some of my Global.asax file is shown below:
public override void Init()
{
base.Init();
// The WebSessionStorage must be created during the Init() to tie in HttpApplication events
webSessionStorage = new WebSessionStorage(this);
}
/// <summary>
/// Due to issues on IIS7, the NHibernate initialization cannot reside in Init() but
/// must only be called once. Consequently, we invoke a thread-safe singleton class to
/// ensure it's only initialized once.
/// </summary>
protected void Application_BeginRequest(object sender, EventArgs e)
{
//the following code sets up the NHibernate Session Factory
NHibernateInitializer.Instance().InitializeNHibernateOnce(
() => InitializeNHibernateSession());
}
Whenever the AppPool recycles the next request is taking a while to execute due to it having to wait for the NHibernateSessionFactory to initialise. After that everything is fine until the next app pool recycle.
Now I'd like to move the initialization into the Application_Start method, so that when the pool recycles, the restart does the heavy lifting PRIOR to the next request coming in. However the comment "Due to issues on IIS7" which comes from S#arp architecture made me realise it's not that simple.
I did find an article: http://scottsdalewebstudio.com/blog/mvc/mvc-sharp-iis7-nhibernate/ which suggests that setting IIS to use "Classic Mode" fixes it - is this the only way?
Related
I use Unity in an MVC5 project (.net461) for DI and I want to register a service with multiple lifetimes.
With the classic core DI I would use RegisterScoped and that's it. Whenever the service is resolved within an Http Request I would reuse the same instance for the duration of the request. If I want to fire a background task, that background task should open a service scope, and I would resolve a new instance for the service for the duration of that scope. No need to have different registrations for the service. In the first case, the scope is created by the runtime, and in the second it is manually created by the developer. In both cases, the service provider only knows that the service is scoped, it doesn't care about where and how the scope has opened.
With Unity the first case is solved with PerRequestLifetimeManager. The second case is solved with a HierarchicalLifetimeManager.
But how should I have a combination of the two?
Whenever a service is resolved within an HttpRequest (in a controller constructor for instace) it should use the PerRequestLifetimeManager and wherever it is resolved in a child container (within the constructor of another service that is instantiated in the child container) it should use HierarchicalLifetimeManager.
How can I register the service with both managers?
At the end of the day, I had to implement my own solution which is based on (but not using) Unity.Mvc, Unity.WebApi packages, and the HierarchicalLifetimeManager.
None of the solutions I found online worked for my case. Most of them covered only the per request part, but not the per custom user scope part.
The key of the solution is not the lifetime manager but the dependency resolver. The lifetime manager for my requirements should always be HierarchicalLifetimeManager because that is what I truly need. A new container for each scope, which is covered by child containers and HierarchicalLifetimeManager.
Using Integrating ASP.NET Core Dependency Injection in MVC 4 as an example on how to implement your own dependency resolver, I came up with the solution below.
What I had to do, is to make sure a new scope is created on the beginning of the Http Request, and Disposed at the end of the Http Request. This part is covered by implementing a simple HttpModule. This part is similar to the HttpModule used by the official Unity Per Request Lifetime implementation.
Per Http Request Module
This is the module implementation
internal class UnityPerHttpRequestModule : IHttpModule
{
private static IUnityContainer _rootContainer;
public void Init(HttpApplication context)
{
context.BeginRequest += (s, e) =>
((HttpApplication)s).Context.Items[typeof(UnityPerHttpRequestModule)]
= _rootContainer.CreateChildContainer();
context.EndRequest += (s, e) =>
(((HttpApplication)s).Context.Items[typeof(UnityPerHttpRequestModule)]
as IUnityContainer)?.Dispose();
}
public static void SetRootContainer(IUnityContainer rootContainer)
{
_rootContainer = rootContainer ?? throw new ArgumentNullException(nameof(rootContainer));
}
public void Dispose() { }
}
On Beginning the request we create a new child container and place it in the HttpRequest Items dictionary.
On Ending the request we retrieve the child container from the Items dictionary and dispose it.
The static method SetRootContainer should be called once at the startup of the application to pass in the initial root Unity container, the one that services are registered on.
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
UnityPerHttpRequestModule.SetRootContainer(UnityConfig.Container); // pass here the root container instance
...
}
}
We also need to register the module with owin.
using Microsoft.Owin;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Owin;
[assembly: OwinStartup(typeof(MyApp.Startup))]
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(MyApp.Startup), nameof(MyApp.Startup.InitScopedServicesModule))]
namespace MyApp
{
public partial class Startup
{
public static void InitScopedServicesModule()
{
DynamicModuleUtility.RegisterModule(typeof(UnityPerHttpRequestModule));
}
public void Configuration(IAppBuilder app)
{
}
}
}
MVC Dependency Resolver
Now the http module is registered and we have a new scope created on each request. Now we need to instruct MVC and WebApi to use that scope. For this, we need to create the appropriate dependency resolvers. I created one dependency resolver for MVC and one for WebApi since they need to implement different interfaces (I could have implemented both in the same class though).
The dependency resolver for MVC is this:
internal class UnityMvcPerHttpRequestDependencyResolver : IDependencyResolver
{
private readonly IUnityContainer rootContainer;
internal UnityMvcPerHttpRequestDependencyResolver(IUnityContainer rootContainer)
{
this.rootContainer = rootContainer;
}
internal IUnityContainer Current => (HttpContext.Current?.Items[typeof(UnityPerHttpRequestModule)] as IUnityContainer) ?? this.rootContainer;
public void Dispose() { }
public object GetService(Type serviceType)
{
try
{
return Current.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return Current.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
}
What the resolver does is that it checks for an HTTP Context and gets the unity container in the Context's item dictionary and uses this container to resolve the services. So effectively, if the service requested is registered with a Hierarchical Lifetime, a new instance of that service will be created within the child container (aka within the context of the request). Since the child container is disposed at the end of the request by the http module, any services instantiated in the child container are also disposed.
Things to notice here:
The IDependencyResolver interface here is the System.Web.Mvc.IDependencyResolver. This is the interface expected by the MVC. The WebApi expects a difference IDependencyResolver (same name, different namespaces)
Catching ResolutionFailedException. If you don't catch those exceptions, the application will crash.
Now that we have the MVC dependecy resolver, we need to instruct MVC to use this resolver.
public static class UnityMvcActivator
{
public static void Start()
{
FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(UnityConfig.Container));
//DependencyResolver.SetResolver(new UnityDependencyResolver(UnityConfig.Container));
DependencyResolver.SetResolver(new UnityMvcPerHttpRequestDependencyResolver(UnityConfig.Container));
// TODO: Uncomment if you want to use PerRequestLifetimeManager
//Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}
}
Things to notice here:
Do not register the official UnityPerRequestHttpModule since we implement our own. ( I could probably use that module but my implementation would depend on the inner implementation of the official module and I don't want that, since it may change later)
Web Api Dependency Resolver
Simlilar to MVC dependency resolver, we need to implement one for the Web Api
internal class UnityWebApiPerHttpRequestDependencyResolver : IDependencyResolver
{
private readonly IUnityContainer rootContainer;
internal UnityWebApiPerHttpRequestDependencyResolver(IUnityContainer rootContainer)
{
this.rootContainer = rootContainer;
}
internal IUnityContainer Current => (HttpContext.Current?.Items[typeof(UnityPerHttpRequestModule)] as IUnityContainer) ?? this.rootContainer;
public IDependencyScope BeginScope() => this;
// Dispose, GetService and GetServices are the same as MVC dependency resolver
}
Things to notice here:
IDependencyResolver here is of type System.Web.Http.Dependencies.IDependencyResolver. It is not the same as MVC's IDependencyResolver.
This Dependency resolver interface implements one more method: BeginScope. This is important here. WebApi pipeline is different that MVC pipeline. WebApi engine, by default, calls BeginScope to open a new scope for each web api request, and uses that scope to resolve controllers and services. So, Web api has already a scoped mechanism. BUT we have already created a scope ourselves with our per request module and we want to use that scope. So what we have to do here is to not create a new scope again. It already exists. So calling BeginScope on our resolver should return the same resolver scope, thus we return this.
Now that we have created the WebApi resolver, we have to also register it to web api.
using System.Web.Http;
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(MyApp.UnityWebApiActivator), nameof(MyApp.UnityWebApiActivator.Start))]
namespace MyApp
{
/// <summary>
/// Provides the bootstrapping for integrating Unity with WebApi when it is hosted in ASP.NET.
/// </summary>
public static class UnityWebApiActivator
{
/// <summary>
/// Integrates Unity when the application starts.
/// </summary>
public static void Start()
{
// Use UnityHierarchicalDependencyResolver if you want to use
// a new child container for each IHttpController resolution.
// var resolver = new UnityHierarchicalDependencyResolver(UnityConfig.Container);
var resolver = new UnityWebApiPerHttpRequestDependencyResolver(UnityConfig.Container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
}
}
Registering services
Now that we have set up and registered all our Resolvers and modules, the last thing to do is to remember to register each scoped service with HierarchicalLifetimeManager. Since our scoped solution depends on child containers, registering our scoped services that way will suffice.
Conclusion
And with that, I managed to implement a working scoped DI solution with Unity. The example below did not work with the official Per Request Lifetime solution, but worked with my custom implementation.
class TestController{
private readonly IMyScopedService service;
private readonly IUnityContainer container;
public TestController(IUnityContainer container, IMyScopedService service){
this.service = service;
this.container = container;
}
public ActionResult Post( ... ){
var childContainer = this.container.CreateChildContainer();
var scopedService = childContainer.GetService<IMyScopedService>()
HostingEnviroment.QueueBackgroundWorkItem(() => {
using(childContainer){
scopedService.DoWork();
}
});
}
}
With the official PerRequestLifetimeManager solution, this.service and scopedService were the same instance. The scoped service was instantiated in the http context, then the same instance was fetched again from the child container (since it was registerd with PerRequestLifetimeManager and not HierarchicalLifetimeManager) and passed to the background Job. The background job outlives the http request. The instance is disposed when the Http requests ends, but it is still being used in the background job which probably runs in another thread. Concurrency issues (and more) arise. For instance you can't use the same instance of an EF DbContext in multiple threads.
With the custom implementation above, the example works. scopedService is a different instance since it is registered with a HierarchicalLifetimeManager. this.services is disposed when the http request ends but scopedService lives during the whole execution of the background Job.
What we effectively do is control the lifetime of the services by controlling the lifetime of child containers. And I have the impression that this is the solution for every scoped service scenario.
Register all scoped services with HierarchicalLifetimeManager
Control the lifetime of services by controlling the lifetime of the child containers.
I recently added MEF to an MVC/WebAPI application using a variety of resources including this SO answer How to integrate MEF with ASP.NET MVC 4 and ASP.NET Web API. While this worked for a time, I started to receive intermittent errors related to making connections to the database, the most frequent one being: "System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached."
I realized I was leaking connections but didn't understand why. All of my repositories implemented IDisposable and disposed of their connections when done. Putting breakpoints in my dispose methods quickly revealed that they were never being hit. When I based my code off of the example linked to above, I noticed the lack of any cleanup, but being new to MEF and MVC I wrongly assumed that cleanup was being done somewhere in MVC's/MEF's dependency pipeline.
I'm wondering how other people have tackled using MEF to properly scope composition on a per request basis in both MVC and WebAPI?
I have found vague guidance here and there and it's all geared toward either MVC or WebAPI. Mef.codeplex has an almost complete MVC centric solution here: https://mef.codeplex.com/releases/view/79090 but it's based off of a preview version of MVC. I found a WebAPI solution here: https://github.com/WebApiContrib/WebApiContrib.IoC.Mef. I'm rolling my own solution at the moment but as I hate to reinvent the wheel, I thought I'd ask to see if anyone knew of one rolling around already.
I ended up tackling this problem myself over the holidays after not finding anything to my satisfaction. MEF contrib on CodePlex had a good start but it was unfinished. I incorporated it with a few modification and combined that with some research and trial and error.
I've created a project on Github (link below, I know external links are frowned upon but it's just too much code to include inline). In it are four projects. The first provides core composition and teardown, the two libraries put the core into the context of MVC and WebAPI respectively, and the last is just a quick sample MVC app with two controllers that each depend on another class which is injected. One caveat, I consider the WebAPI project unfinished as it doesn't yet include facilities for WebAPI filter providers (and maybe other things I haven't thought of or needed yet).
I hope this helps.
https://github.com/rlvandaveer/Heliar-Web-Composition
Wow thanks. I also had a go at resolving this, Though much simpler approach I have confirmed a dramatic reduction in memory use. I created a MefDependencyResolver Which in the BeginScope method instead of returning 'this' as we have seen in other examples, I create a child container based on a filtered catalog as shown in the mef codplex site http://mef.codeplex.com/wikipage?title=Filtering%20Catalogs&referringTitle=Parts%20Lifetime.
My WebAPI test project uses entity framework code first to store entities in a DB.
I created a test client to POST 15000 entities into the database, in each test I ran 3 concurrent clients, repeating the test 3 times. With begin scope returning 'this' and a NOOP in the Dispose method I maxed out the memory allocated for the ApplicationPool. By returning a new container based on a filtered catalogue and disposing the container in the Dispose method and repeating the test Memory increased to 600MB and stayed there IIS remain happy and no pool recycling occurred.
public class MefDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver, System.Web.Mvc.IDependencyResolver
{
protected CompositionContainer _container;
public MefDependencyResolver(CompositionContainer container)
{
_container = container;
}
public IDependencyScope BeginScope()
{
var filteredCat = new FilteredCatalog(_container.Catalog,
def => def.Metadata.ContainsKey(CompositionConstants.PartCreationPolicyMetadataName) &&
((CreationPolicy)def.Metadata[CompositionConstants.PartCreationPolicyMetadataName]) == CreationPolicy.NonShared);
var child = new CompositionContainer(filteredCat, _container);
return new MefDependencyResolver(child);
}
/// <summary>
/// Called to request a service implementation.
///
/// Here we call upon MEF to instantiate implementations of dependencies.
/// </summary>
/// <param name="serviceType">Type of service requested.</param>
/// <returns>Service implementation or null.</returns>
public object GetService(Type serviceType)
{
if (serviceType == null)
throw new ArgumentNullException("serviceType");
var name = AttributedModelServices.GetContractName(serviceType);
var export = _container.GetExportedValueOrDefault<object>(name);
if (export != null)
{
Trace.WriteLine("PAUSE");
}
return export;
}
/// <summary>
/// Called to request service implementations.
///
/// Here we call upon MEF to instantiate implementations of dependencies.
/// </summary>
/// <param name="serviceType">Type of service requested.</param>
/// <returns>Service implementations.</returns>
public IEnumerable<object> GetServices(Type serviceType)
{
if (serviceType == null)
throw new ArgumentNullException("serviceType");
var exports = _container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType));
return exports;
}
#region IDisposable
private bool _disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing) // Managed:
{
//NOOP since MEF does not have the idea of a Scoped Container (except it does have a concept of a filtered container!)
//
Trace.WriteLine("DISPOSING MEF CONTAINER.");
this._container.Dispose();
this._container = null;
}
// Unmanaged:
_disposed = true;
}
}
~MefDependencyResolver()
{
Dispose(false);
}
#endregion
}
In ASP.NET MVC3, I can't seem to override a session timeout. I have set breakpoints at all the relevant server-side code points I can think of (controller actions and methods in globax.ax.cs) but nothing seems to get hit on session timeout.
I even applied an attribute as suggested here: (http://www.tyronedavisjr.com/2008/11/23/detecting-session-timeouts-using-a-aspnet-mvc-action-filter/) but even it was not hit when the session timed out. Surely the timeout must be session-side, but where?
Does anyone know what exactly happens when an ASP.NET MVC application has a session timeout?
What sessionState mode are you using? (<sessionState mode=" ... "> in web.config)
You should be able to add the following method to your Global.asax.cs to override the default Session_End behaviour:
protected void Session_OnEnd(object sender, EventArgs e)
{
// insert code here
}
Things to bear in mind:
The Session_OnEnd / Session_End event will only be called if the HttpSessionState.Mode property value is InProc (this is the default, so if you've not changed it in the web.config this should be fine). If you've changed it to StateServer or SQLServer, then the Session_OnEnd event in the Global.asax file is ignored.
The Session_OnEnd / Session_End event is called by the application when it abandons the session - not when you close the browser. You can manually trigger it by calling Session.Abandon
Typically, session timeouts can be handled in the Session_End event in your Global.asax
void Session_End(object sender, EventArgs e) {
// perform last minute procedures before session ends
}
According to the MSDN, the HttpSessionState.Timeout property has a setter and can be changed from within your application's code as well as permanently in the web.config
First of all, sorry for my bad english.
I have faced a strange problem using asp net mvc.
I have simple controller, which can execute 2 operations. The first operation is continuous and can take a several minutes. And the other is short, and executed some seconds.
Something like this:
public class TestController : Controler {
[HttpPost]
public string Func1(long id) {
// continuous operation
return new ValueGetter().Get(id)
}
[HttpPost]
public string Func2(long id) {
return "Abc";
}
}
And from the client side i call thouse methods via jqueries post:
$.post(url).sucess(...);
The problem consists in the next: while the first operation is executed, the second operation will wait, until first is finished.
I tried to use AsyncController as described there http://msdn.microsoft.com/en-us/library/ee728598.aspx, but the result is the same...
I have logged some application events in global.asax:
protected void Application_PostMapRequestHandler(object sender, EventArgs e) {
LoggerManager.Info("PostMapRequestHandler fired in global.asax");
}
protected void Application_AcquireRequestState(object sender, EventArgs e) {
LoggerManager.Info("AcquireRequestState fired in global.asax");
}
And if I for example, call the first method once, and then Immediately call the second method three times, I have the following result in the log file:
1.PostMapRequestHandler
2.AcquireRequestState
3.PostMapRequestHandler
4.PostMapRequestHandler
5.PostMapRequestHandler
... after first method is executed sucessfuly
6.AcquireRequestState
7.AcquireRequestState
8.AcquireRequestState
I use IIS 7(not express) and asp.net mvc 3
Why it happen and how I can solve it?
I found the answer to my question here:
Session less MVC Controller for MVC 2 / RC (MSDN Blogs)
I hope it will help, if someone faces a similar problem.
I had my NHibernate session management setup like follows:
protected MvcApplication()
{
BeginRequest += delegate
{
NHibernateSessionManager.Instance.OpenSession();
};
EndRequest += delegate
{
NHibernateSessionManager.Instance.CloseSession();
};
}
And for when I needed to save to the database, I made an ActionFilterAttribute that looked like this:
public class TransactionAttribute: ActionFilterAttribute
{
private ITransaction _currentTransaction;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
_currentTransaction = NHibernateSessionManager.Instance.CurrentSession.Transaction;
_currentTransaction.Begin();
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (_currentTransaction.IsActive)
{
if (filterContext.Exception == null)
_currentTransaction.Commit();
else
{
_currentTransaction.Rollback();
}
}
_currentTransaction.Dispose();
}
}
and then I could just add [Transaction] to my action method. This seemed to work in initial testing, but I then I tried using at HttpWebRequest to call an action method from another app multiple times and I had issues. Testing with Fiddler I setup a POST request and then fired them off in quick succession and it showed up the following:
THe red ones are various errors that I believe is to do with threading.
My NHibernateSessionManager uses the HTtpContext to store the session like this:
public ISession CurrentSession
{
get { return (ISession)HttpContext.Current.Items["current.session"]; }
set { HttpContext.Current.Items["current.session"] = value; }
}
So, to fixed it, I moved my Transaction code into my BeginRequest and EndRequest methods - and then I could fire off heaps in succession.
My question is - why did this fix it? I would have thought that I would have had something similar to this:
Begin Request - opens session
OnActionExecuting - starts transaction
action code
OnActionExecuted - commits transaction
End Request - closes session
and that this would be unique to each request, so it shouldn't interfere with one another, because there should be a different HttpContext for each request shouldn't there? Or are they shared or something??
Can someone enlighten me?
Quote from the release notes of ASP.NET MVC 3:
In previous versions of ASP.NET MVC,
action filters were created per
request except in a few cases. This
behavior was never a guaranteed
behavior but merely an implementation
detail and the contract for filters
was to consider them stateless. In
ASP.NET MVC 3, filters are cached more
aggressively. Therefore, any custom
action filters which improperly store
instance state might be broken.
This basically means that the _currentTransaction instance you have in your action filter might not be what you think it is. So be careful how/when is this property injected => it is not clear from the code you have shown.