From 4df1af83d87475eb2941b06e5ff731ab087e8391 Mon Sep 17 00:00:00 2001 From: Muyao CHEN Date: Mon, 30 Sep 2024 09:09:01 +0200 Subject: [PATCH] GoWeb: add service container into Gin's engine and context --- context.go | 31 ++++++++++-- gin.go | 122 +++++++++++++++++++++++++++++++++++++---------- go.mod | 16 +++++-- go.sum | 13 +++-- goweb_context.go | 27 +++++++++++ 5 files changed, 170 insertions(+), 39 deletions(-) create mode 100644 goweb_context.go diff --git a/context.go b/context.go index 1f35651..1b56728 100644 --- a/context.go +++ b/context.go @@ -19,6 +19,7 @@ import ( "sync" "time" + "git.vinchent.xyz/vinchent/go-web/framework" "github.com/gin-contrib/sse" "github.com/gin-gonic/gin/binding" "github.com/gin-gonic/gin/render" @@ -89,6 +90,9 @@ type Context struct { // SameSite allows a server to define a cookie attribute making it impossible for // the browser to send this cookie along with cross-site requests. sameSite http.SameSite + + // GoWeb service container + container framework.Container } /************************************/ @@ -972,7 +976,9 @@ func (c *Context) ClientIP() string { // Legacy "AppEngine" flag if c.engine.AppEngine { - log.Println(`The AppEngine flag is going to be deprecated. Please check issues #2723 and #2739 and use 'TrustedPlatform: gin.PlatformGoogleAppEngine' instead.`) + log.Println( + `The AppEngine flag is going to be deprecated. Please check issues #2723 and #2739 and use 'TrustedPlatform: gin.PlatformGoogleAppEngine' instead.`, + ) if addr := c.requestHeader("X-Appengine-Remote-Addr"); addr != "" { return addr } @@ -1080,7 +1086,12 @@ func (c *Context) SetSameSite(samesite http.SameSite) { // SetCookie adds a Set-Cookie header to the ResponseWriter's headers. // The provided cookie must have a valid Name. Invalid cookies may be // silently dropped. -func (c *Context) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool) { +func (c *Context) SetCookie( + name, value string, + maxAge int, + path, domain string, + secure, httpOnly bool, +) { if path == "" { path = "/" } @@ -1223,7 +1234,13 @@ func (c *Context) Data(code int, contentType string, data []byte) { } // DataFromReader writes the specified reader into the body stream and updates the HTTP code. -func (c *Context) DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string) { +func (c *Context) DataFromReader( + code int, + contentLength int64, + contentType string, + reader io.Reader, + extraHeaders map[string]string, +) { c.Render(code, render.Reader{ Headers: extraHeaders, ContentType: contentType, @@ -1258,7 +1275,8 @@ func escapeQuotes(s string) string { // On the client side, the file will typically be downloaded with the given filename func (c *Context) FileAttachment(filepath, filename string) { if isASCII(filename) { - c.Writer.Header().Set("Content-Disposition", `attachment; filename="`+escapeQuotes(filename)+`"`) + c.Writer.Header(). + Set("Content-Disposition", `attachment; filename="`+escapeQuotes(filename)+`"`) } else { c.Writer.Header().Set("Content-Disposition", `attachment; filename*=UTF-8''`+url.QueryEscape(filename)) } @@ -1332,7 +1350,10 @@ func (c *Context) Negotiate(code int, config Negotiate) { c.TOML(code, data) default: - c.AbortWithError(http.StatusNotAcceptable, errors.New("the accepted formats are not offered by the server")) //nolint: errcheck + c.AbortWithError( + http.StatusNotAcceptable, + errors.New("the accepted formats are not offered by the server"), + ) //nolint: errcheck } } diff --git a/gin.go b/gin.go index 48cc15c..4b3f47a 100644 --- a/gin.go +++ b/gin.go @@ -15,6 +15,7 @@ import ( "strings" "sync" + "git.vinchent.xyz/vinchent/go-web/framework" "github.com/gin-gonic/gin/internal/bytesconv" "github.com/gin-gonic/gin/render" @@ -23,10 +24,12 @@ import ( "golang.org/x/net/http2/h2c" ) -const defaultMultipartMemory = 32 << 20 // 32 MB -const escapedColon = "\\:" -const colon = ":" -const backslash = "\\" +const ( + defaultMultipartMemory = 32 << 20 // 32 MB + escapedColon = "\\:" + colon = ":" + backslash = "\\" +) var ( default404Body = []byte("404 page not found") @@ -41,13 +44,49 @@ var defaultTrustedCIDRs = []*net.IPNet{ Mask: net.IPMask{0x0, 0x0, 0x0, 0x0}, }, { // ::/0 (IPv6) - IP: net.IP{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, - Mask: net.IPMask{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + IP: net.IP{ + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + }, + Mask: net.IPMask{ + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + }, }, } -var regSafePrefix = regexp.MustCompile("[^a-zA-Z0-9/-]+") -var regRemoveRepeatedChar = regexp.MustCompile("/{2,}") +var ( + regSafePrefix = regexp.MustCompile("[^a-zA-Z0-9/-]+") + regRemoveRepeatedChar = regexp.MustCompile("/{2,}") +) // HandlerFunc defines the handler used by gin middleware as return value. type HandlerFunc func(*Context) @@ -178,6 +217,9 @@ type Engine struct { maxSections uint16 trustedProxies []string trustedCIDRs []*net.IPNet + + // GoWeb service container + container framework.Container } var _ IRouter = (*Engine)(nil) @@ -262,11 +304,17 @@ func (engine *Engine) SecureJsonPrefix(prefix string) *Engine { func (engine *Engine) LoadHTMLGlob(pattern string) { left := engine.delims.Left right := engine.delims.Right - templ := template.Must(template.New("").Delims(left, right).Funcs(engine.FuncMap).ParseGlob(pattern)) + templ := template.Must( + template.New("").Delims(left, right).Funcs(engine.FuncMap).ParseGlob(pattern), + ) if IsDebugging() { debugPrintLoadTemplate(templ) - engine.HTMLRender = render.HTMLDebug{Glob: pattern, FuncMap: engine.FuncMap, Delims: engine.delims} + engine.HTMLRender = render.HTMLDebug{ + Glob: pattern, + FuncMap: engine.FuncMap, + Delims: engine.delims, + } return } @@ -277,11 +325,20 @@ func (engine *Engine) LoadHTMLGlob(pattern string) { // and associates the result with HTML renderer. func (engine *Engine) LoadHTMLFiles(files ...string) { if IsDebugging() { - engine.HTMLRender = render.HTMLDebug{Files: files, FuncMap: engine.FuncMap, Delims: engine.delims} + engine.HTMLRender = render.HTMLDebug{ + Files: files, + FuncMap: engine.FuncMap, + Delims: engine.delims, + } return } - templ := template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).Funcs(engine.FuncMap).ParseFiles(files...)) + templ := template.Must( + template.New(""). + Delims(engine.delims.Left, engine.delims.Right). + Funcs(engine.FuncMap). + ParseFiles(files...), + ) engine.SetHTMLTemplate(templ) } @@ -518,8 +575,10 @@ func (engine *Engine) Run(addr ...string) (err error) { defer func() { debugPrintError(err) }() if engine.isUnsafeTrustedProxies() { - debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + - "Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.") + debugPrint( + "[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.", + ) } engine.updateRouteTrees() address := resolveAddress(addr) @@ -536,8 +595,10 @@ func (engine *Engine) RunTLS(addr, certFile, keyFile string) (err error) { defer func() { debugPrintError(err) }() if engine.isUnsafeTrustedProxies() { - debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + - "Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.") + debugPrint( + "[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.", + ) } err = http.ListenAndServeTLS(addr, certFile, keyFile, engine.Handler()) @@ -552,8 +613,10 @@ func (engine *Engine) RunUnix(file string) (err error) { defer func() { debugPrintError(err) }() if engine.isUnsafeTrustedProxies() { - debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + - "Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.") + debugPrint( + "[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.", + ) } listener, err := net.Listen("unix", file) @@ -575,8 +638,10 @@ func (engine *Engine) RunFd(fd int) (err error) { defer func() { debugPrintError(err) }() if engine.isUnsafeTrustedProxies() { - debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + - "Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.") + debugPrint( + "[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.", + ) } f := os.NewFile(uintptr(fd), fmt.Sprintf("fd@%d", fd)) @@ -597,8 +662,10 @@ func (engine *Engine) RunQUIC(addr, certFile, keyFile string) (err error) { defer func() { debugPrintError(err) }() if engine.isUnsafeTrustedProxies() { - debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + - "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.") + debugPrint( + "[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.", + ) } err = http3.ListenAndServeQUIC(addr, certFile, keyFile, engine.Handler()) @@ -608,12 +675,17 @@ func (engine *Engine) RunQUIC(addr, certFile, keyFile string) (err error) { // RunListener attaches the router to a http.Server and starts listening and serving HTTP requests // through the specified net.Listener func (engine *Engine) RunListener(listener net.Listener) (err error) { - debugPrint("Listening and serving HTTP on listener what's bind with address@%s", listener.Addr()) + debugPrint( + "Listening and serving HTTP on listener what's bind with address@%s", + listener.Addr(), + ) defer func() { debugPrintError(err) }() if engine.isUnsafeTrustedProxies() { - debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + - "Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.") + debugPrint( + "[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.", + ) } err = http.Serve(listener, engine.Handler()) diff --git a/go.mod b/go.mod index 035c2de..6d471fc 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,11 @@ module github.com/gin-gonic/gin -go 1.21.0 +go 1.22.5 + +toolchain go1.23.1 require ( + git.vinchent.xyz/vinchent/go-web v0.0.0-20240929215000-f0fc7ee2cb65 github.com/bytedance/sonic v1.11.6 github.com/gin-contrib/sse v0.1.0 github.com/go-playground/validator/v10 v10.20.0 @@ -28,17 +31,18 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect - github.com/klauspost/cpuid/v2 v2.0.9 // indirect - github.com/kr/pretty v0.3.1 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/onsi/ginkgo/v2 v2.9.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect go.uber.org/mock v0.4.0 // indirect - golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect + golang.org/x/arch v0.8.0 // indirect golang.org/x/crypto v0.25.0 // indirect golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect golang.org/x/mod v0.17.0 // indirect @@ -46,3 +50,5 @@ require ( golang.org/x/text v0.16.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect ) + +replace git.vinchent.xyz/vinchent/go-web/ => ./../../ diff --git a/go.sum b/go.sum index 55a2162..469ffbd 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +git.vinchent.xyz/vinchent/go-web v0.0.0-20240929215000-f0fc7ee2cb65 h1:7sHTzY0WpgX4UW2g+dp+icvRyfcreP1fknOJ7/EDvtY= +git.vinchent.xyz/vinchent/go-web v0.0.0-20240929215000-f0fc7ee2cb65/go.mod h1:0t1NertSVVZD1FU7F6RkLb1Y5lcLU96pWygIOIeYjTI= 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= @@ -41,8 +43,9 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 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 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= 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= @@ -52,8 +55,9 @@ 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 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 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/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= @@ -62,7 +66,6 @@ github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= 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/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 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/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= @@ -90,8 +93,9 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= 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.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= @@ -103,6 +107,7 @@ golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/goweb_context.go b/goweb_context.go new file mode 100644 index 0000000..ddc1c73 --- /dev/null +++ b/goweb_context.go @@ -0,0 +1,27 @@ +package gin + +import "git.vinchent.xyz/vinchent/go-web/framework" + +// Engine handles the bind process + +func (engine *Engine) Bind(provider framework.ServiceProvider) error { + return engine.container.Bind(provider) +} + +func (engine *Engine) IsBound(key string) bool { + return engine.container.IsBound(key) +} + +// Context handle the use process. + +func (ctx *Context) Make(name string) (interface{}, error) { + return ctx.container.Make(name) +} + +func (ctx *Context) MustMake(name string) interface{} { + return ctx.container.MustMake(name) +} + +func (ctx *Context) MakeNew(name string, params []interface{}) (interface{}, error) { + return ctx.container.MakeNew(name, params) +}