繁体   English   中英

接口的依赖项注入问题

[英]issue with dependency injection with interface

我有提供与tcp连接一起工作的软件包,基本上是这样的:

package connpool

import (
    "io/ioutil"
    "net/http"
)

type ConnPool struct{}

func (pool *ConnPool) GetConn() Conn {
    return Conn{}
}

func (pool *ConnPool) ReleaseConnection(conn Conn)  {

}

type Conn struct{}

func (c Conn) FetchUrl(url string) ([]byte, error) {
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        return []byte{}, err
    }
    client := &http.Client{}
    resp, _ := client.Do(req)
    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    return body, nil
}

然后我尝试在另一个程序包中使用它,但按接口将其包装起来,因为我想用假connpool在测试环境中替换此程序包

package main

import (
    "connpool"
    "fmt"
)

func onlyDependencyOnConnPool() *connpool.ConnPool {
    return &connpool.ConnPool{}
}

type ConnPoolInterface interface {
    GetConn() ConnInterface
    ReleaseConnection(ConnInterface)
}

type ConnInterface interface {
    FetchUrl(string) ([]byte, error)
}

type Fetcher struct{}

func (f Fetcher) Fetch(cPool ConnPoolInterface) error {
    conn := cPool.GetConn()
    defer cPool.ReleaseConnection(conn)
    body, err := conn.FetchUrl("http://localhost:9200")
    fmt.Println("body: ", string(body))
    return err
}

func main() {
    pool := onlyDependencyOnConnPool()
    f := Fetcher{}
    f.Fetch(pool)
}

但是它将在编译时返回错误:

./main.go:34: cannot use pool (type *connpool.ConnPool) as type ConnPoolInterface in argument to f.Fetch:
    *connpool.ConnPool does not implement ConnPoolInterface (wrong type for GetConn method)
        have GetConn() connpool.Conn
        want GetConn() ConnInterface

有没有办法在每个文件中没有connpool导入的情况下通过接口包装此依赖项?

我只需要它来模拟测试环境中的http请求,就像这样(如果我要在connpool包中实现接口,则我必须在其中实现每个模拟结构,看起来就像是一团糟):

package main

import(
  "testing"
)

type FakeConnPool struct{}

func (pool *FakeConnPool) GetConn() FakeConn {
    return FakeConn{}
}

func (pool *FakeConnPool) ReleaseConnection(conn FakeConn)  {
}

type FakeConn struct{}

func (c FakeConn) FetchUrl(url string) ([]byte, error) {
  println(url)
  body := []byte(`{"status" : 200}`)
    return body, nil
}

func changeDependency() ConnPoolInterface {
  return &FakeConnPool{}
}
func TestBaz(t *testing.T)  {
  pool := changeDependency()
    f := Fetcher{}
    err := f.Fetch(pool)
  if err != nil {
    t.Errorf("error")
  }
}

第一步,将您对GetConn的声明稍微更改为以下内容:

func (pool *ConnPool) GetConn() ConnInterface {  // Conn -> ConnInterface
    return Conn{}
}

那应该满足ConnPoolInterface的接口。 您可能必须稍稍重新排列代码,以免之后出现循环依赖。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM