OnApplicationStarted not firing, kernel never gets created

593 views
Skip to first unread message

Geoff

unread,
Oct 22, 2011, 4:17:41 PM10/22/11
to ninject
When I derive from NinjectHttpApplication and override
OnApplicationStarted, it never seems to fire. Application_Start was
firing before when inheriting from HttpApplication. I can override
Init and it will fire but not OnApplicationStarted. So in my
Application_AuthenticateRequest method where I try to get a type from
Ninject it will always be null because the kernel was never created.

I can avoid using NinjectHttpApplication and write code to always
check to ensure the kernel is created but I wanted to try to do this
the "standard way". I've restarted IIS but I cannot figure out why it
does not fire.

I am using IIS 7.5 and running from Visual Studio. Project is .net 4
ASP.NET MVC. Using 2.2.0.0 version of Ninject.

My app class is below. Any ideas? Thanks

public class MvcApplication : NinjectHttpApplication
{
private static bool AppStarted { get; set; }

private void PerformAppStartup()
{
if (AppStarted) return;
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
AppStarted = true;
}

// never seems to fire:
// http://stackoverflow.com/questions/2247533/how-do-i-get-ninject-2-0-working-with-asp-net-mvc-2
protected override void OnApplicationStarted()
{
base.OnApplicationStarted();
if (!AppStarted) PerformAppStartup();
}

protected override IKernel CreateKernel()
{
var kernel = KernelFactory.Create();
kernel.Load(new WebAppModule());
return kernel;
}

private static void
RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}

private 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 void Application_AuthenticateRequest(Object sender,
EventArgs e)
{
var user = IoC.TryGet<IAppPrincipal>();
if (null == user) return;

var context = IoC.Get<HttpContextBase>();
context.User = user;

// Make sure the principals are in sync
Thread.CurrentPrincipal = context.User;
}

Geoff

unread,
Oct 22, 2011, 4:35:42 PM10/22/11
to ninject
Actually I just realized part of the problem, my IoC class is using
it's own kernel. I'm still not sure why OnApplicationStarted is not
firing, at least not via debugger. I'm also a bit unsure as to how to
get something from the kernel when it is in the global.asax.cs itself
(presumably I cannot use ctor injection there). I tried the below but
it didn't work:

[DepInject]
public IAppPrincipal Principal { get; set; }

Error activating IAppPrincipal using binding from IAppPrincipal to
method
Provider returned null.
Activation path:
2) Injection of dependency IAppPrincipal into property Principal of
type MvcApplication
1) Request for global_asax

Suggestions:
1) Ensure that the provider handles creation requests properly.


My WebAppModule looks like the below BTW:

internal class WebAppModule : NinjectModule
{
public override void Load()
{
BindSecurityTypes();
}

private void BindSecurityTypes()
{
Bind<IPrincipal>().ToMethod(delegate
{
return HttpContext.Current.User;
});

Bind<IAppPrincipal>().ToMethod(delegate
{
IAppPrincipal prin = null;

var user = HttpContext.Current.User;
// if user is null it means we have not yet got to the
point of the app having the
// session and user identity setup so we bail as we
need WindowsIdentity
// WindowsIdentity.GetCurrent() won't help as it will
be the IIS user
if (null == user)
return null;

EnsureThat.ValueIsNotNull(user.Identity,
"user.Identity");
EnsureThat.StringIsSet(user.Identity.Name,
"user.Identity.Name");
var winUser = user.Identity as WindowsIdentity;
EnsureThat.ValueIsNotNull(winUser, "winUser");
prin = new AppPrincipal(winUser);
return prin;
}).InRequestScope();
}
}

On Oct 22, 4:17 pm, Geoff <thnk...@gmail.com> wrote:
> When I derive from NinjectHttpApplication and override
> OnApplicationStarted, it never seems to fire. Application_Start was
> firing before when inheriting from HttpApplication. I can override
> Init and it will fire but not OnApplicationStarted. So in my
> Application_AuthenticateRequest method where I try to get a type from
> Ninject it will always be null because the kernel was never created.
>
> I can avoid using NinjectHttpApplication and write code to always
> check to ensure the kernel is created but I wanted to try to do this
> the "standard way". I've restarted IIS but I cannot figure out why it
> does not fire.
>
> I am using IIS 7.5 and running from Visual Studio. Project is .net 4
> ASP.NET MVC. Using 2.2.0.0 version of Ninject.
>
> My app class is below. Any ideas? Thanks
>
>  public class MvcApplication : NinjectHttpApplication
>     {
>         private static bool AppStarted { get; set; }
>
>         private void PerformAppStartup()
>         {
>             if (AppStarted) return;
>             AreaRegistration.RegisterAllAreas();
>             RegisterGlobalFilters(GlobalFilters.Filters);
>             RegisterRoutes(RouteTable.Routes);
>             AppStarted = true;
>         }
>
>         // never seems to fire:
>         //http://stackoverflow.com/questions/2247533/how-do-i-get-ninject-2-0-w...

Remo Gloor

unread,
Oct 23, 2011, 8:57:57 AM10/23/11
to nin...@googlegroups.com
It seems that either the binding of IAppPrincipal is missing or your own kernel implementation is incorrect. In case an exception occurs before OnApplicationStarted is called (e.g. the Activation exception for IAppPrincipal) this is the reason why it is not called.

--
You received this message because you are subscribed to the Google Groups "ninject" group.
To post to this group, send email to nin...@googlegroups.com.
To unsubscribe from this group, send email to ninject+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/ninject?hl=en.

Geoff

unread,
Oct 24, 2011, 9:43:28 AM10/24/11
to ninject
IAppPrincipal was bound to in the BindSecurityTypes method of
WebAppModule that was loaded.

As for app start not firing in the debugger I think this is the issue:
http://stackoverflow.com/questions/641148/application-start-not-firing

For now I ended up changing to the below which works. Can clean up
later.

Global:

[DepInject(Comment = "Needs to be at least internal")]
internal IAuthenticator Authenticator { get; set; }

[UsedImplicitly]
protected void Application_AuthenticateRequest(Object sender,
EventArgs e)
{
var auth = this.Authenticator;

if (null != auth)
auth.Authenticate();
}

Web App Module:

internal class WebAppModule : NinjectModule
{
public override void Load()
{
Bind<IAuthenticator>().To<HttpAuthenticator>();
}
}

[UsedImplicitly]
internal class HttpAuthenticator : IAuthenticator
{
public void Authenticate()
{
var user = HttpContext.Current.User;
// can be null early on in the process
if (null == user) return;

var winUser = user.Identity as WindowsIdentity;
var prin = new AppPrincipal(winUser);
HttpContext.Current.User = prin;
// Make sure we are in sync
Thread.CurrentPrincipal = prin;
}
}

KernelFactory that CreateKernel() uses:

internal static class KernelFactory
{
public static IKernel Create()
{
var settings = new NinjectSettings
{
InjectAttribute =
typeof(DepInjectAttribute),
InjectNonPublic = true
};

var kernel = new StandardKernel(settings);
return kernel;
Reply all
Reply to author
Forward
0 new messages