first commit

This commit is contained in:
lulz1 2024-10-18 17:21:19 +08:00
parent e778a48287
commit a2bab9cacf
22 changed files with 744 additions and 365 deletions

View File

@ -0,0 +1,7 @@
<component name="ProjectDictionaryState">
<dictionary name="lulz1">
<words>
<w>Hade</w>
</words>
</dictionary>
</component>

155
framework/container.go Normal file
View File

@ -0,0 +1,155 @@
package framework
import (
"errors"
"fmt"
"sync"
)
type Container interface {
// Bind 绑定一个服务提供者,如果关键字凭证已经存在,会进行替换操作,返回 error
Bind(provider ServiceProvider) error
// IsBind 关键字凭证是否已经绑定服务提供者
IsBind(key string) bool
// Make 根据关键字凭证获取一个服务,
Make(key string) (interface{}, error)
// MustMake 根据关键字凭证获取一个服务,如果这个关键字凭证未绑定服务提供者,那么会 panic。
//所以在使用这个接口的时候请保证服务容器已经为这个关键字凭证绑定了服务提供者。
MustMake(key string) interface{}
// MakeNew 根据关键字凭证获取一个服务,只是这个服务并不是单例模式的
//它是根据服务提供者注册的启动函数和传递的 params 参数实例化出来的
//这个函数在需要为不同参数启动不同实例的时候非常有用
MakeNew(key string, params []interface{}) (interface{}, error)
}
type HadeContainer struct {
// providers 存储注册的服务提供者key 为字符串凭证
providers map[string]ServiceProvider
// instance 存储具体的实例key 为字符串凭证
instances map[string]interface{}
// lock 用于锁住对容器的变更操作
lock sync.RWMutex
}
func NewHadeContainer() *HadeContainer {
return &HadeContainer{
providers: make(map[string]ServiceProvider),
instances: make(map[string]interface{}),
lock: sync.RWMutex{},
}
}
// PrintProviders 输出服务容器中注册的关键字
func (h *HadeContainer) PrintProviders() []string {
ret := []string{}
for _, provider := range h.providers {
name := provider.Name()
line := fmt.Sprint(name)
ret = append(ret, line)
}
return ret
}
func (h *HadeContainer) Bind(provider ServiceProvider) error {
//因为要对容器进行更改,先使用读写锁避免并发操作
h.lock.Lock()
defer h.lock.Unlock()
key := provider.Name()
h.providers[key] = provider
if !provider.IsDefer() {
//如果服务者不需要延迟加载的话, 直接创建服务实例
if err := provider.Boot(h); err == nil {
return err
}
params := provider.Params(h)
register := provider.Register(h)
instance, err := register(params)
if err != nil {
return err
}
h.instances[key] = instance
}
return nil
}
func (h *HadeContainer) IsBind(key string) bool {
_, ok := h.instances[key]
return ok
}
func (h *HadeContainer) Make(key string) (interface{}, error) {
return h.make(key, nil, false)
}
func (h *HadeContainer) MustMake(key string) interface{} {
instance, err := h.make(key, nil, false)
if err != nil {
panic(err)
}
return instance
}
func (h *HadeContainer) MakeNew(key string, params []interface{}) (interface{}, error) {
return h.make(key, params, true)
}
func (h *HadeContainer) make(key string, params []interface{}, forceNew bool) (interface{}, error) {
//因为要对容器进行更改,先使用读写锁避免并发操作
h.lock.RLock()
defer h.lock.RUnlock()
provider, err := h.findServiceProvider(key)
if err != nil {
return nil, err
}
//强制重新实例化
if forceNew {
return h.newInstance(provider, params)
}
// 不需要强制重新实例化,如果容器中已经实例化了,那么就直接使用容器中的实例
if instance, ok := h.instances[key]; ok {
return instance, nil
}
// 容器中还未实例化,则进行一次实例化
instance, err := h.newInstance(provider, params)
if err != nil {
return nil, err
}
h.instances[key] = instance
return instance, nil
}
func (h *HadeContainer) findServiceProvider(key string) (ServiceProvider, error) {
provider := h.providers[key]
if provider == nil {
return nil, errors.New("no such provider: " + key)
}
return provider, nil
}
func (h *HadeContainer) newInstance(provider ServiceProvider, params []interface{}) (interface{}, error) {
// force new a
if err := provider.Boot(h); err != nil {
return nil, err
}
if params == nil {
params = provider.Params(h)
}
register := provider.Register(h)
instance, err := register(params)
if err != nil {
return nil, err
}
return instance, nil
}

View File

@ -6,11 +6,10 @@ package binding
import ( import (
"fmt" "fmt"
"github.com/go-playground/validator/v10"
"reflect" "reflect"
"strings" "strings"
"sync" "sync"
"github.com/go-playground/validator/v10"
) )
type defaultValidator struct { type defaultValidator struct {

File diff suppressed because it is too large Load Diff

View File

@ -14,10 +14,10 @@ import (
// See the binding package. // See the binding package.
// //
// Deprecated: Use MustBindWith or ShouldBindWith. // Deprecated: Use MustBindWith or ShouldBindWith.
func (c *Context) BindWith(obj any, b binding.Binding) error { func (ctx *Context) BindWith(obj any, b binding.Binding) error {
log.Println(`BindWith(\"any, binding.Binding\") error is going to log.Println(`BindWith(\"any, binding.Binding\") error is going to
be deprecated, please check issue #662 and either use MustBindWith() if you be deprecated, please check issue #662 and either use MustBindWith() if you
want HTTP 400 to be automatically returned if any error occur, or use want HTTP 400 to be automatically returned if any error occur, or use
ShouldBindWith() if you need to manage the error.`) ShouldBindWith() if you need to manage the error.`)
return c.MustBindWith(obj, b) return ctx.MustBindWith(obj, b)
} }

View File

@ -6,6 +6,7 @@ package gin
import ( import (
"fmt" "fmt"
"github.com/Superdanda/hade/framework"
"html/template" "html/template"
"net" "net"
"net/http" "net/http"
@ -89,6 +90,9 @@ const (
type Engine struct { type Engine struct {
RouterGroup RouterGroup
//新增Hade框架容器
container framework.Container
// RedirectTrailingSlash enables automatic redirection if the current route can't be matched but a // RedirectTrailingSlash enables automatic redirection if the current route can't be matched but a
// handler for the path with (without) the trailing slash exists. // handler for the path with (without) the trailing slash exists.
// For example if /foo/ is requested but a route only exists for /foo, the // For example if /foo/ is requested but a route only exists for /foo, the
@ -209,6 +213,7 @@ func New(opts ...OptionFunc) *Engine {
secureJSONPrefix: "while(1);", secureJSONPrefix: "while(1);",
trustedProxies: []string{"0.0.0.0/0", "::/0"}, trustedProxies: []string{"0.0.0.0/0", "::/0"},
trustedCIDRs: defaultTrustedCIDRs, trustedCIDRs: defaultTrustedCIDRs,
container: framework.NewHadeContainer(),
} }
engine.RouterGroup.engine = engine engine.RouterGroup.engine = engine
engine.pool.New = func() any { engine.pool.New = func() any {
@ -237,7 +242,7 @@ func (engine *Engine) Handler() http.Handler {
func (engine *Engine) allocateContext(maxParams uint16) *Context { func (engine *Engine) allocateContext(maxParams uint16) *Context {
v := make(Params, 0, maxParams) v := make(Params, 0, maxParams)
skippedNodes := make([]skippedNode, 0, engine.maxSections) skippedNodes := make([]skippedNode, 0, engine.maxSections)
return &Context{engine: engine, params: &v, skippedNodes: &skippedNodes} return &Context{engine: engine, params: &v, skippedNodes: &skippedNodes, container: engine.container}
} }
// Delims sets template left and right delims and returns an Engine instance. // Delims sets template left and right delims and returns an Engine instance.

View File

@ -2,8 +2,35 @@ package gin
import ( import (
"context" "context"
"github.com/Superdanda/hade/framework"
) )
func (ctx *Context) BaseContext() context.Context { func (ctx *Context) BaseContext() context.Context {
return ctx.Request.Context() return ctx.Request.Context()
} }
// Bind engine 实现 container 的绑定封装
func (engine *Engine) Bind(provider framework.ServiceProvider) error {
return engine.container.Bind(provider)
}
// IsBind 关键字凭证是否已经绑定服务提供者
func (engine *Engine) IsBind(key string) bool {
return engine.container.IsBind(key)
}
// Make context 实现 container 的几个封装
// 实现 make 的封装
func (ctx *Context) Make(key string) (interface{}, error) {
return ctx.container.Make(key)
}
// MustMake 实现 mustMake 的封装
func (ctx *Context) MustMake(key string) interface{} {
return ctx.container.MustMake(key)
}
// MakeNew 实现 makenew 的封装
func (ctx *Context) MakeNew(key string, params []interface{}) (interface{}, error) {
return ctx.container.MakeNew(key, params)
}

View File

@ -5,13 +5,6 @@ import (
"mime/multipart" "mime/multipart"
) )
package gin
import (
"mime/multipart"
"github.com/spf13/cast"
)
// const defaultMultipartMemory = 32 << 20 // 32 MB // const defaultMultipartMemory = 32 << 20 // 32 MB
// 代表请求包含的方法 // 代表请求包含的方法

View File

@ -1,27 +1,25 @@
package middleware package middleware
import ( import (
"github.com/echo/hade/framework" "github.com/Superdanda/hade/framework/gin"
"log" "log"
"time" "time"
) )
// recovery机制将协程中的函数异常进行捕获 // recovery机制将协程中的函数异常进行捕获
func Cost() framework.ControllerHandler { func Cost() gin.HandlerFunc {
// 使用函数回调 // 使用函数回调
return func(c *framework.Context) error { return func(c *gin.Context) {
// 记录开始时间 // 记录开始时间
start := time.Now() start := time.Now()
log.Printf("api uri start: %v", c.GetRequest().RequestURI) log.Printf("api uri start: %v", c.Request.RequestURI)
// 使用next执行具体的业务逻辑 // 使用next执行具体的业务逻辑
c.Next() c.Next()
// 记录结束时间 // 记录结束时间
end := time.Now() end := time.Now()
cost := end.Sub(start) cost := end.Sub(start)
log.Printf("api uri end: %v, cost: %v", c.GetRequest().RequestURI, cost.Seconds()) log.Printf("api uri end: %v, cost: %v", c.Request.RequestURI, cost.Seconds())
return nil
} }
} }

View File

@ -1,18 +1,17 @@
package middleware package middleware
import ( import (
"github.com/echo/hade/framework" "github.com/Superdanda/hade/framework/gin"
"net/http" "net/http"
) )
func Recovery() framework.ControllerHandler { func Recovery() gin.HandlerFunc {
return func(c *framework.Context) error { return func(c *gin.Context) {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
c.SetStatus(http.StatusInternalServerError).Json(err) c.ISetStatus(http.StatusInternalServerError).IJson(err)
} }
}() }()
c.Next() c.Next()
return nil
} }
} }

View File

@ -3,15 +3,15 @@ package middleware
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/echo/hade/framework" "github.com/Superdanda/hade/framework/gin"
"log" "log"
"net/http" "net/http"
"time" "time"
) )
func Timeout(d time.Duration) framework.ControllerHandler { func Timeout(d time.Duration) gin.HandlerFunc {
// 使用函数回调 // 使用函数回调
return func(c *framework.Context) error { return func(c *gin.Context) {
finish := make(chan struct{}, 1) finish := make(chan struct{}, 1)
panicChan := make(chan interface{}, 1) panicChan := make(chan interface{}, 1)
// 执行业务逻辑前预操作初始化超时context // 执行业务逻辑前预操作初始化超时context
@ -32,14 +32,12 @@ func Timeout(d time.Duration) framework.ControllerHandler {
// 执行业务逻辑后操作 // 执行业务逻辑后操作
select { select {
case p := <-panicChan: case p := <-panicChan:
c.SetStatus(http.StatusInternalServerError).Json("time out") c.ISetStatus(http.StatusInternalServerError).IJson("time out")
log.Println(p) log.Println(p)
case <-finish: case <-finish:
fmt.Println("finish") fmt.Println("finish")
case <-durationCtx.Done(): case <-durationCtx.Done():
c.SetHasTimeout() c.ISetStatus(http.StatusInternalServerError).IJson("time out")
c.SetStatus(http.StatusInternalServerError).Json("time out")
} }
return nil
} }
} }

23
framework/provider.go Normal file
View File

@ -0,0 +1,23 @@
package framework
// NewInstance 定义了如何创建一个新实例,所有服务容器的创建服务
type NewInstance func(...interface{}) (interface{}, error)
type ServiceProvider interface {
// Register 在服务容器中注册了一个实例化服务的方法,是否在注册的时候就实例化这个服务,需要参考 IsDefer 接口。
Register(Container) NewInstance
// Boot 在调用实例化服务的时候会调用,可以把一些准备工作:基础配置,初始化参数的操作放在这个里面。
//如果 Boot 返回 error整个服务实例化就会实例化失败返回错误
Boot(Container) error
// IsDefer 决定是否在注册的时候实例化这个服务,如果不是注册的时候实例化,那就是在第一次 make 的时候进行实例化操作
//false 表示不需要延迟实例化在注册的时候就实例化。true 表示延迟实例化
IsDefer() bool
// Params params 定义传递给 NewInstance 的参数,可以自定义多个,建议将 container 作为第一个参数
Params(Container) []interface{}
// Name 代表了这个服务提供者的凭证
Name() string
}

2
go.mod
View File

@ -2,7 +2,7 @@ module github.com/Superdanda/hade
go 1.23.2 go 1.23.2
require github.com/spf13/cast v1.7.0 // indirect require github.com/spf13/cast v1.7.0
//gin //gin
require ( require (

95
go.sum Normal file
View File

@ -0,0 +1,95 @@
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

View File

@ -2,8 +2,9 @@ package main
import ( import (
"context" "context"
"github.com/echo/hade/framework/gin" "github.com/Superdanda/hade/framework/gin"
middleware2 "github.com/echo/hade/framework/middleware" middleware2 "github.com/Superdanda/hade/framework/middleware"
"github.com/Superdanda/hade/provider/demo"
"log" "log"
"net/http" "net/http"
"os" "os"
@ -18,6 +19,8 @@ func main() {
core.Use(middleware2.Recovery()) core.Use(middleware2.Recovery())
core.Use(middleware2.Cost()) core.Use(middleware2.Cost())
core.Bind(&demo.DemoServiceProvider{})
registerRouter(core) registerRouter(core)
server := &http.Server{ server := &http.Server{
Handler: core, Handler: core,

View File

@ -2,7 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/echo/hade/framework/gin" "github.com/Superdanda/hade/framework/gin"
) )
func Test1() gin.HandlerFunc { func Test1() gin.HandlerFunc {

View File

@ -0,0 +1 @@
package demo

30
provider/demo/provider.go Normal file
View File

@ -0,0 +1,30 @@
package demo
import (
"fmt"
"github.com/Superdanda/hade/framework"
)
type DemoServiceProvider struct {
}
func (sp *DemoServiceProvider) Name() string {
return Key
}
func (sp *DemoServiceProvider) Register(c framework.Container) framework.NewInstance {
return NewDemoService
}
func (sp *DemoServiceProvider) IsDefer() bool {
return true
}
func (sp *DemoServiceProvider) Params(c framework.Container) []interface{} {
return []interface{}{c}
}
func (sp *DemoServiceProvider) Boot(c framework.Container) error {
fmt.Println("demo service boot")
return nil
}

36
provider/demo/service.go Normal file
View File

@ -0,0 +1,36 @@
package demo
import (
"fmt"
"github.com/Superdanda/hade/framework"
)
// Key Demo 服务的 key
const Key = "hade:demo"
// Service Demo 服务的接口
type Service interface {
GetFoo() Foo
}
// Foo Demo 服务接口定义的一个数据结构
type Foo struct {
Name string
}
// DemoService serviceProvider 实现
type DemoService struct {
Service
c framework.Container
}
// GetFoo 实现接口
func (s *DemoService) GetFoo() Foo {
return Foo{Name: "i am foo"}
}
func NewDemoService(params ...interface{}) (interface{}, error) {
c := params[0].(framework.Container)
fmt.Println("new demo service")
return &DemoService{c: c}, nil
}

View File

@ -1,7 +1,7 @@
package main package main
import ( import (
"github.com/echo/hade/framework/gin" "github.com/Superdanda/hade/framework/gin"
) )
func registerRouter(core *gin.Engine) { func registerRouter(core *gin.Engine) {

View File

@ -1,6 +1,9 @@
package main package main
import "github.com/echo/hade/framework/gin" import (
"github.com/Superdanda/hade/framework/gin"
"github.com/Superdanda/hade/provider/demo"
)
func SubjectDelController(c *gin.Context) { func SubjectDelController(c *gin.Context) {
c.ISetOkStatus().IJson("ok SubjectDelController") c.ISetOkStatus().IJson("ok SubjectDelController")
@ -15,5 +18,9 @@ func SubjectGetController(c *gin.Context) {
} }
func SubjectListController(c *gin.Context) { func SubjectListController(c *gin.Context) {
c.ISetOkStatus().IJson("ok SubjectListController") demoService := c.MustMake(demo.Key).(demo.Service)
foo := demoService.GetFoo()
c.ISetOkStatus().IJson(foo)
} }

View File

@ -3,8 +3,7 @@ package main
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/Superdanda/hade/framework/gin"
"github.com/echo/hade/framework/gin"
"net/http" "net/http"
"time" "time"
) )