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

网站制作能在家做吗门户类网站备案

网站制作能在家做吗,门户类网站备案,建e室内设计网 周婷,东阳房产网文章目录 前言依赖注入是什么依赖注入的好处是什么结构图应用程序上下文接口上下文管理器暴露的功能使用示例最后 前言 你好,我是醉墨居士,欢迎来到我的博客,今天带领大伙使用Go语言实现依赖自动注入,我们不会使用其它的第三方库…

文章目录

  • 前言
  • 依赖注入是什么
  • 依赖注入的好处是什么
  • 结构图
  • 应用程序上下文接口
  • 上下文管理器
  • 暴露的功能
  • 使用示例
  • 最后

前言

你好,我是醉墨居士,欢迎来到我的博客,今天带领大伙使用Go语言实现依赖自动注入,我们不会使用其它的第三方库,项目核心代码不到100行,是Go语言初学者难得的精简项目

依赖注入是什么

依赖注入(Dependency Injection,简称DI)是一种设计模式,用于实现控制反转(Inversion of Control,简称IoC)原则。它的核心思想是将对象的依赖关系从内部管理转移到外部管理,从而降低对象之间的耦合度,提高代码的灵活性和可测试性

依赖注入的好处是什么

降低耦合度:通过将依赖关系从对象内部转移到外部,可以降低对象之间的耦合度。这样,对象只需要知道它需要什么,而不需要知道如何获取这些依赖

提高可测试性:依赖注入使得单元测试变得更加容易。在测试时,可以轻松地替换掉真实的依赖对象,使用模拟对象(Mock Object)或存根(Stub)来进行测试,从而隔离被测试代码

增强可维护性:由于依赖关系被明确地定义和管理,代码的可读性和可维护性得到了提高。当需要修改依赖关系时,只需要在配置或注入点进行修改,而不需要修改对象内部的代码

促进代码重用:依赖注入使得组件可以更容易地在不同的上下文中重用。因为组件不直接创建和管理自己的依赖,所以它们可以在不同的环境中被配置和使用

支持面向接口编程:依赖注入鼓励使用接口来定义依赖关系,而不是具体的实现类。这使得代码更加灵活,因为可以在运行时替换不同的实现,而不需要修改调用代码

简化对象创建:依赖注入容器(如Spring的ApplicationContext)可以自动管理对象的创建和生命周期,开发者不需要手动创建和管理这些对象,从而简化了代码

结构图

现在介绍一下我们依赖注入这个小项目的结构图
在这里插入图片描述

应用程序上下文接口

type BeanProvider func() reflect.Valuetype ApplicationContext interface {Inject(provider BeanProvider, name string) errorAutowise(obj any, name string) error
}

上下文管理器

type context struct {namedConatiner map[string]BeanProvidertypedContainer map[reflect.Type]BeanProvider
}// 实现依赖注入
func (c *context) Inject(provider BeanProvider, name string) error {if provider == nil {return fmt.Errorf("inject: provider can not be nil")}if name == "" {// type injectty := provider().Type()if _, ok := c.typedContainer[ty];ok {return fmt.Errorf("inject: %v is ambiguous", ty)}c.typedContainer[ty] = provider} else {// name injectif _, ok := c.namedConatiner[name];ok {return fmt.Errorf("inject: %v is ambiguous", name)}c.namedConatiner[name] = provider}return nil
}// 实现自动装配
func (c *context) Autowise(val any, name string) error {if val == nil {return fmt.Errorf("inject: nil value")}rv := reflect.ValueOf(val)if rv.Kind() != reflect.Ptr {return fmt.Errorf("inject: %v is not a pointer", rv)}ri := reflect.Indirect(rv)rt := ri.Type()var provider BeanProviderif name == "" {// type autowiseprovider = c.typedContainer[rt]} else {// name autowiseprovider = c.namedConatiner[name]}if provider == nil {return fmt.Errorf("inject: %v is not found", name)}obj := provider()if obj.CanConvert(rt) {ri.Set(obj.Convert(rt))return nil}return fmt.Errorf("inject: value can not convert to %s", ri.Type())
}

暴露的功能

func defaultBeanProvider(v any) BeanProvider {return func() reflect.Value {return reflect.ValueOf(v)}
}// 对外暴露依赖注入的能力,name为空字符串时表示默认使用类型注入
func Inject(obj any, name string) error {return instance.Inject(defaultBeanProvider(obj), name)
}// 对外暴露依赖注入的能力,name为空字符串时表示默认使用类型注入
func DeepInject(provider BeanProvider, name string) error {return instance.Inject(provider, name)
}// 对外暴露自动装配的能力,name为空字符串时表示默认使用类型自动装配
func Autowise[T any](obj *T, name string) error {return instance.Autowise(obj, name)
}

使用示例

示例代码

package mainimport ("fmt""github.com/zm50/injector""reflect"
)type TwoString struct {s1 *strings2 *string
}func main() {// 通过类型注入变量,注入一个string类型的变量var injectString string = "醉墨居士"err := injector.Inject(injectString, "")if err != nil {panic(err)}// 通过类型装配变量,通过string类型自动装配变量var autowiseString stringerr = injector.Autowise(&autowiseString, "")if err != nil {panic(err)}fmt.Println("类型注入和装配的演示结果")fmt.Println("注入的变量:", injectString, "装配的变量:", autowiseString)// 通过名称注入变量var injectName string = "醉墨"var injectString2 string = "居士"err = injector.Inject(injectString2, injectName)if err != nil {panic(err)}// 通过名称装配变量var autowiseString2 stringerr = injector.Autowise(&autowiseString2, "醉墨")if err != nil {panic(err)}fmt.Println("名称注入和装配的演示结果")fmt.Println("注入的变量:", injectString2, "装配的变量:", autowiseString2)// 通过类型注入结构体指针injectStruct := &TwoString{}injectStruct.s1 = new(string)injectStruct.s2 = new(string)*injectStruct.s1 = "醉墨"*injectStruct.s2 = "居士"err = injector.Inject(injectStruct, "")if err != nil {panic(err)}// 通过类型装配结构体指针autowiseStruct := &TwoString{}err = injector.Autowise(&autowiseStruct, "")if err != nil {panic(err)}fmt.Println("结构体指针注入和装配的演示结果")fmt.Println("注入的变量:", injectStruct, *(injectStruct.s1), *(injectStruct.s2))fmt.Println("装配的变量:", autowiseStruct, *(autowiseStruct.s1), *(autowiseStruct.s2))fmt.Println("是否相等:", injectStruct == autowiseStruct, injectStruct.s1 == autowiseStruct.s1, injectStruct.s2 == autowiseStruct.s2)// 自定义依赖注入和装配的能力,演示自定义依赖注入和装配的能力实现深拷贝,大家可以也根据自己的需求自定义依赖注入和装配的能力injectStruct2 := &TwoString{s1: new(string), s2: new(string),}*(injectStruct2.s1) = "醉墨"*(injectStruct2.s2) = "居士"provider := func() reflect.Value {twoString := TwoString{}twoString.s1 = new(string)twoString.s2 = new(string)*twoString.s1 = *injectStruct.s1*twoString.s2 = *injectStruct.s2return reflect.ValueOf(twoString)}err = injector.DeepInject(provider, "")if err != nil {panic(err)}autowiseStruct2 := &TwoString{}err = injector.Autowise(autowiseStruct2, "")if err != nil {panic(err)}fmt.Println("自定义规则实现结构体深拷贝注入和装配的演示结果")fmt.Println("注入的变量:", injectStruct2, *(injectStruct2.s1), *(injectStruct2.s2))fmt.Println("装配的变量:", autowiseStruct2, *(autowiseStruct2.s1), *(autowiseStruct2.s2))fmt.Println("是否相等:", injectStruct2 == autowiseStruct2, injectStruct2.s1 == autowiseStruct2.s1, injectStruct2.s2 == autowiseStruct2.s2)
}

示例结果
在这里插入图片描述

最后

至此,各位我们已经一起完成了这个依赖注入的小项目
我是醉墨居士,我们下篇博客见

http://www.yayakq.cn/news/302274/

相关文章:

  • 商城微网站如何做网站群管理系统哪个好
  • 备案网站域名和主机关系装修工人
  • 旅游电子商务网站模板和业务多一样的平台
  • 营销网站建设内容域名交易网站源代码下载
  • 特产网站开发的好处seo优化多久能上排名
  • 专业电子科技网站建设中国建设官方网
  • 网站平台建设咨询合同程序员培训机构哪家好
  • 营销网站模版外贸网站建设 杭州
  • 浙江小九天建设集团网站小程序定制开发深圳公司
  • htm网站制作一千元左右最好的手机
  • 网站建设公司华网天下买赠两年平面设计师的前景和收入
  • 可以免费制作网页的网站网站开发职业前景
  • 网站设计方案怎么写福州网站建设价格
  • 南昌珠峰网站建设刘淼 网站开发
  • 怎么利用wordpress管理站点网站开发公司长春
  • 微网站开发案例淄博seo怎么选择
  • 承德网站开发网站建设流程 知乎
  • 免费建站哪家好如何查看一个网站是用什么程序做的
  • 切图做网站如何做做网站需要购买网站空间吗
  • 上海网站建设服务站霸网络企业网站开发研究现状
  • 汕头网站建设开发专业网站开发哪家公司好
  • 哈尔滨服务专业的建站南磨房网站建设公司
  • 集团网站设计方案企业形象设计vi手册
  • 物流公司在哪做网站如何网上开店卖东西
  • 站长 网站ipthinkphp5菜鸟教程
  • 做任务网站有哪些内容wordpress密码正确登录不
  • 响应式网站 拖拽买购网中国10大品牌网
  • 蓝海国际版网站建设凡科网上商城
  • 个人业余做网站怎么弄建立网站定制
  • 营销型网站页面布局北京市地铁建设公司网站