I\'m starting a web application with MVC3 and Ninject. There is one dependency that I also need in the Global.asax file that needs to be a singleton.
I thought it sh
Can you use the HttpApplication.Appliction property?
public class MyHttpApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
this.Application["auth"] = GetAuthFromContainer();
}
protected void Application_AuthenticateRequest()
{
IUserAuthentication auth = (IUserAuthentication)this.Application["auth"];
// auth != null
}
}
Move the code from the constructor to Application_Start
method. I believe even if multiple HttpApplication instances are created, Application_Start is called only once, and that too on the 1st instance only. Let me know if it has solved your problem.
These are the various event handlers you can potentially have in your Global.asax.cs :
public class Global : System.Web.HttpApplication
{
public Global()
{
InitializeComponent();
}
protected void Application_Start(Object sender, EventArgs e)
{
}
protected void Session_Start(Object sender, EventArgs e)
{
}
protected void Application_BeginRequest(Object sender, EventArgs e)
{
}
protected void Application_EndRequest(Object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
}
protected void Application_Error(Object sender, EventArgs e)
{
}
protected void Session_End(Object sender, EventArgs e)
{
}
protected void Application_End(Object sender, EventArgs e)
{
}
#region Web Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
}
#endregion
}
The MVC extension injects the HttpApplication by default. But only property injection can be used! So just add a property decorated with the Inject attribute.
This is how we do it, I did some testing and my AuthService seems to go in his controller only once :
public class MvcApplication : NinjectHttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected override IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
kernel.Bind<ISession>().To<MongoSession>().InRequestScope();
kernel.Bind<IAuthenticationService>().To<AuthenticationService>().InSingletonScope();
kernel.Bind<IMailer>().To<Mailer>().InRequestScope();
kernel.Bind<IFileProvider>().To<MongoFileProvider>().InRequestScope();
return kernel;
}
protected override void OnApplicationStarted()
{
base.OnApplicationStarted();
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
if (HttpContext.Current.User != null)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
if (HttpContext.Current.User.Identity is FormsIdentity)
{
var id = (FormsIdentity) HttpContext.Current.User.Identity;
var ticket = id.Ticket;
var authToken = ticket.UserData;
var authService = (IAuthenticationService)DependencyResolver.Current.GetService(typeof(IAuthenticationService));
var user = authService.GetUserForAuthToken(authToken);
if (user != null)
{
user.SetIdentity(HttpContext.Current.User.Identity);
HttpContext.Current.User = (IPrincipal) user;
}
}
}
}
}
}
Hope it helps!