Hacker News new | ask | show | jobs
by ducharmdev 1515 days ago
At work, we have a .Net 6 codebase that had some odd design decisions made in the past couple years. Roughly ~115 classes using Unity for dependency injection instead of ASP.NET Core DI, and this horrible Unity-based service locator pattern used all over the place. Since nothing was using constructor injection and instead just grabbed deps from calls to a global static locator willy-nilly, it was very difficult to tell how many dependencies a given class had. The worst classes were injecting 30-40 dependencies, but you couldn't tell this in looking at them.

Anyway - I was tasked with removing Unity and refactoring the service locator usage, since Unity was going to be unsupported soon. Doing this gave me a real sense of agency in our otherwise boring enterprise app; it was one of the rare chances where I could make a significant, wide-scale improvement that would make future development easier for everyone.

1 comments

out of curiosity, is the code you've had to touch all in one single source control repository? have you needed to refactor stuff across many different independently versioned packages, or is it all monolithic?

(if it were me, i'd be hoping it was one giant monolithic application in one single repo, to make it easier to track & perform this kind of sweeping surgery)

Yup, all one repo fortunately. The majority of changes were in 3 class library projects, each of which is referenced by web portal, API, and nightly jobs projects. I'd imagine it could be quite painful if scattered in various repos!
i've sometimes enjoyed this kind of work in the past, provided there's good automated test coverage / static analysis from compiler & tooling to lean on. After the initial experimentation to decide on the new structure and confirm it is going to work, put on some good music and grind away at it.
Haha yep, that just about describes how it went for me. No way would I do all that without automated testing too - the immediate feedback is crucial for broad changes like this, that way if you do find you've made a wrong judgment in your approach, you find out immediately and correct your course.

One thing specific to .Net DI that made it easier was an extension method provided by our architecture team that does a "warmup" of all dependencies registered in your service collection. In practice all this means is, on app startup, it attempts to instantiate every registered service; if a dependency is missing, you'll get an exception for the service that failed to be created with the dep it failed on. Very helpful for chasing down issues related to missing service registrations!