Ninject-ing Global.asax 中的依赖项

发布于 2024-10-29 04:50:49 字数 1437 浏览 1 评论 0原文

我正在使用 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();
    }

但后来我看到调用 MvcApplication_AuthenticateRequest_auth 为 null。

然后我尝试这样:

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,并且我想单例实例在我的应用程序范围内不会那么单例。

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

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 should be like this:

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

But then I saw that _auth is null when MvcApplication_AuthenticateRequest is called.

Then I tried like this:

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

But now I can see that the constructor is being called several times, therefore I will have several IKernel, and I guess that singleton instances won't be so singleton in my app scope.

How should I do it? Using a static variable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

_失温 2024-11-05 04:50:49

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

希望它有帮助!

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!

っ左 2024-11-05 04:50:49

MVC 扩展默认注入 HttpApplication。但只能使用属性注入!因此只需添加一个用 Inject 属性修饰的属性即可。

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.

各自安好 2024-11-05 04:50:49

当您初始化 IOC 时,在 ASP.NET MVC 中,如果您设置依赖解析器,例如使用 Simple Injector:

DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));

那么在 global.asax 中,您可以只使用 DependencyResolver 来获取服务,例如

var penTestService = DependencyResolver.Current.GetService<IPenTestService>();

When you initialise IOC, in ASP.NET MVC if you set the dependency resolver, for example with Simple Injector:

DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));

Then in global.asax you can just use the DependencyResolver to get the service, e.g.

var penTestService = DependencyResolver.Current.GetService<IPenTestService>();
回忆追雨的时光 2024-11-05 04:50:49

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

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
}
仄言 2024-11-05 04:50:49

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

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
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文