2011-04-01 13 views
8

MVC3 ve Ninject ile bir web uygulaması başlatıyorum. Singleton olması gereken Global.asax dosyasında da ihtiyacım olan bir bağımlılık var.Global.asax'ta bağımlılık çıkarma

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(); 
    } 

Ama sonra MvcApplication_AuthenticateRequest çağrıldığında _auth boş olduğunu gördük:

Ben böyle olmalı düşündüm.

Sonra böyle çalıştı:

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(); 
    } 

Ama şimdi yapıcı birkaç kez çağrıldığı görebilirsiniz nedenle birkaç iKernel olacak ve ben tekil örnekleri o kadar tekil olmayacağını tahmin benim uygulama kapsamımda.

Nasıl yapmalıyım? Statik bir değişken mi kullanıyorsunuz?

cevap

8

Biz bazı test yaptım, böyle yaparız ve benim AuthService sadece bir kez onun denetleyicisi gitmek görünüyor:

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; 
         } 
        } 
       } 
      } 
     } 
} 

yardımcı olur Umut!

+0

, her istekte DependencyResolver çağrısı yapan bir gerçeği öldürmez. – vtortola

+0

Ben öyle düşünmüyorum, @Remo bana benden daha fazlasını anlatabiliyor olmalı, ancak denetleyicideki denetleyicimin çoğunda _authService enjekte ettiğimden muhtemelen aynı şeyi yapıyor ve "maliyet" değerine sahip ... – VinnyG

+0

harika. Ben bu konu düzeltmek kadar yapacak. Bir milyona teşekkürler. – vtortola

-1

Kodu kurucudan Application_Start yöntemine taşıyın. Birden çok HttpUygulaması örneği oluşturulmuş olsa bile, Application_Start yalnızca bir kez çağrılır ve bu yalnızca 1 örneğinde de geçerlidir. Sorunu çözdüyse bana bildirin.

Bu

potansiyel olarak Global.asax.cs sahip çeşitli olay işleyicileri şunlardır:

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 
} 
+0

Hayır öyle değil. Bunu yaptım ve ne zaman MvcApplication_AuthenticateRequest çağrı, _auth hala boş :( – vtortola

4

MVC uzantısı varsayılan olarak HttpApplication enjekte eder. Ancak sadece mülk enjeksiyonu kullanılabilir! Bu yüzden, Enjeksiyon özniteliği ile dekore edilmiş bir özellik ekleyin.

+0

Bu işe yaramıyor.MaxApplication_AuthenticateRequest – vtortola

+2

@ vtortola çağrıldığında _auth null, Ninject Mvc3 en son sürümünü kullanıyor musunuz? Bu gibi: [Inject] public ItUserAuthentication Auth {get; set;} – Talljoe

+0

"Ninject.Web.Mvc3-2.2.1.0-release-net-4.0.zip" aldım, bence bu son sürüm. işe yaramadı – vtortola

-1

HttpApplication.Appliction özelliğini mi kullanıyorsunuz?

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 
    } 
}