【问题标题】:Ninject-ing a dependency in Global.asax在 Global.asax 中注入依赖项
【发布时间】:2011-04-01 10:21:24
【问题描述】:

我正在使用 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,我猜单例实例在我的应用范围内不会那么单例。

我该怎么做?使用静态变量?

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 ninject ninject-extensions


    【解决方案1】:

    我们就是这样做的,我做了一些测试,我的 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;
                            }
                        }
                    }
                }
            }
    }
    

    希望对你有帮助!

    【讨论】:

    • 在每个请求中都调用 DependencyResolver 这不是一个扼杀事实吗?
    • 我不这么认为,@Remo 应该比我能告诉你更多,但由于我在构造函数的大部分控制器中注入了我的 _authService,它可能会做同样的事情并且不会“成本”那个笨蛋......
    • 太棒了。我认为这会在@Remo 解决问题之前完成。谢谢一百万。
    • 很高兴它有帮助,我的荣幸 :)
    【解决方案2】:

    默认情况下,MVC 扩展注入 HttpApplication。但是只能使用属性注入!所以只需添加一个用 Inject 属性装饰的属性。

    【讨论】:

    • 那也行不通。调用 MvcApplication_AuthenticateRequest 时 _auth 为空
    • @vtortola,您使用的是最新版本的 Ninject Mvc3 吗?该属性应如下所示: [Inject] public ItUserAuthentication Auth { get;放; }
    • 我得到了 "Ninject.Web.Mvc3-2.2.1.0-release-net-4.0.zip" ,我认为这是最后一个版本。我试过了,还是不行
    • @vtortola 我看了一下代码。随着 NuGet 包的引入,此功能已被破坏。由于我目前正在将 NuGet 包更新到 NuGet 1.2,因此我将在接下来的几天内解决此问题。
    • @B Z 将具有请求生命周期的对象注入具有更长生命周期的对象是没有意义的。一个对象应该只依赖于具有相同或更长生命周期的对象。
    【解决方案3】:

    将代码从构造函数移至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
    }
    

    【讨论】:

    • 不,它没有。我已经这样做了,当调用 MvcApplication_AuthenticateRequest 时,_auth 仍然为 null :(
    【解决方案4】:

    您可以使用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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-30
      • 2018-03-07
      • 1970-01-01
      • 2020-12-20
      • 2020-03-14
      • 2013-03-03
      • 2017-11-26
      • 1970-01-01
      相关资源
      最近更新 更多