Heim > Artikel > Backend-Entwicklung > Was ist Go-Sprachabhängigkeitsinjektion?
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.
Die Betriebsumgebung dieses Tutorials: Windows 7-System, GO Version 1.18, Dell G3-Computer.
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.
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:
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
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
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!