Gone框架介绍28 - 使用goner.IsDefault 将Goner设置为接口的默认实现

gone是可以高效开发Web服务的Golang依赖注入框架
github地址:https://github.com/gone-io/gone
文档地址:https://goner.fun/zh/

文章目录

  • 使用`goner.IsDefault(...)`将Goner设置为接口的默认实现
    • 从内置组件goner/logrus的构造函数讲起
    • 按类型注入的歧义性
    • 使用GonerId做具名注入
    • 带来的好处
    • 注意gone.IsDefault的参数
    • 注册Goner时,也可以不使用构造函数
    • 可以多次使用IsDefault,给同一个Goner添加为多个接口的默认实现

使用goner.IsDefault(...)将Goner设置为接口的默认实现

从内置组件goner/logrus的构造函数讲起

查看goner/logrus的源代码,其构造函数的代码如下:

func NewLogger() (gone.Goner, gone.GonerId, gone.GonerOption) {log := &logger{Logger: logrus.StandardLogger(),}log.ResetLog()return log, gone.IdGoneLogger, gone.IsDefault(new(gone.Logger))
}

如果使用 cemetery.Bury(NewLogger())将Logger注册到框架,将会为gone.Logger接口添加默认实现。这个特性Gone v1.x版本新添加的,目的是为了解决按类型注入的“歧义性问题”。

按类型注入的歧义性

在Gone框架中,没有限制注册到框架同类型的Goner的数量,也不应该做这样的限制;然而这样却带来一个问题,如果多个Goners同时实现了某个接口,在注入该接口时,语义上是不明确的。
在v0.x版本中,遇到这种情况会先注册的那一个;选择第一个注册的Goner虽然能解决一定问题,但是这种依赖是隐形的潜规则,不是一个优秀的设计。

使用GonerId做具名注入

在 Gone v0.x版本中,如果需要依赖gone.Logger接口,如果对匿名嵌入的属性进行注入只能使用GonerId做具名注入:

type ServiceX struct {gone.Flaggone.Logger `gone:"gone-logger"`
}

原因是,匿名嵌入gone.LoggerServiceX等于实现了gone.Logger接口,如果再按类型匿名注入gone.Logger接口到Logger属性,可能会导致自己注入到自己的属性上,不符合期望。

在 Gone v1.x版本中,NewLogger()函数返回的gone.GonerOption参数中,添加了IsDefault(new(gone.Logger)),Goner在注册时会被设置为gone.Logger的默认实现。
框架在给gone.Logger类型的属性进行依赖注入的装配过程中,会优先选择类型的他的默认实现。这样按类型注入,也能唯一指向一个实现,消除了歧义性问题。

带来的好处

在 Gone v0.x版本中,注入组件一般都使用GonerId做具名注入;然而GonerId是不在IDE工具的提范围内的,编写代码是需要记住或者查询GonerId,增加了使用心智负担。
在 Gone v1.x版本中,使用IsDefault(...)将Goner设置为某个接口的默认实现,可以解决这个问题。同时,Gone v1.x版本,内置组件全部使用了IsDefault(...),使用时可以放心的按类型注入:

type ServiceX struct {gone.Flaggone.Logger     `gone:"*"` //注入Loggergone.XormEngine `gone:"*"` //注入xorm 引擎redis.Cache     `gone:"*"` //注入redis缓存// ...
}

注意gone.IsDefault的参数

gone.IsDefault是一个函数,返回的是一个gone.GonerOption,函数的功能是获取接口的类型包装为gone.GonerOption;接口作为golang的一种类型定义,是不能作为参数的,只能通过接口的指针间接传递类型信息。

注册Goner时,也可以不使用构造函数


type myImplementation struct {gone.Flag
}
// ...
// 对myImplementation实现gone.Logger接口
//...func Priest(cemetery gone.Cemetery) {cemetery.Bury(&myImplementation{}, gone.IsDefault(new(gone.Logger)))
}

可以多次使用IsDefault,给同一个Goner添加为多个接口的默认实现

例如:

type X interface {}
type Y interface {}type myImplementation struct {gone.Flag
}func Priest(cemetery gone.Cemetery) {cemetery.Bury(&myImplementation{},gone.IsDefault(new(X)),gone.IsDefault(new(Y)))
}type user struct {gone.FlagX `gone:"*"`Y `gone:"*"`
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/29848.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式注册中心如何保证数据一致性

分布式注册中心保证数据一致性主要依赖于一些核心的设计原则、技术和策略。以下是一些关键的方法和步骤: 1、使用分布式协调服务 如ZooKeeper、Etcd等,这些服务提供了分布式锁、分布式配置管理等功能,非常适合作为注册中心的数据存储。它们…

Python uWSGI 安装配置

Python uWSGI 安装配置 1. 引言 uWSGI是一个高性能的HTTP服务器,它实现了WSGI、uwsgi和HTTP等协议。它是用C编写的,旨在提供高性能和低资源消耗的Web服务。uWSGI广泛应用于Python Web应用程序,如Django、Flask等。本文将介绍如何在Python环境中安装和配置uWSGI。 2. 安装…

openEuler2203SP1自定义镜像,ks自动化安装

需求: 1、legacy启动 2、/boot分区1G,剩余给/ 3、创建root密码和一个普通用户 4、最小化安装(选上development、legacy-unix、security-tools、standard) 5、关闭firewalld、selinux 6、增加安装vim、ntpdate、iptables、ex…

SpringBoot配置第三方专业缓存技术jetcache方法缓存方案

jetcache方法缓存 我们可以给每个方法配置缓存方案 JetCache 是一个基于 Java 的缓存库,支持多种缓存方案和缓存策略,主要用于提升应用程序的性能和响应速度。它提供了多种缓存模式和特性,可以根据需求选择合适的缓存方案。 JetCache 的主…

认识QML

为什么使用Qt Quick? Qt4的设计用于满足开发者在主流桌面操作系统上有一套表现一致的窗口组件可以 使用。如今Qt的使用者面临了新的问题,他们需要提供可触碰交互的用户界面以满 足软件界面需求,并在主流桌面操作系统和移动操作系统上实现这些…

问题解决:局域网下多台电脑实现共享打印机

看了很多篇解决措施,都没有解决,自己鼓弄了好久,终于解决了,如下步骤所示,实测好用。 首先先保证本电脑已打开网络共享 其次关闭防火墙(有时会出现奇怪问题,最好关闭) 接着访问IP…

Scikit-Learn支持向量机回归

Scikit-Learn支持向量机回归 1、支持向量机回归1.1、最大间隔与SVM的分类1.2、软间隔最大化1.3、支持向量机回归1.4、支持向量机回归的优缺点2、Scikit-Learn支持向量机回归2.1、Scikit-Learn支持向量机回归API2.2、支持向量机回归初体验2.3、支持向量机回归实践(加州房价预测…

TikTok账号养号的流程分享

对于很多刚开始运营TikTok的新手小白来说,都会有一个同样的疑问,那就是:TikTok到底需不需要养号?这里明确告诉大家是需要养号的,今天就把我自己实操过的养号经验和策略总结出来,分享给大家。 一、什么是Ti…

国产24位I2S输入+192kHz立体声DAC音频数模转换器CJC4344

CJC4344是一款立体声数模转换芯片,内含插值滤波器、multi bit数模转换器、输出模拟滤波器。CJC4344系列支持大部分的音频数据格式。CJC4344基于一个带线性模拟低通滤波器的四阶multi-bitΔ-Σ调制器,而且本芯片可以通过检测信号频率和主时钟频率&#xf…

【面试八股总结】Redis数据结构及底层实现

一、五种基本数据结构 Redis 提供了丰富的数据类型,常见的有五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合&#xff0…

负载均衡(DR)

负载均衡(DR) 1.实验环境 准备三台机器网络使用NAT模式DR模式要求DIP与RIP必须在同一个王段及广播域关闭防火墙与selinux 2.分发器配置 #安装分发器并启动 [rootlocalhost ~]# yum -y install ipvsadm [rootlocalhost ~]# systemctl start ipvsadm #上…

华为鸿蒙 adb

安卓应用程序安装在鸿蒙手机上,使用adb开启服务失败 查找原因后: 1. 鸿蒙有自己的adb,叫hdc 文档中心 2. 可以打个鸿蒙的apk,调用hdc 3. 可以尝试降低应用android api版本,使adb在鸿蒙系统中可以使用

harmony鸿蒙下实现bc交互的方式和方法

前言 最近在研究harmony操作系统下的交互,因此写一篇文章记录一下。 解决的问题 本篇文章主要是来写解决如果兼容android或者ios的交互,这样子避免h5页面的二次开发,节省资源。 交互的种类 交互对于harmony来说其实只有一种,…

C语言中的内存动态管理

1.为什么有动态内存管理 int a20;//开辟4个字节 int arr[10]{0};//开辟40个字节 上述的代码有两个特点 1.开辟空间的大小是固定的。 2.数组在申明的时候已经固定了大小,无法更改。 这样写代码不够灵活,所以c语言中引入了动态内存管理,让程序…

MySQL指令收集

一、数据定义语言 (DDL): CREATE DATABASE database_name; - 创建新的数据库。 USE database_name; - 选择要使用的数据库。 SHOW DATABASES; - 列出所有数据库。 DROP DATABASE database_name; - 删除数据库。 CREATE TABLE table_name (column definitions); …

Springboot整合Kafka消息队列服务实例

一、Kafka相关概念 1、关于Kafka的描述 Kafka是由Apache开源,具有分布式、分区的、多副本的、多订阅者,基于Zookeeper协调的分布式处理平台,由Scala和Java语言编写。通常用来搜集用户在应用服务中产生的动作日志数据,并高速的处…

Milvus 2.4 向量库安装部署

1、linux 已有docker环境 2、安装fio命令 yum install -y fio 2、mkdir test-data fio --rwwrite --ioenginesync --fdatasync1 --directorytest-data --size2200m --bs2300 --namemytest ctrlc 3、lscpu 4、docker -v 6、安装docker compose组件 yum -y install python3-…

Maven下载安装、环境配置(超详细)(包括Windows、IDEA)

目录 一、引言 二、下载和安装 Maven (1)首先保证 Java 的环境是正常的。 1、电脑桌面上右击 " 此电脑 ",点击属性。 2、点击高级系统设置。 3、点击环境变量。 4、找到系统变量中的 Path。 5、点击新建,然后把…

结合简单工厂和工厂方法模式:实现灵活的对象创建

前言 在软件开发过程中,创建对象的方式直接影响代码的灵活性和可维护性。设计模式提供了一种解决复杂问题的方法,其中简单工厂模式和工厂方法模式是两种常用的创建型模式。在这篇文章中,我们将结合这两种模式,通过一个实际案例&a…

深度剖析ElasticSearch分页原理与深分页问题|ES深分页问题|ES分页原理剖析

文章目录 ES分页|Paginate search resultsES深分页的问题一页获取数据量太大,报错分页深度太大,报错官方解释 其他解决方案Search after解决两个问题 有没有深分页查询的必要性?search after & PIT的使用方式1.创建pit2.首次查询3.之后的…