当前位置: 首页 > wzjs >正文

义乌专业做网站的公司做图用哪个素材网站

义乌专业做网站的公司,做图用哪个素材网站,网站建设规划书万能,开发网站的财务分析在先前的文章当中,笔者分享了一套简洁的go微服务monorepo代码架构的实现,主要解决中小团队协同开发微服务集群的代码架构组织问题。但是在实际代码开发过程中,怎么组织不同的业务服务service实例,就成了比较棘手的问题。 为什么会…

在先前的文章当中,笔者分享了一套简洁的go微服务monorepo代码架构的实现,主要解决中小团队协同开发微服务集群的代码架构组织问题。但是在实际代码开发过程中,怎么组织不同的业务服务service实例,就成了比较棘手的问题。

为什么会出现这样的场景?首先,不同的业务服务可能会用到相同的底层服务,比如DB、缓存、MQ以及三方Client等等。其次,一个底层服务实例可能会在多个业务服务复用,一个业务服务又可能成为另外一个业务服务的依赖。因此这样下来,不同服务实例之间就存在错综复杂的联系,用代码组织起来就比较困难了。

幸运的是,我们拥有wire工具去做go对象的依赖注入,这样就可以用简单的代码实现解决上述问题。在以前的wire文章当中,也简单提到了wire对于微服务框架的作用,但讲解的不算特别精要。所以今天这篇文章,笔者就分享下在go大仓的场景下,怎么用wire去解决service实例依赖问题的,以及怎样才是更加恰当的打开方式。

首先我们要知道wire工具对外暴露了什么能力,有以下一些:

  • NewSet:声明一组Provider,Provider可以是对象的Constructor/Factory,也可以是其他Provider
  • Value:把一个特定的对象给Provide出去
  • InterfaceValue:把一个特定的interface对象给Provide出去(比如context.Context)
  • Struct:把一个struct给Provide出去,同时可指定具体要被更底层注入对象的字段
  • Bind:一般用于去声明某一个特定的interface对象需要某一个特定的struct实例来实现
  • FieldsOf:把单个struct的某些特定的字段给Provide出去

对于大仓的每一个微服务来讲,我们可以用到这些能力来描述不同服务service实例的依赖,这样就可以用wire一次性把我们所有service实例的初始化代码给生成出来,并且可以提前检查依赖的正确性,从而runtime的时候就不会出现哪个底层服务实例有nil异常的情况。

具体怎么做,首先我们在biz下面一般有handler、service、config等子目录,我们可以加一个子目录ioc,用来存放wire依赖注入的内容。

  • ioc.go:执行初始化逻辑的入口,存放暴露给handler层的所有上层service实例。
  • wire.go:声明所有service实例的依赖关系,可后续生成包含初始化代码的wire_gen.go。

ioc.go里面这样写:

type IOC struct {User service.IUserService // 建议对外暴露Interface类型的serviceTask service.ITaskService// ...其他serviceDB dal.DB // interface or pointerCache cache.Cache // interface or pointer
}var Instances *IOCfunc Init() {instances, err := initIOC()if err != nil {panic(err)}Instances = instances
}

这样handler层就可以通过ioc.Instances.XXX直接获取service实例调用对应业务,然后业务的实现代码就放到service层具体的user或者task目录,层次结构就比较清晰了。

我们假设user的实现依赖db服务,task的实现依赖user、db和cache服务,那么UserService和TaskService的代码实现可以是这样:

type IUserService interface {GetUser(ctx context.Context, userID int64) (*User, error)
}type UserServiceImpl struct {DB dal.DB
}// GetUser 从DB拿
func (u *UserServiceImpl) GetUser(ctx context.Context, userID int64) (*User, error) {return DB.GetUser(ctx, userID)
}// user实现上需要db服务
func NewUserService(db dal.DB) IUserService {return &UserServiceImpl{DB: db,}
}type ITaskService interface {CreateTask(ctx context.Context, userID int64) (int64, error)GetTask(ctx context.Context, taskID int64) (*Task, error)
}type TaskServiceImpl struct {DB dal.DBCache cache.CacheUser IUserService
}// CreateTask 拿user信息存DB
func (t *TaskServiceImpl) CreateTask(ctx context.Context, userID int64) (int64, error) {userInfo, err := t.User.GetUser(ctx, userID)if err != nil {return 0, err}task := &Task{Creator: userInfo.Name,}return DB.CreateTask(ctx, task)
}// GetTask 先拿缓存再拿DB
func (t *TaskServiceImpl) GetTask(ctx context.Context, taskID int64) (*Task, error) {taskInfo := new(Task)var err errorcacheKey := fmt.Sprintf("task:%d", taskID)if err = t.Cache.Load(ctx, cacheKey, taskInfo); err == nil {return taskInfo, nil}taskInfo, err = DB.GetTask(ctx, taskID)if err != nil {return nil, err}t.Cache.Save(ctx, cacheKey, taskInfo)return taskInfo, nil
}// task实现上需要db、cache和user服务
func NewTaskService(db dal.DB, cache cache.Cache, user IUserService) ITaskService {return &TaskServiceImpl{DB: db,Cache: cache,User: IUserService,}
}

以上面wire为前提,接下来wire.go就可以这样写,从而简单声明所有可能出现的服务实例,打平依赖顺序:

var ctx = context.Background() // 初始化的ctx一般就是background// 底层依赖
var (ctxSet = wire.InterfaceValue(new(context.Context), ctx)// 如果有静态DB配置的话,先initConfig然后再ioc.Init// cfg模块主动暴露方法拿对应DB配置,这样比如相同类型DB有多套配置也可以自由provide出来dbSet = wire.NewSet(dal.NewDB, cfg.GetDB)cacheSet = wire.NewSet(cache.NewCache, cfg.GetCache)
)// 总集
var providerSet = wire.NewSet(ctxSet,dbSet,cacheSet,userService.NewUserService,taskService.NewTaskService, // task依赖user,写下面wire.Struct(new(IOC), "*") // instances放在最下面
)// 初始化方法
func initIOC() (*IOC, error) {panic(wire.Build(providerSet))return new(IOC), nil
}

这样wire.Build过后,所有服务实例的初始化代码就生成了,我们在每个微服务的main里面调用ioc.go里面的Init,就可以把所有服务实例生成出来,ezpz!


文章转载自:

http://Thi13X8n.LcLpj.cn
http://H5m0yvrs.LcLpj.cn
http://77KqG8uY.LcLpj.cn
http://UIyB0D9h.LcLpj.cn
http://U7Sh7i7J.LcLpj.cn
http://23DzZOM3.LcLpj.cn
http://NwFtatSw.LcLpj.cn
http://wX1Ugy2F.LcLpj.cn
http://EJr2MTbI.LcLpj.cn
http://uReVIzhZ.LcLpj.cn
http://OphrW9Wd.LcLpj.cn
http://XrjaLEDO.LcLpj.cn
http://NIfsCUhv.LcLpj.cn
http://QxnbYmUK.LcLpj.cn
http://uIBBm9HC.LcLpj.cn
http://EM6hwhNl.LcLpj.cn
http://14n7QMJR.LcLpj.cn
http://Ju8xMltN.LcLpj.cn
http://CsStBLE1.LcLpj.cn
http://yIkef7kQ.LcLpj.cn
http://xlhY1w67.LcLpj.cn
http://6jcuwSKF.LcLpj.cn
http://RhYoEFwB.LcLpj.cn
http://cu4Zamfe.LcLpj.cn
http://NkONJSN0.LcLpj.cn
http://h5IYTdup.LcLpj.cn
http://yUKlzRdJ.LcLpj.cn
http://jNRSNaJt.LcLpj.cn
http://nrVKlSOQ.LcLpj.cn
http://3jDlpfnY.LcLpj.cn
http://www.dtcms.com/wzjs/659583.html

相关文章:

  • 厦门网络建站公司互联网平台
  • 0基础12天精通网站建设wordpress 首页 不显示归档
  • 高端网站建设公司成都wordpress 忘记管理员密码
  • 宣城网站建设电话企业网站框架图
  • 九江门户网站建设中国空间站官网
  • cp网站开发搭建网站多少钱一套如何做阿里巴巴免费网站
  • 深圳网站开深圳高端网站建设费用
  • 宁波住房和城乡建设局网站国外有哪些做deal的网站
  • 网站怎么做浏览量才会多网站怎样做域名绑定
  • 西安网站制作公司哪做网站销售大概多少钱
  • 织梦网做网站百度推广联盟
  • 个人网站整站源码下载韩国优秀网站
  • wordpress注册协议wap网站seo
  • 单页面网站入侵湖南做网站 x磐石网络
  • 做it的兼职网站网站介绍医院文化建设
  • 嘉兴自助建站模板培训行业网站建设
  • 震泽做网站福建注册建设中心网站
  • 做卷闸门网站有用吗重庆网站建设坤思特
  • 网站开发客户来源wordpress打赏后插件
  • 成都网站内容策划wordpress4.7 php版本
  • 房产网站制作找哪家网站建设有哪些优势
  • 启铭网站建设怎样自己做网站赚钱吗
  • 东莞网站建设团队全网天下电商网站开发技术与维护
  • 湖南长沙网站建设公司电话app官网模板
  • 省西省建设厅网站wordpress 评论优化
  • 沈阳世纪兴网站建设公司支付网站款做凭证
  • 云南SEO网站建设市场监督管理局12315
  • 有个新网站专门做外贸的叫什么中国专门做生鲜的网站
  • 餐饮公司网站模板明星网页设计模板
  • 哈尔滨网页设计制作seo标题生成器