在 go 中使用接口进行依赖注入
Dependency injection with interface in go
我有一个结构 StructDependingOnInterface
依赖于 MyInterface
接口。我希望在实例化 StructDependingOnInterface
时将结构 Implementation
注入到 bar
中。
我试过用 facebookgo/inject 库来做这个,但它似乎不适用于接口。 s.bar
始终为零。
package main
import (
"fmt"
"log"
"github.com/facebookgo/inject"
)
type MyInterface interface {
Foo()
}
type Implementation struct{}
func (imp *Implementation) Foo() {
fmt.Println("Hello")
}
type StructDependingOnInterface struct {
bar MyInterface `inject:""`
}
func main() {
var g inject.Graph
err := g.Provide(
&inject.Object{Value: &Implementation{}},
)
if err != nil {
log.Fatal(err)
}
g.Populate()
s := &StructDependingOnInterface{}
s.bar.Foo()
}
go 语言是否允许我尝试做的事情?
是否有 facebookgo/inject 的替代品可以满足我的需要?
facebookgo/inject should be able to handle interfaces, look at the example in the link and how they use http.RoundTripper
和 http.DefaultTransport
.
首先您需要导出 bar
,即将其更改为 Bar
。然后你还需要将 s
传递给 Provide
以获得 g.Populate
然后才能设置 Bar
.
type StructDependingOnInterface struct {
Bar MyInterface `inject:""`
}
func main() {
var g inject.Graph
s := &StructDependingOnInterface{}
err := g.Provide(
&inject.Object{Value: s},
&inject.Object{Value: &Implementation{}},
)
if err != nil {
log.Fatal(err)
}
if err := g.Populate(); err != nil {
log.Fatal(err)
}
s.bar.Foo()
}
hiboot 是一个 cli/web 框架,支持用 Go 编写的依赖注入。
Code:
https://github.com/hidevopsio/hiboot
Hiboot概述
- Web MVC(模型-视图-控制器)。
- 自动配置,使用属性配置为依赖注入预创建实例。
- 使用结构标签名称
inject:""
或构造函数的依赖注入。
示例代码:
package main
import (
"github.com/hidevopsio/hiboot/pkg/app/web"
"github.com/hidevopsio/hiboot/pkg/model"
"github.com/hidevopsio/hiboot/pkg/starter/jwt"
"time"
)
// This example shows that token is injected through constructor,
// once you imported "github.com/hidevopsio/hiboot/pkg/starter/jwt",
// token jwt.Token will be injectable.
func main() {
// create new web application and run it
web.NewApplication().Run()
}
// PATH: /login
type loginController struct {
web.Controller
token jwt.Token
}
type userRequest struct {
// embedded field model.RequestBody mark that userRequest is request body
model.RequestBody
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
}
func init() {
// Register Rest Controller through constructor newLoginController
web.RestController(newLoginController)
}
// inject token through the argument token jwt.Token on constructor newLoginController, you may wonder why is token come from
// well, it provided by hiboot starter jwt, see above hiboot link for more details
func newLoginController(token jwt.Token) *loginController {
return &loginController{
token: token,
}
}
// Post /
// The first word of method is the http method POST, the rest is the context mapping
func (c *loginController) Post(request *userRequest) (response model.Response, err error) {
jwtToken, _ := c.token.Generate(jwt.Map{
"username": request.Username,
"password": request.Password,
}, 30, time.Minute)
response = new(model.BaseResponse)
response.SetData(jwtToken)
return
}
我有一个结构 StructDependingOnInterface
依赖于 MyInterface
接口。我希望在实例化 StructDependingOnInterface
时将结构 Implementation
注入到 bar
中。
我试过用 facebookgo/inject 库来做这个,但它似乎不适用于接口。 s.bar
始终为零。
package main
import (
"fmt"
"log"
"github.com/facebookgo/inject"
)
type MyInterface interface {
Foo()
}
type Implementation struct{}
func (imp *Implementation) Foo() {
fmt.Println("Hello")
}
type StructDependingOnInterface struct {
bar MyInterface `inject:""`
}
func main() {
var g inject.Graph
err := g.Provide(
&inject.Object{Value: &Implementation{}},
)
if err != nil {
log.Fatal(err)
}
g.Populate()
s := &StructDependingOnInterface{}
s.bar.Foo()
}
go 语言是否允许我尝试做的事情?
是否有 facebookgo/inject 的替代品可以满足我的需要?
facebookgo/inject should be able to handle interfaces, look at the example in the link and how they use http.RoundTripper
和 http.DefaultTransport
.
首先您需要导出 bar
,即将其更改为 Bar
。然后你还需要将 s
传递给 Provide
以获得 g.Populate
然后才能设置 Bar
.
type StructDependingOnInterface struct {
Bar MyInterface `inject:""`
}
func main() {
var g inject.Graph
s := &StructDependingOnInterface{}
err := g.Provide(
&inject.Object{Value: s},
&inject.Object{Value: &Implementation{}},
)
if err != nil {
log.Fatal(err)
}
if err := g.Populate(); err != nil {
log.Fatal(err)
}
s.bar.Foo()
}
hiboot 是一个 cli/web 框架,支持用 Go 编写的依赖注入。
Code:
https://github.com/hidevopsio/hiboot
- Web MVC(模型-视图-控制器)。
- 自动配置,使用属性配置为依赖注入预创建实例。
- 使用结构标签名称
inject:""
或构造函数的依赖注入。
package main
import (
"github.com/hidevopsio/hiboot/pkg/app/web"
"github.com/hidevopsio/hiboot/pkg/model"
"github.com/hidevopsio/hiboot/pkg/starter/jwt"
"time"
)
// This example shows that token is injected through constructor,
// once you imported "github.com/hidevopsio/hiboot/pkg/starter/jwt",
// token jwt.Token will be injectable.
func main() {
// create new web application and run it
web.NewApplication().Run()
}
// PATH: /login
type loginController struct {
web.Controller
token jwt.Token
}
type userRequest struct {
// embedded field model.RequestBody mark that userRequest is request body
model.RequestBody
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
}
func init() {
// Register Rest Controller through constructor newLoginController
web.RestController(newLoginController)
}
// inject token through the argument token jwt.Token on constructor newLoginController, you may wonder why is token come from
// well, it provided by hiboot starter jwt, see above hiboot link for more details
func newLoginController(token jwt.Token) *loginController {
return &loginController{
token: token,
}
}
// Post /
// The first word of method is the http method POST, the rest is the context mapping
func (c *loginController) Post(request *userRequest) (response model.Response, err error) {
jwtToken, _ := c.token.Generate(jwt.Map{
"username": request.Username,
"password": request.Password,
}, 30, time.Minute)
response = new(model.BaseResponse)
response.SetData(jwtToken)
return
}