Go语言依赖注入 go语言import

go依赖注入dig包使用-来自uber公司原文链接Go语言依赖注入:
github:
Dependency Injection is the idea that your components (usuallystructsin go) should receive their dependencies when being created. This runs counter to the associated anti-pattern of components building their own dependencies during initialization. Let’s look at an example.
Suppose you have aServerstruct that requires aConfigstruct to implement its behavior. One way to do this would be for theServerto build its ownConfigduring initialization.
This seems convenient. Our caller doesn’t have to be aware that ourServereven needs access toConfig . This is all hidden from the user of our function.
However, there are some disadvantages. First of all, if we want to change the way ourConfigis built, we’ll have to change all the places that call the building code. Suppose, for example, ourbuildMyConfigSomehowfunction now needs an argument. Every call site would need access to that argument and would need to pass it into the building function.
Also, it gets really tricky to mock the behavior of ourConfig . We’ll somehow have to reach inside of ourNewfunction to monkey with the creation ofConfig .
Here’s the DI way to do it:
Now the creation of ourServeris decoupled from the creation of theConfig . We can use whatever logic we want to create theConfigand then pass the resulting data to ourNewfunction.
Furthermore, ifConfigis an interface, this gives us an easy route to mocking. We can pass anything we want intoNewas long as it implements our interface. This makes testing ourServerwith mock implementations ofConfigsimple.
The main downside is that it’s a pain to have to manually create theConfigbefore we can create theServer . We’ve created a dependency graph here – we must create ourConfigfirst because ofServerdepends on it. In real applications these dependency graphs can become very large and this leads to complicated logic for building all of the components your application needs to do its job.
This is where DI frameworks can help. A DI framework generally provides two pieces of functionality:
A DI framework generally builds a graph based on the “providers” you tell it about and determines how to build your objects. This is very hard to understand in the abstract, so let’s walk through a moderately-sized example.
We’re going to be reviewing the code for an HTTP server that delivers a JSON response when a client makes aGETrequest to/people . We’ll review the code piece by piece. For simplicity sake, it all lives in the same package ( main ). Please don’t do this in real Go applications. Full code for this example can be foundhere .
First, let’s look at ourPersonstruct. It has no behavior save for some JSON tags.
APersonhas anId ,NameandAge . That’s it.
Next let’s look at ourConfig . Similar toPerson , it has no dependencies. UnlikePerson , we will provide a constructor.
Enabledtells us if our application should return real data.DatabasePathtells us where our database lives (we’re using sqlite).Porttells us the port on which we’ll be running our server.
Here’s the function we’ll use to open our database connection. It relies on ourConfigand returns a*sql.DB .
Next we’ll look at ourPersonRepository . This struct will be responsible for fetching people from our database and deserializing those database results into properPersonstructs.
PersonRepositoryrequires a database connection to be built. It exposes a single function calledFindAllthat uses our database connection to return a list ofPersonstructs representing the data in our database.
To provide a layer between our HTTP server and thePersonRepository , we’ll create aPersonService .
OurPersonServicerelies on both theConfigand thePersonRepository . It exposes a function calledFindAllthat conditionally calls thePersonRepositoryif the application is enabled.
Finally, we’ve got ourServer . This is responsible for running an HTTP server and delegating the appropriate requests to ourPersonService .

推荐阅读