generic-di/README.md
2025-08-05 13:06:09 +02:00

3.5 KiB

generic-di

Go Dependency Injection with Generics

Example

Struct

configuration.go

package main

import "git.apihub24.de/admin/generic-di"

func init() {
	// register the Struct Constructor Function for DI
	di.Injectable[*Configuration, *Configuration](NewConfiguration)
}

type Configuration struct {
	UserName string
}

func NewConfiguration() *Configuration {
	return &Configuration{
		UserName: "Markus",
	}
}

greeter.go

package main

import (
	"fmt"
	"git.apihub24.de/admin/generic-di"
)

func init() {
	di.Injectable[*Greeter, *Greeter](NewGreeter)
}

type Greeter struct {
	config *Configuration
}

func NewGreeter() *Greeter {
	return &Greeter{
		// here was the Configuration from configuration.go injected
		config: di.Inject[*Configuration](),
	}
}

func (ctx *Greeter) Greet() string {
	return fmt.Sprintf("Hello, %s", ctx.config.UserName)
}

message_service.go

package main

import "git.apihub24.de/admin/generic-di"

func init() {
	di.Injectable[*MessageService, *MessageService](NewMessageService)
}

type MessageService struct {
	greeter *Greeter
}

func NewMessageService() *MessageService {
	return &MessageService{
		// here was the Greeter from greeter.go injected
		greeter: di.Inject[*Greeter](),
	}
}

func (ctx *MessageService) Welcome() string {
	return ctx.greeter.Greet()
}

main.go

package main

import di "git.apihub24.de/admin/generic-di"

func main() {
	msgService := di.Inject[*MessageService, *MessageService]()
	// prints the message "Hello, Markus"
	println(msgService.Welcome())
}

Interface

message_service.go

package main

import "git.apihub24.de/admin/generic-di"

func init() {
	di.Injectable[IMessageService, *messageService](newMessageService)
}

type IMessageService interface {
	Welcome() string
}

type messageService struct {
	greeter *Greeter
}

func NewMessageService() IMessageService {
	return &messageService{
		// here was the Greeter from greeter.go injected
		greeter: di.Inject[*Greeter](),
	}
}

func (ctx *messageService) Welcome() string {
	return ctx.greeter.Greet()
}

main.go

package main

import di "git.apihub24.de/admin/generic-di"

func main() {
	msgService := di.Inject[IMessageService, *messageService]()
	// prints the message "Hello, Markus"
	println(msgService.Welcome())
}

Multiple Instance

services/message_service.go

package services

import "git.apihub24.de/admin/generic-di"

func init() {
	di.Injectable[IMessageService, *MessageService](newMessageService)
	di.Injectable[IMessageService, *MessageServiceMock](newMessageServiceMock)
}

type IMessageService interface {
	Welcome() string
}

type MessageService struct {
	greeter *Greeter
}

func newMessageService() IMessageService {
	return &messageService{
		// here was the Greeter from greeter.go injected
		greeter: di.Inject[*Greeter](),
	}
}

func (ctx *MessageService) Welcome() string {
	return ctx.greeter.Greet()
}

type MessageServiceMock struct {}

func newMessageServiceMock() IMessageService {
	return &MessageServiceMock{}
}

func (svc *MessageServiceMock) Welcome() string {
	return "Hello, Mock"
}

main.go

package main

import di "git.apihub24.de/admin/generic-di"

func main() {
	// get the basic implementation
	msgService := di.Inject[services.IMessageService, *services.MessageService]()
	// prints the message "Hello, Markus"
	println(msgService.Welcome())

	// get the mock implementation
	msgService = di.Inject[services.IMessageService, *services.MessageServiceMock]()
	// prints the message "Hello, Mock"
	println(msgService.Welcome())
}