fix: DI wrong approach wasn't working

This commit is contained in:
Florian Sylvain
2025-03-29 01:45:48 +01:00
parent a77a5ad314
commit 2292a8ef34
+47 -25
View File
@@ -3,6 +3,7 @@ package api
import ( import (
"GoCMS/adapters/secondary/gateways" "GoCMS/adapters/secondary/gateways"
"GoCMS/adapters/secondary/gateways/models" "GoCMS/adapters/secondary/gateways/models"
domainGateways "GoCMS/domain/gateways"
"GoCMS/useCases" "GoCMS/useCases"
"fmt" "fmt"
"os" "os"
@@ -20,6 +21,11 @@ type UseCaseDefinition struct {
FieldName string FieldName string
} }
type RepositoryDefinition struct {
Constructor interface{}
Interface interface{}
}
var useCaseDefinitions = []UseCaseDefinition{ var useCaseDefinitions = []UseCaseDefinition{
{useCases.NewCreatePostUseCase, "CreatePostUseCase"}, {useCases.NewCreatePostUseCase, "CreatePostUseCase"},
{useCases.NewGetPostUseCase, "GetPostUseCase"}, {useCases.NewGetPostUseCase, "GetPostUseCase"},
@@ -37,6 +43,14 @@ var useCaseDefinitions = []UseCaseDefinition{
{useCases.NewDeleteImageUseCase, "DeleteImageUseCase"}, {useCases.NewDeleteImageUseCase, "DeleteImageUseCase"},
} }
var repositoryDefinitions = []RepositoryDefinition{
{gateways.NewPostRepository, new(domainGateways.IPostRepository)},
{gateways.NewUserRepository, new(domainGateways.IUserRepository)},
{gateways.NewImageRepository, new(domainGateways.IImageRepository)},
{gateways.NewMailRepository, new(domainGateways.IMailRepository)},
{gateways.NewPageRepository, new(domainGateways.IPageRepository)},
}
type UseCases struct { type UseCases struct {
CreatePostUseCase *useCases.CreatePostUseCase CreatePostUseCase *useCases.CreatePostUseCase
GetPostUseCase *useCases.GetPostUseCase GetPostUseCase *useCases.GetPostUseCase
@@ -89,22 +103,10 @@ func InitContainer() {
} }
} }
if err := digContainer.Provide(func(values ...any) *UseCases { constructorType := buildConstructorType()
container := &UseCases{} constructor := reflect.MakeFunc(constructorType, buildUseCasesInstance)
containerValue := reflect.ValueOf(container).Elem()
for i, value := range values { if err := digContainer.Provide(constructor.Interface()); err != nil {
fieldName := useCaseDefinitions[i].FieldName
field := containerValue.FieldByName(fieldName)
if field.IsValid() && field.CanSet() {
field.Set(reflect.ValueOf(value))
} else {
panic(fmt.Sprintf("Failed to set field %s", fieldName))
}
}
return container
}, dig.As(new(*UseCases))); err != nil {
panic("Failed to provide container constructor: " + err.Error()) panic("Failed to provide container constructor: " + err.Error())
} }
@@ -113,18 +115,38 @@ func InitContainer() {
} }
} }
func provideRepositories(container *dig.Container) { func buildConstructorType() reflect.Type {
repositories := []any{ var paramTypes []reflect.Type
gateways.NewPostRepository, for _, def := range useCaseDefinitions {
gateways.NewUserRepository, constructorType := reflect.TypeOf(def.Constructor)
gateways.NewImageRepository, returnType := constructorType.Out(0)
gateways.NewMailRepository, paramTypes = append(paramTypes, returnType)
gateways.NewPageRepository,
} }
for _, repo := range repositories { return reflect.FuncOf(paramTypes, []reflect.Type{reflect.TypeOf(&UseCases{})}, false)
if err := container.Provide(repo); err != nil { }
funcName := runtime.FuncForPC(reflect.ValueOf(repo).Pointer()).Name()
func buildUseCasesInstance(args []reflect.Value) []reflect.Value {
container := &UseCases{}
containerValue := reflect.ValueOf(container).Elem()
for i, arg := range args {
fieldName := useCaseDefinitions[i].FieldName
field := containerValue.FieldByName(fieldName)
if field.IsValid() && field.CanSet() {
field.Set(arg)
} else {
panic(fmt.Sprintf("Failed to set field %s", fieldName))
}
}
return []reflect.Value{reflect.ValueOf(container)}
}
func provideRepositories(container *dig.Container) {
for _, def := range repositoryDefinitions {
if err := container.Provide(def.Constructor, dig.As(def.Interface)); err != nil {
funcName := runtime.FuncForPC(reflect.ValueOf(def.Constructor).Pointer()).Name()
panic(fmt.Sprintf("Failed to provide repository %s: %v", funcName, err)) panic(fmt.Sprintf("Failed to provide repository %s: %v", funcName, err))
} }
} }