我正在使用MVC3和Ninject启动Web应用程序。在Global.asax文件中还需要一个依赖项,它需要是一个单例。
我认为应该是这样的:
public class MvcApplication : NinjectHttpApplication
{
IUserAuthentication _auth;
public MvcApplication()
{
base.AuthenticateRequest += new EventHandler(MvcApplication_AuthenticateRequest);
}
protected override IKernel CreateKernel()
{
var _kernel = new StandardKernel(new SecurityModule());
_auth = _kernel.Get<IUserAuthentication>();
return _kernel;
}
void MvcApplication_AuthenticateRequest(object sender, EventArgs e)
{
_auth.ToString();
}
但是当我调用_auth
时,我看到MvcApplication_AuthenticateRequest
为空。
然后我试着这样:
public class MvcApplication : NinjectHttpApplication
{
ItUserAuthentication _auth;
IKernel _kernel;
public MvcApplication()
{
_kernel = new StandardKernel(new SecurityModule());
_auth = _kernel.Get<IUserAuthentication>();
base.AuthenticateRequest += new EventHandler(MvcApplication_AuthenticateRequest);
}
protected override IKernel CreateKernel()
{
return _kernel;
}
void MvcApplication_AuthenticateRequest(object sender, EventArgs e)
{
_auth.ToString();
}
但是现在我可以看到构造函数被多次调用,因此我将有几个IKernel,我想单例实例在我的应用范围内不会是单例。
我该怎么办?使用静态变量?
答案 0 :(得分:9)
我们这样做,我做了一些测试,我的AuthService似乎只进入他的控制器一次:
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;
}
}
}
}
}
}
希望它有所帮助!
答案 1 :(得分:5)
MVC扩展默认注入HttpApplication。但只能使用属性注入!所以只需添加一个用Inject属性修饰的属性。
答案 2 :(得分:-1)
将代码从构造函数移动到Application_Start
方法。我相信即使创建了多个HttpApplication实例,Application_Start也只调用一次,而且仅在第一个实例上调用。如果它已经解决了您的问题,请告诉我。
这些是您在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
}
答案 3 :(得分:-1)
您可以使用HttpApplication.Appliction属性吗?
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
}
}