Heim  >  Artikel  >  Backend-Entwicklung  >  Was ist Go-Sprachabhängigkeitsinjektion?

Was ist Go-Sprachabhängigkeitsinjektion?

青灯夜游
青灯夜游Original
2023-01-18 16:41:241727Durchsuche

In der Go-Sprache ist die Abhängigkeitsinjektion (DI) ein Entwurfsmuster, das bei Bedarf Abhängigkeiten zwischen Komponenten entkoppelt. Verschiedene Komponenten können über eine einheitliche Schnittstelle Objekte und Zustände in anderen Komponenten abrufen. Der Vorteil der Abhängigkeitsinjektion ist die Entkopplung; und die Entkopplung kann weitere Vorteile bringen: verbesserte Code-Skalierbarkeit, verbesserte Code-Wartbarkeit, einfachere Unit-Tests usw.

Was ist Go-Sprachabhängigkeitsinjektion?

Die Betriebsumgebung dieses Tutorials: Windows 7-System, GO Version 1.18, Dell G3-Computer.

Was ist Abhängigkeitsinjektion?

Als ich dieses Wort zum ersten Mal hörte, war ich verwirrt. Es war schwer auszusprechen. Vielleicht denken viele Studenten, die Frühling studiert haben, dass dies sehr grundlegendes und leicht verständliches Wissen ist, aber weil ich es noch nie vor Java und Frühling gelernt habe Deshalb war ich sehr verwirrt, als ich zum ersten Mal auf dieses Wort stieß.

Abhängigkeitsinjektion, der englische Name ist Abhängigkeitsinjektion, kurz DI. Das Wort Abhängigkeit ist leicht zu verstehen. Beim Softwaredesign gibt es große und kleine Abhängigkeiten von Architekturmodulen bis hin zu funktionalen Methoden.

Zum Beispiel muss neues B vor neuem A erstellt werden. A hängt von B ab. Zu diesem Zeitpunkt können wir sagen, dass B eine Abhängigkeit von A ist. A kontrolliert B. Es besteht eine Kopplungsbeziehung zwischen AB und dem Code Designidee ist die beste lose Kopplung, die erreicht werden kann. Wenn B eines Tages transformiert werden muss, muss auch A transformiert werden. Möglicherweise ist dies eine Abhängigkeit, aber wenn es eine Reihe von Abhängigkeiten zwischen A->B->C->D->E->F gibt, wird die Transformation sehr mühsam sein.

Zu diesem Zeitpunkt ist etwas erforderlich, um die starke Kopplung zwischen ihnen zu entkoppeln. Wir können die Macht von A an B übergeben. Diese Art von Idee wird „Inversion of Control (IOC Inversion Of Control)“ genannt, und dieser Dritte wird als IOC-Container bezeichnet. Was der IOC-Container tun muss, ist, ein neues B zu erstellen und dann diese Instanz von B in A zu injizieren. Dann kann A normalerweise die auf B basierende Methode verwenden. Dieser Prozess wird als Abhängigkeitsinjektion bezeichnet, und diese Methode wird auf Basis von IOC aufgerufen Abhängigkeitsinjektion. Einfach ausgedrückt ist die Abhängigkeitsinjektion (DI) ein Entwurfsmuster, das Abhängigkeiten zwischen Komponenten entkoppelt. Bei Bedarf können verschiedene Komponenten über eine einheitliche Schnittstelle Objekte und Zustände in anderen Komponenten abrufen. Das Schnittstellendesign der Go-Sprache vermeidet viele Situationen, in denen Abhängigkeitsinjektions-Frameworks von Drittanbietern verwendet werden müssen (z. B. Java usw.). Unsere Injektionslösung bietet nur sehr wenige Injektionslösungen, die denen in Dager oder Guice ähneln, und konzentriert sich auf die Vermeidung der manuellen Konfiguration von Abhängigkeiten zwischen Objekten und Komponenten.

Die Vorteile der AbhängigkeitsinjektionWenn Sie die Idee der Abhängigkeitsinjektion verstehen, sollten Sie auch den größten Vorteil verstehen, den sie mit sich bringt – die Entkopplung.

Und die Entkopplung kann weitere Vorteile bringen: verbesserte Code-Skalierbarkeit, verbesserte Code-Wartbarkeit, einfachere Unit-Tests usw.

Wie implementiert man also die Abhängigkeitsinjektion?

In Java gibt es die folgenden Methoden:

    Setter-Methodeninjektion: Implementieren Sie die öffentliche Set-Methode bestimmter Eigenschaften, damit der externe Container das Objekt des abhängigen Typs aufrufen kann.
  • Schnittstellenbasierte Injektion: Implementieren Sie eine spezifische Schnittstelle für externe Container, um Objekte des abhängigen Typs zu injizieren.
  • Konstruktorbasierte Injektion: Implementieren Sie den Konstruktor mit bestimmten Parametern und übergeben Sie beim Erstellen eines neuen Objekts das Objekt des abhängigen Typs.
  • Annotationsbasierte Injektion: Fügen Sie dem Code bestimmte Schlüsselwörter hinzu, um eine Injektion zu erreichen.
  • Anmerkungen sind die gebräuchlichste Methode. Sie werden wie Kommentare nicht als Code ausgeführt, sondern sind speziell für die Lektüre anderer gedacht. Aber die Leser von Annotationen sind ausschließlich Menschen, und die wichtigsten Leser von Annotationen sind neben Menschen Frameworks oder Precompiler.

Go Dependency Injection-WireWire ist eine annotationsbasierte Abhängigkeitsinjektionsmethode. wire ist ein Open-Source-Abhängigkeitsinjektionstool von Google. Wir müssen wire nur die Abhängigkeiten zwischen Typen in einer speziellen go-Datei mitteilen Generieren Sie automatisch Code für uns, helfen Sie uns beim Erstellen von Objekten bestimmter Typen und stellen Sie deren Abhängigkeiten zusammen.

wire hat zwei Grundkonzepte: Provider (Konstruktor) und Injector (Injektor). wire是 Google 开源的一个依赖注入工具,我们只需要在一个特殊的go文件中告诉wire类型之间的依赖关系,它会自动帮我们生成代码,帮助我们创建指定类型的对象,并组装它的依赖。

wire有两个基础概念,Provider(构造器)和Injector(注入器)。

通过提供provider函数,让wire知道如何产生这些依赖对象。wire根据我们定义的injector函数签名,生成完整的injector函数,injector函数是最终我们需要的函数,它将按依赖顺序调用provider

wire的要求很简单,新建一个wire.go文件(文件名可以随意),创建我们的初始化函数。比如,我们要创建并初始化一个Mission

Durch die Bereitstellung der Funktion provider teilen Sie wire mit, wie diese abhängigen Objekte generiert werden. wire generiert eine vollständige injector-Funktion basierend auf der von uns definierten injector-Funktion. Die injector-Funktion ist das, was wir letztendlich haben Bedarf. Funktion, die provider in Abhängigkeitsreihenfolge aufruft. 🎜🎜Die Anforderungen von wire sind sehr einfach. Erstellen Sie eine neue wire.go-Datei (der Dateiname kann beliebig sein) und erstellen Sie unsere Initialisierungsfunktion. Wenn wir beispielsweise ein Mission-Objekt erstellen und initialisieren möchten, können wir Folgendes tun: 🎜
//+build wireinject

package main

import "github.com/google/wire"

func InitMission(name string) Mission {
  wire.Build(NewMonster, NewPlayer, NewMission)
  return Mission{}
}

Sie können die Anmerkung in der ersten Zeile sehen: +build wireinject, was darauf hinweist, dass es sich um einen Injektor handelt. +build ist eigentlich eine Funktion der Go-Sprache. Ähnlich wie bei der bedingten Kompilierung von C/C++ können beim Ausführen von go build einige Optionen übergeben werden, und anhand dieser Optionen wird entschieden, ob bestimmte Dateien kompiliert werden. Das wire-Tool verarbeitet nur Dateien mit wireinject, daher muss unsere wire.go-Datei dies hinzufügen. +build其实是 Go 语言的一个特性。类似 C/C++ 的条件编译,在执行go build时可传入一些选项,根据这个选项决定某些文件是否编译。wire工具只会处理有wireinject的文件,所以我们的wire.go文件要加上这个。

在函数中,我们调用wire.Build()将创建Mission所依赖的类型的构造器传进去。例如,需要调用NewMission()创建Mission类型,NewMission()接受两个参数一个Monster类型,一个Player类型。Monster类型对象需要调用NewMonster()创建,Player类型对象需要调用NewPlayer()创建。所以NewMonster()NewPlayer()我们也需要传给wire

In der Funktion rufen wir wire.Build() auf, um den Konstruktor des Typs zu übergeben, von dem Mission abhängt. Beispielsweise müssen Sie NewMission() aufrufen, um einen Mission-Typ zu erstellen, der zwei Parameter und ein Monster-Typ. Ein <code>Player-Typ. Objekte vom Typ Monster müssen durch Aufruf von NewMonster() erstellt werden, und Objekte vom Typ Player müssen durch Aufruf von NewPlayer() erstellt werden. . Daher müssen wir auch NewMonster() und NewPlayer() an wire übergeben.

Nach dem Schreiben der Datei „wire.go“ und dem Ausführen des Befehls „wire“ wird automatisch eine Datei „wire_gen.go“ generiert.

// Code generated by Wire. DO NOT EDIT.

//go:generate wire
//+build !wireinject

package main

// Injectors from wire.go:

func InitMission(name string) Mission {
  player := NewPlayer(name)
  monster := NewMonster()
  mission := NewMission(player, monster)
  return mission
}

Sie können sehen, dass Wire automatisch die InitMission-Methode für uns generiert. Bei dieser Methode werden Spieler, Monster und Mission nacheinander initialisiert. Dann müssen wir diese InitMission nur noch in unserer Hauptfunktion aufrufen.

func main() {
  mission := InitMission("dj")

  mission.Start()
}

Vor der Abhängigkeitsinjektion sah unser Code so aus:

func main() {
  monster := NewMonster()
  player := NewPlayer("dj")
  mission := NewMission(player, monster)

  mission.Start()
}

Ist es nicht viel einfacher? Es gibt hier nur drei Objektinitialisierungen. Wenn es mehr wären, würden Sie die Vorteile der Abhängigkeitsinjektion möglicherweise nicht erkennen.

Zum Beispiel:

wire.go文件:
// +build wireinject
// The build tag makes sure the stub is not built in the final build.

package di

import (
	"github.com/google/wire"
)

//go:generate kratos t wire
func InitApp() (*App, func(), error) {
	panic(wire.Build(dao.Provider, service.Provider, http.New, grpc.New, NewApp))
}

实现文件:
//dao
var Provider = wire.NewSet(New, NewDB, NewRedis)
//service
var Provider = wire.NewSet(New, wire.Bind(new(pb.Server), new(*Service)))


生成的wire_gen.go 文件:
func InitApp() (*App, func(), error) {
	redis, cleanup, err := dao.NewRedis()
	if err != nil {
		return nil, nil, err
	}
	db, cleanup2, err := dao.NewDB()
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	daoDao, cleanup3, err := dao.New(redis, db)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	serviceService, cleanup4, err := service.New(daoDao)
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	engine, err := http.New(serviceService)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	server, err := grpc.New(serviceService)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	app, cleanup5, err := NewApp(serviceService, engine, server)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	return app, func() {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}

Also, was genau ist Abhängigkeitsinjektion?

Es geht nur um Kapselung und Entkopplung.

【Verwandte Empfehlungen: Go-Video-Tutorial, Programmierunterricht

】🎜

Das obige ist der detaillierte Inhalt vonWas ist Go-Sprachabhängigkeitsinjektion?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn