By using this site, you agree to the Privacy Policy and Terms of Use.
Accept
World of SoftwareWorld of SoftwareWorld of Software
  • News
  • Software
  • Mobile
  • Computing
  • Gaming
  • Videos
  • More
    • Gadget
    • Web Stories
    • Trending
    • Press Release
Search
  • Privacy
  • Terms
  • Advertise
  • Contact
Copyright © All Rights Reserved. World of Software.
Reading: Understanding Dependency Injection in Object-Oriented Programming | HackerNoon
Share
Sign In
Notification Show More
Font ResizerAa
World of SoftwareWorld of Software
Font ResizerAa
  • Software
  • Mobile
  • Computing
  • Gadget
  • Gaming
  • Videos
Search
  • News
  • Software
  • Mobile
  • Computing
  • Gaming
  • Videos
  • More
    • Gadget
    • Web Stories
    • Trending
    • Press Release
Have an existing account? Sign In
Follow US
  • Privacy
  • Terms
  • Advertise
  • Contact
Copyright © All Rights Reserved. World of Software.
World of Software > Computing > Understanding Dependency Injection in Object-Oriented Programming | HackerNoon
Computing

Understanding Dependency Injection in Object-Oriented Programming | HackerNoon

News Room
Last updated: 2025/10/16 at 8:46 PM
News Room Published 16 October 2025
Share
Understanding Dependency Injection in Object-Oriented Programming | HackerNoon
SHARE

In Object-Oriented Programming, objects collaborate. The initial idea of collaboration, first found in Smalltalk, was for object A to send a message to object B. Languages designed later use method calling. In both cases, the same question stands: how does an object reference other objects to reach the desired results?

In this post, I tackle the problem of passing dependencies to an object. I will go through several options and analyze their respective pros and cons.

Constructor injection

For constructor injection, you pass dependencies as parameters to the constructor.

class Delivery(private val addressService: AddressService,
               private val geoService: GeoService,
               private val zoneId: ZoneId) {

    fun computeDeliveryTime(user: User, warehouseLocation: Location): ZonedDateTime {
        val address = addressService.getAddressOf(user)
        val coordinates = geoService.getCoordinates(location)
        // return date time
    }
}

Constructor injection is by far the most widespread way to pass to an object its dependencies: for about ten years, every codebase I’ve seen has constructor injection.

I’ve a slight issue with constructor injection: it stores dependencies as fields, just like state. Looking at the constructor’s signature, it’s impossible to distinguish between the state and dependencies without proper typing.

It bugs me. Let’s see other ways.

Parameter passing

Instead of storing the dependencies along with the state, we can pass the dependency when calling the method.

class Delivery(private val zoneId: ZoneId) {

    fun computeDeliveryTime(addressService: AddressService,
                            geoService: GeoService,
                            user: User, warehouseLocation: Location): ZonedDateTime {
        val address = addressService.getAddressOf(user)
        val coordinates = geoService.getCoordinates(location)
        // return date time
    }
}

The separation of state and dependencies is now clear: the former is stored in fields, while the latter is passed as function parameters. However, the responsibility of handling the dependency is moved one level up the call chain. The longer the call chain, the more unwieldy it gets.

class Order() {

    fun deliver(delivery: Delivery, user: User, warehouseLocation: Location): OrderDetails {
        // Somehow get the address and the geo services
        val deliveryTime = delivery.computeDeliveryTime(addressService, geoService, user, warehouseLocation)
        // return order details
    }
}

Note that the call chain length is also a problem with constructor injection. You need to design the code for the call site to be as close as possible to the dependency creation one.

ThreadLocal

Legacy design makes use of the ThreadLocal:

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).

For example, the class below generates unique identifiers local to each thread. A thread’s ID is assigned the first time it invokes ThreadId.get() and remains unchanged on subsequent calls.

import java.util.concurrent.atomic.AtomicInteger;

public class ThreadId {
   // Atomic integer containing the next thread ID to be assigned
   private static final AtomicInteger nextId = new AtomicInteger(0);

   // Thread local variable containing each thread's ID
   private static final ThreadLocal<Integer> threadId =
       new ThreadLocal<Integer>() {
           @Override protected Integer initialValue() {
               return nextId.getAndIncrement();
       }
   };

   // Returns the current thread's unique ID, assigning it if necessary
   public static int get() {
       return threadId.get();
   }
}

— Class ThreadLocal

We can rewrite the above code using ThreadLocal:

class Delivery(private val zoneId: ZoneId) {

    fun computeDeliveryTime(user: User, warehouseLocation: Location): ZonedDateTime {
        val addressService = AddressService.get()
        val geoService = GeoService.get()
        // return date time
    }
}

The ThreadLocal can be either set up in the call chain or lazily, on first access. Regardless, the biggest disadvantage of this approach is that it completely hides the dependency. There’s no way to understand the coupling by only looking at the class constructor or the function signature; one needs to read the function’s source code.

Additionally, the implementation could be a regular singleton pattern, with the same downsides.

Kotlin context

The last approach is Kotlin-specific and has just been promoted from experimental to beta in Kotlin 2.2.

Context parameters allow functions and properties to declare dependencies that are implicitly available in the surrounding context.

With context parameters, you don’t need to manually pass around values, such as services or dependencies, that are shared and rarely change across sets of function calls.

— Context parameter

Here’s how we can migrate the above code to context parameters:

class Delivery(private val zoneId: ZoneId) {

    context(addressService: AddressService, geoService: GeoService)
    fun computeDeliveryTime(user: User, warehouseLocation: Location): ZonedDateTime {
        // return date time
    }
}

And here’s how to call it:

context(addressService,geoService) {
    delivery.computeDeliveryTime(user, location)
}

Note that the call can be nested at any level inside the context.

Summary

| Approach | Pros | Cons |
|—-|—-|—-|
| Constructor injection | Testable | Mix state and dependencies |
| Parameter passing | Testable | Noisy |
| ThreadLocal | | Hides coupling |
| Context parameter | Get dependencies on deeply-nested | Limited to Kotlin |

I guess I’ll continue to use constructor injection, unless I’m coding in Kotlin. In this case, I’ll be happy to use context parameters, even though they are in beta.


Originally published at A Java Geek on October 12th, 2025

Sign Up For Daily Newsletter

Be keep up! Get the latest breaking news delivered straight to your inbox.
By signing up, you agree to our Terms of Use and acknowledge the data practices in our Privacy Policy. You may unsubscribe at any time.
Share This Article
Facebook Twitter Email Print
Share
What do you think?
Love0
Sad0
Happy0
Sleepy0
Angry0
Dead0
Wink0
Previous Article Tesla’s Controversial ‘Mad Max’ Full Self-Driving Mode Is Back, For Some Inexplicable Reason – BGR Tesla’s Controversial ‘Mad Max’ Full Self-Driving Mode Is Back, For Some Inexplicable Reason – BGR
Next Article M5 MacBook Air Coming Spring 2026 With M5 Mac Studio and Mac Mini in Development M5 MacBook Air Coming Spring 2026 With M5 Mac Studio and Mac Mini in Development
Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Stay Connected

248.1k Like
69.1k Follow
134k Pin
54.3k Follow

Latest News

Treat yourself: The best smart glasses to buy with your holiday gift money |  News
Treat yourself: The best smart glasses to buy with your holiday gift money | News
News
AI agent governance is the new resilience mandate –  News
AI agent governance is the new resilience mandate – News
News
Someone believed that ‘GTA Vice City’ could be played for free in the browser without consequences. Take-Two has reacted firmly
Someone believed that ‘GTA Vice City’ could be played for free in the browser without consequences. Take-Two has reacted firmly
Mobile
the ultimate summary if you are lost before the end of the series
the ultimate summary if you are lost before the end of the series
Mobile

You Might also Like

QNX Self-Hosted Developer Desktop Brings QNX 8.0 To A Wayland + Xfce Desktop
Computing

QNX Self-Hosted Developer Desktop Brings QNX 8.0 To A Wayland + Xfce Desktop

2 Min Read
Bitunix Ranked Among the World’s Top 7 Exchanges by Volume in CoinGlass 2025 Report | HackerNoon
Computing

Bitunix Ranked Among the World’s Top 7 Exchanges by Volume in CoinGlass 2025 Report | HackerNoon

1 Min Read
Wine 11.0-rc4 Brings 22 Bug Fixes
Computing

Wine 11.0-rc4 Brings 22 Bug Fixes

1 Min Read
Washington state Commerce chief Joe Nguyen is leaving, reportedly to lead Seattle Metro Chamber
Computing

Washington state Commerce chief Joe Nguyen is leaving, reportedly to lead Seattle Metro Chamber

3 Min Read
//

World of Software is your one-stop website for the latest tech news and updates, follow us now to get the news that matters to you.

Quick Link

  • Privacy Policy
  • Terms of use
  • Advertise
  • Contact

Topics

  • Computing
  • Software
  • Press Release
  • Trending

Sign Up for Our Newsletter

Subscribe to our newsletter to get our newest articles instantly!

World of SoftwareWorld of Software
Follow US
Copyright © All Rights Reserved. World of Software.
Welcome Back!

Sign in to your account

Lost your password?