iris的依赖注入

iris的依赖注入

本篇文章介绍一下其他语言也有的设计概念,就是依赖注入,以及在iris如何利用这种设计概念让程序的组件职能分工,并且能每个组件专注在各自的逻辑开发。

本文同步放置於此

iris的依赖注入

本篇介绍iris的依赖注入,首先先由什麽是依赖注入开始,让大家对於这种设计概念有一些初步的概念,然後再带到如何在iris利用依赖注入的方式来开发,所有先跟大家介绍依赖注入。

依赖注入

提到依赖注入就不能不提另一个概念就是控制反转IoC,这个概念的起因是因为有个人想说为什麽都是类别决定需要什麽组件呢,为什麽不能反过来让外部决定类别需要的组件呢,所以就成了今天要说明的主题依赖注入。
这时候读者会好奇那怎麽由外部决定类别要相依的组件呢,简单来说类别只要相依介面interface就好了,不要相依到实体,如此就可以由外部来决定这个类别要相依的实体是什麽,换一句话来说就是在外部来注入类别所依赖的组件,所以接下来开始介绍怎麽在iris中实作依赖注入的设计概念。

iris的依赖注入

iris的依赖注入文件中有详细的说明如何在iris中用依赖注入的方式开发,不过其内容有点复杂,所以我们直接看iris官方依赖注入的范例,虽然个范例的程序码很多,但是对於依赖注入的内容只有一些,所以接下来针对这些内容跟大家说明。
首先请大家看一下下列的例子

// file: web/routes/movie.go
package routes

import (
	"errors"

	"github.com/kataras/iris/v12/_examples/dependency-injection/overview/datamodels"
	"github.com/kataras/iris/v12/_examples/dependency-injection/overview/services"

	"github.com/kataras/iris/v12"
)

// Movies returns list of the movies.
// Demo:
// curl -i http://localhost:8080/movies
func Movies(service services.MovieService) (results []datamodels.Movie) {
	return service.GetAll()
}

// MovieByID returns a movie.
// Demo:
// curl -i http://localhost:8080/movies/1
func MovieByID(service services.MovieService, id uint64) (movie datamodels.Movie, found bool) {
	return service.GetByID(id) // it will throw 404 if not found.
}

// UpdateMovieByID updates a movie.
// Demo:
// curl -i -X PUT -F "genre=Thriller" -F "poster=@/Users/kataras/Downloads/out.gif" http://localhost:8080/movies/1
func UpdateMovieByID(ctx iris.Context, service services.MovieService, id uint64) (datamodels.Movie, error) {
	// get the request data for poster and genre
	file, info, err := ctx.FormFile("poster")
	if err != nil {
		return datamodels.Movie{}, errors.New("failed due form file 'poster' missing")
	}
	// we don't need the file so close it now.
	file.Close()

	// imagine that is the url of the uploaded file...
	poster := info.Filename
	genre := ctx.FormValue("genre")

	return service.UpdatePosterAndGenreByID(id, poster, genre)
}

// DeleteMovieByID deletes a movie.
// Demo:
// curl -i -X DELETE -u admin:password http://localhost:8080/movies/1
func DeleteMovieByID(service services.MovieService, id uint64) interface{} {
	wasDel := service.DeleteByID(id)
	if wasDel {
		// return the deleted movie's ID
		return iris.Map{"deleted": id}
	}
	// right here we can see that a method function can return any of those two types(map or int),
	// we don't have to specify the return type to a specific type.
	return iris.StatusBadRequest
}

上面是需要传入一个MovieService的handler而这个MovieService就是我们定义的interface所以我们这个handler直接相依这个interface而不在乎这interface的实作是什麽,所以接下来我们只要注册实作这interface`的实体并注入即可,所以我们再看看下面例子来了解如何注入。

// file: main.go
package main

import (
	"github.com/kataras/iris/v12/_examples/dependency-injection/overview/datasource"
	"github.com/kataras/iris/v12/_examples/dependency-injection/overview/repositories"
	"github.com/kataras/iris/v12/_examples/dependency-injection/overview/services"
	"github.com/kataras/iris/v12/_examples/dependency-injection/overview/web/middleware"
	"github.com/kataras/iris/v12/_examples/dependency-injection/overview/web/routes"

	"github.com/kataras/iris/v12"
)

func main() {
	app := iris.New()
	app.Logger().SetLevel("debug")

	// Load the template files.
	app.RegisterView(iris.HTML("./web/views", ".html"))

	// Create our movie repository with some (memory) data from the datasource.
	repo := repositories.NewMovieRepository(datasource.Movies)

	app.Party("/hello").ConfigureContainer(func(r *iris.APIContainer) {
		r.Get("/", routes.Hello)
		r.Get("/{name}", routes.HelloName)
	})

	app.Party("/movies").ConfigureContainer(func(r *iris.APIContainer) {
		// Create our movie service, we will bind it to the movie app's dependencies.
		movieService := services.NewMovieService(repo)
		r.RegisterDependency(movieService)

		// Add the basic authentication(admin:password) middleware
		// for the /movies based requests.
		r.Use(middleware.BasicAuth)

		r.Get("/", routes.Movies)
		r.Get("/{id:uint64}", routes.MovieByID)
		r.Put("/{id:uint64}", routes.UpdateMovieByID)
		r.Delete("/{id:uint64}", routes.DeleteMovieByID)
	})

	// http://localhost:8080/hello
	// http://localhost:8080/hello/iris
	// http://localhost:8080/movies ("admin": "password")
	// http://localhost:8080/movies/1
	app.Listen(
		// Start the web server at localhost:8080
		"localhost:8080",
		// enables faster json serialization and more:
		iris.WithOptimizations,
	)
}

相信大家都可以看到我们绑定handler之前会呼叫Party("/movies").ConfigureContainer(func(r *iris.APIContainer)这一段,并且呼叫r.RegisterDependency(movieService)来呼叫注册service如此在绑定handler之後当handler被呼叫时会注册该service给其使用了。
至於service以及repository的实作就不是本篇文章的重点,还请读者们自行阅读了。

结论

本篇介绍了依赖注入的内容以及如何在iris上使用依赖注入的方式进行开发,希望这篇文章可以帮助大家都程序开发。


<<:  许多有趣的变数!如何使用 Postman 尝试 Nutanix 的 API

>>:  [2020铁人赛] Day30 - .net core第一阶段结束,感谢IT邦!

[Day 08] tinyML开胃菜Arduino IDE上桌(上)

书接上回,讲了一大堆如何做出好吃的AI咖哩饭,那到底要如何开始才能当上新一代的「AI食神」呢? 首先...

【Day30】函式常见的陷阱题

今天来讲解 this 相关的陷阱题 第一题 myName = '全域'; var person = ...

Golang 学习笔记-- 快速上手/重点整理 - 3 - Array, Slice

宣告方式 var array_name = [length]datatype{values} var...

[Day 10] 第一主餐 pt.3-Djgnao与网页间的连结

在上一篇我们成功建立了django专案 今天我们就要来加上一些东西,并且让我们的django跑起来啦...

Day9 - pandas(4)Series与DataFrame的运算

Series间的运算: Series在互相做数学运算时 会根据对应index的位置来做互动 如没有对...