Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to manage dependency will be more elegant? #35

Open
bluntdel opened this issue Dec 2, 2019 · 7 comments
Open

How to manage dependency will be more elegant? #35

bluntdel opened this issue Dec 2, 2019 · 7 comments

Comments

@bluntdel
Copy link

bluntdel commented Dec 2, 2019

I see these codes in the main.go.

authorRepo := _authorRepo.NewMysqlAuthorRepository(dbConn)
ar := _articleRepo.NewMysqlArticleRepository(dbConn)
timeoutContext := time.Duration(viper.GetInt("context.timeout")) * time.Second
au := _articleUcase.NewArticleUsecase(ar, authorRepo, timeoutContext)
_articleHttpDeliver.NewArticleHttpHandler(e, au)

I think if articleUcase need articleRepo,articleAuthorRepo and more other repository... Dependency management will be terrible, it will produce many codes like "newAriticleUseaCase(ARepo,BRepo,CRepo...)".So if it can be more elegant? I don't think write in the main.go is a good idea.

@frederikhors
Copy link

@bluntdel and @bxcodec what do you think about https://github.com/google/wire guys?

@bxcodec
Copy link
Owner

bxcodec commented May 15, 2020

Wow, good question, personally I haven't do any elegant way.

Because for me personally, I'd rather see an explicit one rather than implicit, like in Java world with a lot of decorator things, that really consumes a lot of my mind budget to understand how is it worked.

Also in this explicit way, I can do knowledge transfer to junior engineers easily without the need to know how dependency injection tools work.

@frederikhors , I'll look into it, and try to understand it. If it's not making things more complicated, then it's a good to try.

@PhantomX7
Copy link

@bluntdel surely it is a problem if we create a monolith using this this design pattern. It will create a long dependency injection call
func New(aRepo a.repository, bRepo b.repository ...) AUsecase { ... }
i have found a great library called fx to reduce the code boilerplate of the dependency injection.
@frederikhors the difference between wire and fx is that wire is a code generator and fx is runtime auto inject dependency.

@myugen
Copy link

myugen commented Nov 10, 2020

Maybe, it could be possible manage those dependencies through a context, for example, creating an ArticleContext interface such that

type ArticleContext interface {
    GetARepo() ARepo
    GetBRepo() BRepo
    GetCRepo() CRepo
    ....
    GetZRepo() ZRepo
}

Then, you just need to call inside usecase the respective repository:

func (a *articleUsecase) Fetch(c MyArticleContext, cursor string, num int64) (res []domain.Article, nextCursor string, err error) {
    ....
    aRepo := c.GetARepo()
    ....
}

@mcauto
Copy link

mcauto commented Dec 13, 2021

@bxcodec
I made a sample project with dependency injection framework uber-go/fx.
Could you feedback to me?

https://github.com/mcauto/todolist-api

@HubQin
Copy link

HubQin commented Feb 23, 2023

I wonder that is this way testable? and where to place ArticleContext.

@mcauto
Copy link

mcauto commented Feb 24, 2023

이런 식으로 테스트 가능한지 궁금합니다. 그리고 ArticleContext를 배치할 위치.

How about this?

https://github.com/mcauto/todolist-api/blob/main/modules/domains/todo/service_test.go#L38

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants