How to dependency inject database clients into structs in golang?

huangapple go评论79阅读模式
英文:

How to dependency inject database clients into structs in golang?

问题

我正在尝试使用依赖注入来在Go语言中的结构体中注入数据库客户端。不幸的是,我不太理解如何实现这一点,因为我在互联网上只看到了一些基本的例子,无法获得完整的图片。

我有一个Producer接口,其中有不同的实现。我还有一个用于redis/kafka的客户端来产生消息。

package producers

type IProducer interface {
	setMessageType(messageType string)
	setTopic(topic string)
	getMessageType() string
	getTopic() string
}

type Producer struct {
	messageType string
	topic       string
}
// producer implements the IProducer

type UserLocationProducer struct {
	Producer
}

func newUserLocationProducer() IProducer {
	return &UserLocationProducer{
		Producer: Producer{
			messageType: "user_location",
			topic:       "user_location",
		},
	}
}

Redis客户端代码

type RedisClient struct {
	pool *redis.Pool
}

func NewRedisClient(addr string, dn int, passwd string) *RedisClient {
	// 创建客户端的代码
	return client
}

现在我的问题是,如果我想将RedisClient注入到Producer中,我该如何实现。我基本上是从Java背景来的,在Java中,我会使用Spring来连接我的依赖项并自动连接依赖项。非常感谢任何指导。

英文:

I am trying to use dependency injection to inject a database client in the struct using go language. Unfortunately, I did not understand how this could be done as i only see basic examples in the internet from which i am unable to get complete picture.

I have a Producer interface which is having different implementations. I also have a client for redis/kafka to produce messages.

package producers

type IProducer interface {
	setMessageType(messageType string)
	setTopic(topic string)
	getMessageType() string
	getTopic() string
}

type Producer struct {
	messageType string
	topic       string
}
// producer implements the IProducer

type UserLocationProducer struct {
	Producer
}

func newUserLocationProducer() IProducer {
	return &UserLocationProducer{
		Producer: Producer{
			messageType: "user_location",
			topic:       "user_location",
		},
	}
}

Redis client code

type RedisClient struct {
	pool *redis.Pool
}

func NewRedisClient(addr string, dn int, passwd string) *RedisClient {
	// code to create client
	return client
}

Now my question is if i want to inject RedisClient into Producer how can i achieve it. I am basically from Java background where i will wire my dependencies using Spring and Autowiring the dependency. Any pointers is very much appreciated.

答案1

得分: 2

依赖注入可以通过使用接口来实现,在不同的客户端之间起到共通性的作用,例如下面是一种实现方式。

一个客户端接口,满足kafka/redis客户端的要求:

type Client interface{
    Publish(<message等字段>)
}

func (redisClient RedisClient) Publish(<message等字段>){
    //执行客户端操作
}

IProducer:设置客户端(kafka/redis)的新方法。

type IProducer interface {
    ...
    SetClient(client Client)
}

Producer:引用客户端的字段和设置方法。

type Producer struct {
    ...
    client Client
}

func (producer Producer)SetClient(clt Client){
    producer.client = clt
}

func (producer Producer)send(){
    client.Publish(<message等字段>)
}

可以为了测试目的对客户端接口进行模拟,并以相同的方式注入到Producer中。

此外,可以直接在创建Producer时设置client字段,只是使用setter方法可以提供更多的控制。

英文:

Dependency injection can be done here by using interfaces, which act as a commonality between the different clients, e.g. below is one of the ways this can be done.

A Client interface that both kafka/redis clients satisfy

type Client interface{
    Publish(&lt;message etc fields&gt;)
}

func (redisClient RedisClient) Publish(&lt;message etc fields&gt;){
    //Do client things
}

IProducer: new method to set client (kafka/redis).

type IProducer interface {
    ...
    SetClient(client Client)
}

Producer: field for reference to the client, and setter method,

type Producer struct {
    ...
    client Client
}

func (producer Producer)SetClient(clt Client){
    producer.client = clt
}

func (producer Producer)send(){
    client.Publish(&lt;message etc fields&gt;)
}

Client interface can be mocked for testing and injected same way into Producer

Also Instead of SetClient method field client can be set directly while creating Producer, Just that setter methods give a bit more control.

huangapple
  • 本文由 发表于 2022年8月27日 19:44:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/73510698.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定