edge-connect-client/cmd/cli/main.go
Stephan Lo ef1f5b3f35 feat: implement dependency injection with proper hexagonal architecture
 Features:
- Simple dependency inversion following SOLID principles
- Clean constructor injection without complex DI containers
- Proper hexagonal architecture with driving/driven separation
- Presentation layer moved to cmd/cli for correct application structure

🏗️ Architecture Changes:
- Driving Adapters (Inbound): internal/adapters/driving/cli/
- Driven Adapters (Outbound): internal/adapters/driven/edgeconnect/
- Core Services: Dependency-injected via interface parameters
- main.go relocated from root to cmd/cli/main.go

📦 Application Flow:
1. cmd/cli/main.go - Entry point and dependency wiring
   └── Creates EdgeConnect client based on environment
   └── Instantiates services with injected repositories
   └── Executes CLI with properly wired dependencies

2. internal/adapters/driving/cli/ - User interface layer
   └── Receives user commands and input validation
   └── Delegates to core services via driving ports
   └── Handles presentation logic and output formatting

3. internal/core/services/ - Business logic layer
   └── NewAppService(appRepo, instanceRepo) - Constructor injection
   └── NewAppInstanceService(instanceRepo) - Interface dependencies
   └── NewCloudletService(cloudletRepo) - Clean separation

4. internal/adapters/driven/edgeconnect/ - Infrastructure layer
   └── Implements repository interfaces for external API
   └── Handles HTTP communication and data persistence
   └── Provides concrete implementations of driven ports

🔧 Build & Deployment:
- CLI Binary: make build → bin/edge-connect-cli
- Usage: ./bin/edge-connect-cli --help
- Tests: make test (all passing)
- Clean: make clean (updated paths)

💡 Benefits:
- Simple and maintainable dependency management
- Testable architecture with clear boundaries
- SOLID principles compliance without overengineering
- Proper separation of concerns in hexagonal structure
2025-10-08 18:15:26 +02:00

40 lines
1.5 KiB
Go

package main
import (
"os"
"edp.buildth.ing/DevFW-CICD/edge-connect-client/internal/adapters/driving/cli"
"edp.buildth.ing/DevFW-CICD/edge-connect-client/internal/adapters/driven/edgeconnect"
"edp.buildth.ing/DevFW-CICD/edge-connect-client/internal/core/services"
)
func main() {
// Präsentationsschicht: Simple dependency wiring - no complex container needed
// 1. Infrastructure Layer: Create EdgeConnect client (concrete implementation)
baseURL := getEnvOrDefault("EDGE_CONNECT_BASE_URL", "https://console.mobiledgex.net")
username := os.Getenv("EDGE_CONNECT_USERNAME")
password := os.Getenv("EDGE_CONNECT_PASSWORD")
var client *edgeconnect.Client
if username != "" && password != "" {
client = edgeconnect.NewClientWithCredentials(baseURL, username, password)
} else {
client = edgeconnect.NewClient(baseURL)
}
// 2. Application Layer: Create services with dependency injection (client implements repository interfaces)
appService := services.NewAppService(client) // client implements AppRepository
instanceService := services.NewAppInstanceService(client) // client implements AppInstanceRepository
cloudletService := services.NewCloudletService(client) // client implements CloudletRepository
// 3. Presentation Layer: Execute CLI driven adapters with injected services (simple parameter passing)
cli.ExecuteWithServices(appService, instanceService, cloudletService)
}
func getEnvOrDefault(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}