liveBook · Manning

Dependency injection

As explained in gRPC Microservices in Go

Dependency injection is a design technique in which a component receives its required collaborators from outside rather than constructing them internally.

Dependency injection gives a component its collaborators when the component is created, rather than having it construct them. In a Go Order service, the application accepts a database through `ports.DBPort`. `PlaceOrder` can save an order without knowing which database adapter implements that port. section 4.2.3

package api
 
import (
    "github.com/huseyinbabal/microservices/order/internal/application/core/
      domain"                                                    #1
    "github.com/huseyinbabal/microservices/order/internal/ports"   #2
)
 
type Application struct {
    db ports.DBPort                                                #3
}
 
func NewApplication(db ports.DBPort) *Application {
    return &Application{
        db: db,                                                    #4
    }
}
 
func (a Application) PlaceOrder(order domain.Order) (domain.Order, error) {
    err := a.db.Save(&order)                                       #5
    if err != nil {
        return domain.Order{}, err
    }
    return order, nil
}

`NewApplication` receives the database port and stores it on `Application`; `PlaceOrder` uses that dependency to save the order. section 4.2.3

Wire the service at startup:

  • Read the database URL and application port from environment variables. Reject missing values rather than starting with empty configuration. section 4.2.7
  • Create the database adapter, pass it to `NewApplication`, then pass the application and port to the gRPC adapter before running the server. section 4.2.7
  • When order creation also needs payment, initialize a payment adapter from `PAYMENT_SERVICE_URL` and pass both adapters to `NewApplication`. Initialization fails if the payment stub cannot be created. section 5.2.5
func main() {
    dbAdapter, err := db.NewAdapter(config.GetDataSourceURL())
    if err != nil {
        log.Fatalf("Failed to connect to database. Error: %v", err)
    }
 
    paymentAdapter, err := 
     payment.NewAdapter(config.GetPaymentServiceUrl())
    if err != nil {
        log.Fatalf("Failed to initialize payment stub. Error: %v", err)
    }
 
    application := api.NewApplication(dbAdapter, paymentAdapter)    #1
    grpcAdapter := grpc.NewAdapter(application, 
     config.GetApplicationPort())
    grpcAdapter.Run()
}

The expanded `main` function is the composition point: it constructs database and payment adapters, injects them into the application, and starts the gRPC adapter. section 5.2.5

A port defines the contract; an adapter supplies a matching implementation. Keeping that choice at startup separates application behavior from database and payment integration. The same boundary runs in the other direction: the gRPC adapter receives an API port and calls `PlaceOrder` when it handles a create request. This layering supports a testable application core, but it requires explicit construction and configuration of its collaborators. section 4.3 section 4.2.6

How gRPC Microservices in Go covers it

How deep it goes
Shows constructor-level injection and startup wiring in Go, including an expanded payment dependency.
Examples
Uses an Order service whose startup injects database and payment adapters into its application and that application into a gRPC adapter.
What it assumes
Assumes familiarity with Go packages and interfaces while illustrating how constructors connect a port to its adapter.
What you can do after
Build it from scratch by defining port-based dependencies and constructing their adapters at service startup.
How it connects
Connects dependency injection to hexagonal architecture, ports and adapters, environment-variable configuration, and gRPC.

Also explained in

Compare how 21 books explain dependency injection →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of gRPC Microservices in Go. The section links point to the parts of the book it draws on.