Open feikeq opened 3 months ago
You might use dependency injection for controller field types, as shown below:
package main
import (
"log"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/mvc"
)
type KVObject struct {
}
type ContactModel struct {
DB *sqlx.DB
TableName string
}
func NewContactModel(db *sqlx.DB) *ContactModel {
return &ContactModel{
DB: db,
TableName: "tbj_contact",
}
}
func (m *ContactModel) Groups(uid int64) ([]KVObject, error) {
// 确保 ContactModel 不为 nil
if m == nil {
println("ContactModel 为空?")
return nil, nil
}
log.Printf("ContactModel: %v\n", m)
println(m.TableName) // 第317行
return nil, nil
}
type UserModel struct {
DB *sqlx.DB
TableName string
}
func NewUserModel(db *sqlx.DB) *UserModel {
return &UserModel{
DB: db,
TableName: "tbj_user",
}
}
type ContactController struct {
DB *sqlx.DB
Models *ContactModel
UserModels *UserModel // 用户模型
CTX iris.Context
}
func (c *ContactController) GetGroups() {
_, err := c.Models.Groups(000)
if err != nil {
c.CTX.JSON(iris.Map{"code": 1, "msg": err.Error()})
return
}
c.CTX.JSON(iris.Map{"code": 0, "msg": "ok", "data": c.Models})
}
func NewContactController() *ContactController {
return &ContactController{}
}
func main() {
db, err := sqlx.Connect("mysql", "demo:demo@tcp(127.0.0.1:3306)/demo?parseTime=True&loc=Local")
if err != nil {
log.Fatalln(err)
}
baseApp := iris.Default()
app := baseApp.Party("/")
mvc.New(app.Party("/contact")).Configure(func(application *mvc.Application) {
application.Register(
NewContactModel(db),
NewUserModel(db),
)
application.Handle(NewContactController())
})
err = baseApp.Run(iris.Addr(":6677"))
if err != nil {
log.Fatalln(err)
}
}
在代码 main.go 中,使用了以下方式来创建控制器:
contactController := controllers.NewContactController(db, otherCfg)
mvc.New(app.Party("/contact")).Handle(contactController)
这段代码在12.2.4版本上是正常工作的,但是到12.2.5版本上感觉在处理请求时都使用的不是同一个控制器实例,是不是框架内部实现发生了变化,可能会导致新请求时创建新的控制器实例而不是复用旧的,这表明在某个地方 ContactController 的实例被替换或重新创建了。
contactController := controllers.NewContactController(db, otherCfg)
// contactController.Cfg = otherCfg // 手动绑定当前上下文没用
mvc.New(app.Party("/contact")).Register(db, otherCfg).Handle(contactController)
使用 mvc.New().Register() 也无效!为什么会这样?
iris-go 从 1.12.0 升级到 1.12.11 后报错,最多只能到 Iris Version: 12.2.4
[WARN] 2024/08/27 11:11 Recovered from a route's Handler('iris/hero.makeHandler.func2') GET /contact/groups/ HTTP/1.1 Host: 192.168.172.88:8888 Accept: application/json, text/plain, / Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Authorization: TT3tocaDvHzNmwI4bkXlzXunknW/iiqgxDoLy2kKGxcrc76sXOA9ahF8jSMBZijokBzC1H9HgO565yU= Connection: keep-alive Content-Type: application/json Origin: http://192.168.172.88:7777 Referer: http://192.168.172.88:7777/ User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36
runtime error: invalid memory address or nil pointer dereference /Users/feikeq/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.darwin-amd64/src/runtime/panic.go:770 /Users/feikeq/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.darwin-amd64/src/runtime/panic.go:261 /Users/feikeq/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.darwin-amd64/src/runtime/signal_unix.go:881 /Users/feikeq/Desktop/tibiji-go/models/contact.go:317 /Users/feikeq/Desktop/tibiji-go/controllers/contact.go:284 /Users/feikeq/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.darwin-amd64/src/reflect/value.go:596 /Users/feikeq/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.darwin-amd64/src/reflect/value.go:380 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/hero/handler.go:180 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/context/context.go:683 /Users/feikeq/Desktop/tibiji-go/middle/auth.go:125 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/context/context.go:683 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/middleware/logger/logger.go:73 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/context/context.go:683 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/middleware/recover/recover.go:29 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/context/context.go:683 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/aliases.go:362 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/context/context.go:683 /Users/feikeq/Desktop/tibiji-go/main.go:105 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/context/context.go:531 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/core/router/handler.go:498 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/core/router/router.go:117 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/context/context.go:683 /Users/feikeq/Desktop/tibiji-go/middle/cors.go:61 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/context/context.go:531 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/core/router/router.go:162 /Users/feikeq/go/pkg/mod/github.com/kataras/iris/v12@v12.2.11/core/router/router.go:341 /Users/feikeq/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.darwin-amd64/src/net/http/server.go:3142 /Users/feikeq/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.darwin-amd64/src/net/http/server.go:2044 /Users/feikeq/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.6.darwin-amd64/src/runtime/asm_amd64.s:1695
我那个317行是 m.TableName 具体model文件内容大概如下。
type ContactModel struct { DB *sqlx.DB TableName string }
func NewContactModel(db sqlx.DB) ContactModel { return &ContactModel{ DB: db, TableName: "tbj_contact", } } func (m *ContactModel) Groups(uid int64) ([]KVObject, error) {
}
控制台确实打印显示的是 “ContactModel 为空?”,但我在控制里是这样实例化的:
type ContactController struct { DB sqlx.DB Models models.ContactModel UserModels *models.UserModel // 用户模型 CTX iris.Context }
func NewContactController(db sqlx.DB) ContactController { // 返回一个结构体指针 return &ContactController{ DB: db, Models: models.NewContactModel(db), UserModels: models.NewUserModel(db), } }
我在main.go入口文件中是这样使用的(用的是irir-go框架)
contactController := controllers.NewContactController(db) mvc.New(app.Party("/contact")).Handle(contactController)
问题出在哪?为什么iris-go 从 1.12.0 升级到 1.12.11 后会报上面我提到的那种错误?
我尝试从高往低一个一个降版本测试,终于到 v12.2.4 就不报错了,于是找了一下v12.2.5的更新介绍: Mon, 21 Aug 2023 | v12.2.5 Add optional Singleton() bool method to controllers to mark them as singleton, will panic with a specific error if a controller expects dynamic dependencies. This behavior is idendical to the app-driven app.EnsureStaticBindings(). Non-zero fields of a controller that are marked as ignored, with ignore:"true" field tag, they are not included in the dependencies at all now. Re-add error log on context rich write (e.g. JSON) failures when the application is running under debug mode (with app.Logger().SetLevel("debug")) and there is no a registered context error handler at place. master branch finally renamed to main. Don't worry GitHub will still navigate any master request to main automatically. Examples, Documentation and other Pages are refactored too. 2023 年 8 月 21 日星期一 | v12.2.5 向控制器添加可选Singleton() bool方法以将其标记为单例,如果控制器需要动态依赖项,则会因特定错误而崩溃。此行为与应用驱动相同app.EnsureStaticBindings()。 控制器的非零字段被标记为忽略,带有ignore:"true"字段标签,它们现在根本不包含在依赖项中。 app.Logger().SetLevel("debug")当应用程序在调试模式下运行(使用)并且没有注册上下文错误处理程序时,重新添加上下文丰富写入(例如 JSON)失败的错误日志。 master分支最终重命名为main。不用担心,GitHub 仍会自动将任何master请求导航到main。示例、文档和其他页面也进行了重构。
能看出来我上面回复的代码里哪没按新的更新调整吗?