Ninject and static classes - how to?

11,868

Solution 1

Don't do it. Don't use a static class that needs dependencies of its own. This makes testing harder and other types that depend on this AuthenticationHelper won't be able to include it in their constructor which means they hide the fact that they depend on it.

Instead just do what you would always do: make AuthenticationHelper non-static, implement an IAuthenticationHelper interface on it and inject all dependencies through its public constructor.

But if you insist into keeping that class static (which again is a really bad idea), create a static Initialize(UserBusiness userBusiness) method on it, and call this method in the start-up path of your application. You can't let your DI container call this static method. They don't allow because 1. it's a bad idea, and 2. such static method only has to be called once, so letting your container auto-wire this for you doesn't really help.

Solution 2

As a side note, the lock is completely useless since you are locking access to a local variable "user" which will not change between the 2 "if (user == null)" lines.

Your intention is to lock access to the Context.Session[CURRENT_USER] element, so ..

            User user = (User)Context.Session[SessionKeys.CURRENT_USER];

            if (user == null)
            {
                lock (_lock)
                {
                    user = (User)Context.Session[SessionKeys.CURRENT_USER];
                    if (user == null)
                    {
                        user = _userBusiness.Find(CurrentUserId);
                        Context.Session[SessionKeys.CURRENT_USER] = user;
                    }
                }
            }
Share:
11,868
Phillippe Santana
Author by

Phillippe Santana

I help entrepreneurs succeed in their startups, bringing to life projects that solve people’s problems and change the world for the better. I’m co-founder at Ideia no Ar - Marketplace Platform, a project manager for work, programmer by education and entrepreneur by heart!

Updated on June 04, 2022

Comments

  • Phillippe Santana
    Phillippe Santana almost 2 years

    I have a static class and I need to inject some instances into it. A static class can have a static constructor but it must be parameterless. So, how am I supposed to inject something into it?

    I do not wish to create a singleton. I wish to have a static class, and one of its methods operate on an instance that should be injected. Below is an example of the sort of thing I need:

    public static class AuthenticationHelper
    {
        // Fields.
        private static object _lock = new object();
        private static readonly UserBusiness _userBusiness; // <-- this field needs to be injected.
    
        // Public properties.
        public static User CurrentUser
        {
            get
            {
                if (IsAuthenticated)
                {
                    User user = (User)Context.Session[SessionKeys.CURRENT_USER];
    
                    if (user == null)
                    {
                        lock (_lock)
                        {
                            if (user == null)
                            {
                                user = _userBusiness.Find(CurrentUserId);
                                Context.Session[SessionKeys.CURRENT_USER] = user;
                            }
                        }
                    }
    
                    return user;
                }
    
                return null;
            }
        }
        public static int CurrentUserId { get; /* implementation omitted for brevity */ }
        public static bool IsAuthenticated { get; /* implementation omitted for brevity */ }
    }
    

    Background info: this is an MVC4 application, so I'm using ninject.mvc3 plugin.

    PS.: I've seen some questions concerning Ninject and static methods, but none of them seemed to address an issue like this.

  • Phillippe Santana
    Phillippe Santana almost 11 years
    I see. I didn't realize it was such a bad practice, but with your explanation I can now understant it, and will follow your advice. Anyways, it is good to know how to work around this if there's no other option. Thanks!
  • Steven
    Steven almost 11 years
    It's true, sometimes you can't. For instance when introducing Dependency Injection into legacy applications you will have to move in small steps. On of those temporary steps could be a solution like this. It's ugly, it's technical depth, but temporary (at least it should be). But if your application is already built up using DI, there is really no reason to do this.