Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you refactor static classes to use dependency injection?

I've inherited some code that has a class AuthenticationManager with all static methods.

Im introducing DI and wanted to add a constructor that took a dependency UserController

UserController _userController;

public AuthenticationManager(UserController userCont)
{
    _userController = userCont;
}

Now Im getting the compile time error as a non-static variable is referenced from a static method. What would your best practice recommendation be to get this to work with the minmimal changes to this class and the calling code?

We're using the SimpleServiceLocator as the IOC container.

like image 670
Steve Ward Avatar asked Dec 23 '11 00:12

Steve Ward


People also ask

Can I use dependency injection with a static class?

You can use dependency injection in a static class using method or property injection. However, you cannot use constructor injection in a static class because the constructor of a static class cannot accept any parameters.

How do you inherit a static class?

Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor. However, they can contain a static constructor.

What is static $inject?

A static web injection, also known as a redirect attack, is a technique used to redirect an infected victims' traffic to a malicious server that hosts a replica of the original website that was requested.


1 Answers

Well it depends on how often the class is used throughout the code. You'll likely want to create an IAuthenticationManager interface that includes methods that match the static methods you want to replace with instance methods. Then you could create an AuthenticationManager class that implements the interface, and accepts the UserController dependency via its constructor.

You would then need to replace all the static method call-sites the instance methods. You would probably want to inject an IAuthenticationManager into the classes via a constructor or a property. If need-be, you could also pass an IAuthenticationManager to the methods (at the call-sites) as a parameter.

Unfortunately replacing static methods takes quite a bit of refactoring. It is worth the effort though. It opens up the door for unit-testing.

Keep in mind that you can always refactor one method at a time by extracting an interface for one of the static methods. Do each method one at a time to take a step-wise approach to your refactoring (in other words, each method gets its own interface).

I would recommend taking a look at this book if you can: Working Effectively With Legacy Code. Great book that covers all sort of situation like this one.

like image 82
Jason Down Avatar answered Oct 19 '22 09:10

Jason Down