I'm trying to implement some of the best code practices in a Go project, and I know that Go have he particularities, but I think that I'm found the right way to do it, but have one point that bother me. I create a repository package with an interface like below:
type IItemsRepository interface {
ListItems() (items []entities.Item)
GetItemByID(id uuid.UUID) (item entities.Item)
CreateItem(item entities.Item)
DeleteItem(item entities.Item)
UpdateItem(item entities.Item)
}
It implementation is below:
type ItemsRepository struct{}
func (ir ItemsRepository) ListItems() (items []entities.Item) {
items = []entities.Item{}
db.Instance.Find(&items)
return items
}
func (ir ItemsRepository) GetItemByID(id uuid.UUID) (item entities.Item) {
item = entities.Item{}
db.Instance.Where(&entities.Item{ID: id}).First(&item)
return item
}
func (ir ItemsRepository) CreateItem(item entities.Item) {
db.Instance.Create(item)
}
func (ir ItemsRepository) DeleteItem(item entities.Item) {
db.Instance.Delete(item)
}
func (ir ItemsRepository) UpdateItem(item entities.Item) {
db.Instance.Save(item)
}
At this point I don't see any problem, but now let's see how I have implemented the IOC, I did created a package called ioc with this function that will resolve all project dependencies:
func ResolveDependencies() {
container.Singleton(func() repositories.IItemsRepository {
return &items_repository.ItemsRepository{}
})
}
And now I have a problem, in every function that will use the item repository I should call a function that resolve the dependency, like bellow:
var itemsRepository repositories.IItemsRepository
func Execute(input AddItemInput) models.ResultWrapper[AddItemOutput] {
container.Resolve(&itemsRepository)
item := mapItem(input)
itemsRepository.CreateItem(item)
output := AddItemOutput{
ID: item.ID.String(),
}
return models.ResultWrapper[AddItemOutput]{
Success: true,
Errors: nil,
Data: output,
}
}
How you will implement IOC without call the dependency resolver in every function?
A better way to implement IOC in Go.