diff --git a/vblog/README.md b/vblog/README.md index 35f919f..c2cc746 100644 --- a/vblog/README.md +++ b/vblog/README.md @@ -318,4 +318,53 @@ curl --location 'http://127.0.0.1:8080/vblog/api/v1/tokens' \ ### 问题 ++ 手动管理: main, 自己组装对象, 业务越复杂,组装难度越高 +![](./docs/oop.png) + ++ ioc: 引入了一个中间层, 这个中间层负责对象的管理, 自己对象自己去ioc获取依赖,而不是我们开发者 把依赖传递给他,完成 对象的 依赖 由被动 变成主动, ioc, 依赖倒置 + +![](./docs/ioc.png) + +### 基于mcube ioc来改造 + +![alt text](image.png) + +https://www.mcube.top/docs/framework/ + +1. 对象注册到ioc: 把我们的对象实现了1个IOC对象(符合Ioc接口定义的对象), 可以通过继承基础类,直接实现接口ObjectImpl + + 2 APIHandler: TokenApiHandler, BlogApiHandler + + 3 Controller: UserServiceImpl, TokenServiceImpl, BlogServiceImpl + +对象注册 +```go +func init() { + ioc.Controller().Registry(&TokenServiceImpl{}) +} + +// 定义一个struct, 用于实现 UserService就是刚才定义的接口 +// 怎么才能判断这个结构体没有实现这个接口 +type TokenServiceImpl struct { + ioc.ObjectImpl + + // user service + user user.AdminService +} + +func (*TokenServiceImpl) Name() string { + return token.AppName +} + +// 他需要自己去获取依赖,通过ioc +func (i *TokenServiceImpl) Init() error { + i.user = user.GetService() + return nil +} +``` + +对象获取 +```go +func GetService() Service { + return ioc.Controller().Get(AppName).(Service) +} +``` \ No newline at end of file diff --git a/vblog/apps/registry.go b/vblog/apps/registry.go new file mode 100644 index 0000000..7124ee0 --- /dev/null +++ b/vblog/apps/registry.go @@ -0,0 +1,7 @@ +package apps + +import ( + _ "gitlab.com/go-course-project/go17/vblog/apps/blog/impl" + _ "gitlab.com/go-course-project/go17/vblog/apps/token/impl" + _ "gitlab.com/go-course-project/go17/vblog/apps/user/impl" +) diff --git a/vblog/apps/token/impl/impl.go b/vblog/apps/token/impl/impl.go index f00efa7..bc8fd47 100644 --- a/vblog/apps/token/impl/impl.go +++ b/vblog/apps/token/impl/impl.go @@ -5,29 +5,35 @@ import ( "fmt" "github.com/infraboard/mcube/v2/exception" + "github.com/infraboard/mcube/v2/ioc" "github.com/infraboard/mcube/v2/ioc/config/datasource" "gitlab.com/go-course-project/go17/vblog/apps/token" "gitlab.com/go-course-project/go17/vblog/apps/user" - "gitlab.com/go-course-project/go17/vblog/apps/user/impl" ) -var TokenService token.Service = &TokenServiceImpl{ - user: impl.UserService, -} - -func NewTokenService(user user.AdminService) token.Service { - return &TokenServiceImpl{ - user: impl.UserService, - } +func init() { + ioc.Controller().Registry(&TokenServiceImpl{}) } // 定义一个struct, 用于实现 UserService就是刚才定义的接口 // 怎么才能判断这个结构体没有实现这个接口 type TokenServiceImpl struct { + ioc.ObjectImpl + // user service user user.AdminService } +func (*TokenServiceImpl) Name() string { + return token.AppName +} + +// 他需要自己去获取依赖,通过ioc +func (i *TokenServiceImpl) Init() error { + i.user = user.GetService() + return nil +} + // IssueToken implements token.Service. func (t *TokenServiceImpl) IssueToken(ctx context.Context, in *token.IssueTokenRequest) (*token.Token, error) { if err := in.Validate(); err != nil { diff --git a/vblog/apps/token/impl_test.go b/vblog/apps/token/impl_test.go index 6d1e7db..94f2df3 100644 --- a/vblog/apps/token/impl_test.go +++ b/vblog/apps/token/impl_test.go @@ -5,7 +5,6 @@ import ( "testing" "gitlab.com/go-course-project/go17/vblog/apps/token" - "gitlab.com/go-course-project/go17/vblog/apps/token/impl" ) var ( @@ -20,7 +19,7 @@ var ( // https://gitee.com/infraboard/go-course/blob/master/day09/go-hash.md#bcrypt func TestIssueToken(t *testing.T) { req := token.NewIssueTokenRequest("admin", "123456") - ins, err := impl.TokenService.IssueToken(ctx, req) + ins, err := token.GetService().IssueToken(ctx, req) if err != nil { t.Fatal(err) } @@ -29,7 +28,7 @@ func TestIssueToken(t *testing.T) { func TestValidateToken(t *testing.T) { req := token.NewValidateTokenRequest("51bf49f5-12a2-406a-baf8-3f99d985b41a") - ins, err := impl.TokenService.ValidateToken(ctx, req) + ins, err := token.GetService().ValidateToken(ctx, req) if err != nil { t.Fatal(err) } diff --git a/vblog/apps/token/interface.go b/vblog/apps/token/interface.go index b9152d7..a6aa998 100644 --- a/vblog/apps/token/interface.go +++ b/vblog/apps/token/interface.go @@ -3,9 +3,18 @@ package token import ( "context" + "github.com/infraboard/mcube/v2/ioc" "github.com/infraboard/mcube/v2/ioc/config/validator" ) +const ( + AppName = "token" +) + +func GetService() Service { + return ioc.Controller().Get(AppName).(Service) +} + // 业务域 type Service interface { UserService diff --git a/vblog/apps/user/impl/impl.go b/vblog/apps/user/impl/impl.go index 4754647..34fd074 100644 --- a/vblog/apps/user/impl/impl.go +++ b/vblog/apps/user/impl/impl.go @@ -3,16 +3,28 @@ package impl import ( "context" + "github.com/infraboard/mcube/v2/ioc" "github.com/infraboard/mcube/v2/ioc/config/datasource" "gitlab.com/go-course-project/go17/vblog/apps/user" "golang.org/x/crypto/bcrypt" ) -var UserService user.Service = &UserServiceImpl{} +func init() { + ioc.Controller().Registry(&UserServiceImpl{}) +} + +// int(10) -> (int)(10) +var _ user.Service = (*UserServiceImpl)(nil) // 定义一个struct, 用于实现 UserService就是刚才定义的接口 // 怎么才能判断这个结构体没有实现这个接口 type UserServiceImpl struct { + // 这个对象 就实现ioc Object接口, 他就能被放到ioc + ioc.ObjectImpl +} + +func (i *UserServiceImpl) Name() string { + return user.AppName } // DescribeUser implements user.Service. diff --git a/vblog/apps/user/impl_test.go b/vblog/apps/user/impl_test.go index 5ef84d0..b83506d 100644 --- a/vblog/apps/user/impl_test.go +++ b/vblog/apps/user/impl_test.go @@ -5,7 +5,6 @@ import ( "testing" "gitlab.com/go-course-project/go17/vblog/apps/user" - "gitlab.com/go-course-project/go17/vblog/apps/user/impl" ) var ( @@ -22,7 +21,7 @@ func TestRegistry(t *testing.T) { req := user.NewRegistryRequest() req.Username = "test02" req.Password = "123456" - ins, err := impl.UserService.Registry(ctx, req) + ins, err := user.GetService().Registry(ctx, req) if err != nil { t.Fatal(err) } @@ -30,7 +29,7 @@ func TestRegistry(t *testing.T) { } func TestDescribeUser(t *testing.T) { - ins, err := impl.UserService.DescribeUser(ctx, &user.DescribeUserRequest{ + ins, err := user.GetService().DescribeUser(ctx, &user.DescribeUserRequest{ user.DESCRIBE_BY_USERNAME, "admin", }) if err != nil { @@ -38,5 +37,5 @@ func TestDescribeUser(t *testing.T) { } // // if ins.Password = in.Password - t.Log(ins.CheckPassword("1234567")) + t.Log(ins) } diff --git a/vblog/apps/user/interface.go b/vblog/apps/user/interface.go index a2401cb..0d704af 100644 --- a/vblog/apps/user/interface.go +++ b/vblog/apps/user/interface.go @@ -1,6 +1,19 @@ package user -import "context" +import ( + "context" + + "github.com/infraboard/mcube/v2/ioc" +) + +// 获取实现,从ioc +func GetService() Service { + return ioc.Controller().Get(AppName).(Service) +} + +const ( + AppName = "user" +) type Service interface { AdminService diff --git a/vblog/config/setup.go b/vblog/config/setup.go index fd598fd..9261606 100644 --- a/vblog/config/setup.go +++ b/vblog/config/setup.go @@ -4,6 +4,9 @@ import ( "os" "github.com/infraboard/mcube/v2/ioc" + + // 导入程序所有的对 + _ "gitlab.com/go-course-project/go17/vblog/apps" ) func LoadConfig() { diff --git a/vblog/docs/ioc.drawio b/vblog/docs/ioc.drawio new file mode 100644 index 0000000..ff4bcad --- /dev/null +++ b/vblog/docs/ioc.drawio @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vblog/docs/ioc.png b/vblog/docs/ioc.png new file mode 100644 index 0000000..d2c4cbe Binary files /dev/null and b/vblog/docs/ioc.png differ diff --git a/vblog/docs/oop.png b/vblog/docs/oop.png new file mode 100644 index 0000000..a06910a Binary files /dev/null and b/vblog/docs/oop.png differ diff --git a/vblog/image.png b/vblog/image.png new file mode 100644 index 0000000..2a78271 Binary files /dev/null and b/vblog/image.png differ diff --git a/vblog/main.go b/vblog/main.go index e60dd61..d68fb4a 100644 --- a/vblog/main.go +++ b/vblog/main.go @@ -5,9 +5,8 @@ import ( blogApi "gitlab.com/go-course-project/go17/vblog/apps/blog/api" blogImpl "gitlab.com/go-course-project/go17/vblog/apps/blog/impl" + "gitlab.com/go-course-project/go17/vblog/apps/token" tokenApi "gitlab.com/go-course-project/go17/vblog/apps/token/api" - tokenImpl "gitlab.com/go-course-project/go17/vblog/apps/token/impl" - userImpl "gitlab.com/go-course-project/go17/vblog/apps/user/impl" "github.com/gin-gonic/gin" "github.com/infraboard/mcube/v2/ioc/config/http" @@ -21,7 +20,7 @@ func main() { server := gin.Default() // 注册业务模块的路有 - tokenApi.NewTokenApiHandler(tokenImpl.NewTokenService(&userImpl.UserServiceImpl{})).Registry(server) + tokenApi.NewTokenApiHandler(token.GetService()).Registry(server) blogApi.NewBlogApiHandler(&blogImpl.BlogServiceImpl{}).Registry(server) // ... 50 个API // diff --git a/vblog/middleware/auth.go b/vblog/middleware/auth.go index 1f7862d..73428c6 100644 --- a/vblog/middleware/auth.go +++ b/vblog/middleware/auth.go @@ -9,8 +9,6 @@ import ( "github.com/infraboard/mcube/v2/exception" "github.com/infraboard/mcube/v2/http/gin/response" "gitlab.com/go-course-project/go17/vblog/apps/token" - "gitlab.com/go-course-project/go17/vblog/apps/token/impl" - userImpl "gitlab.com/go-course-project/go17/vblog/apps/user/impl" ) // // HandlerFunc defines the handler used by gin middleware as return value. @@ -30,7 +28,7 @@ func Auth(c *gin.Context) { accessToken = tkList[1] } // 2. 校验Token - tk, err := impl.NewTokenService(&userImpl.UserServiceImpl{}).ValidateToken(c.Request.Context(), token.NewValidateTokenRequest(accessToken)) + tk, err := token.GetService().ValidateToken(c.Request.Context(), token.NewValidateTokenRequest(accessToken)) if err != nil { response.Failed(c, exception.NewUnauthorized("令牌校验失败: %s", err)) c.Abort()