{"id":13413450,"url":"https://github.com/go-kata/kinit","last_synced_at":"2025-03-14T19:32:16.808Z","repository":{"id":57563181,"uuid":"332459515","full_name":"go-kata/kinit","owner":"go-kata","description":"GO Dependency Injection","archived":false,"fork":false,"pushed_at":"2021-06-12T14:27:19.000Z","size":108,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-07-31T20:52:21.145Z","etag":null,"topics":["constructor","dependency-injection","factory","go","initializer","ioc","reflection"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/go-kata.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-24T13:41:41.000Z","updated_at":"2024-02-22T10:05:24.000Z","dependencies_parsed_at":"2022-08-31T05:01:36.808Z","dependency_job_id":null,"html_url":"https://github.com/go-kata/kinit","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-kata%2Fkinit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-kata%2Fkinit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-kata%2Fkinit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-kata%2Fkinit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/go-kata","download_url":"https://codeload.github.com/go-kata/kinit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243635439,"owners_count":20322941,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["constructor","dependency-injection","factory","go","initializer","ioc","reflection"],"created_at":"2024-07-30T20:01:40.685Z","updated_at":"2025-03-14T19:32:16.529Z","avatar_url":"https://github.com/go-kata.png","language":"Go","funding_links":[],"categories":["杂项","Miscellaneous","Microsoft Office","Dependency Injection"],"sub_categories":["依赖注入","Dependency Injection"],"readme":"# KInit\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/go-kata/kinit.svg)](https://pkg.go.dev/github.com/go-kata/kinit)\n[![codecov](https://codecov.io/gh/go-kata/kinit/branch/master/graph/badge.svg?token=NBFR4LKON8)](https://codecov.io/gh/go-kata/kinit)\n[![Report Card](https://goreportcard.com/badge/github.com/go-kata/kinit)](https://goreportcard.com/report/github.com/go-kata/kinit)\n[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)\n\n**[Usage examples](https://github.com/go-kata/examples)**\n\n## Installation\n\n`go get github.com/go-kata/kinit`\n\n## Status\n\n**This is a beta version.** API is not stabilized for now.\n\n## Versioning\n\n*Till the first major release* minor version (`v0.x.0`) must be treated as a major version\nand patch version (`v0.0.x`) must be treated as a minor version.\n\nFor example, changing of version from `v0.1.0` to `v0.1.1` indicates compatible changes,\nbut when version changes `v0.1.1` to `v0.2.0` this means that the last version breaks the API.\n\n## How to use\n\nThis library provides the global [IoC](https://en.wikipedia.org/wiki/Inversion_of_control) container which does\nthe automatic [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection):\n\n```go\nkinit.Global()\n```\n\nIf you need a local one (e.g. for tests), you can create it as following:\n\n```go\nctr := kinit.NewContainer()\n```\n\nA local container must be filled up with *constructors* and *processors* manually whereas the global one\ncan be filled up when [initializing packages](https://golang.org/doc/effective_go.html#init).\n\n### Constructors\n\nConstructors are entities that create *objects* (dependencies for injection in context of the DI). They have the\nfollowing interface:\n\n```go\ntype Constructor interface {\n\t\n\tType() reflect.Type\n\t\n\tParameters() []reflect.Type\n\t\n\tCreate(a ...reflect.Value) (reflect.Value, kdone.Destructor, error)\n\t\n}\n```\n\nHere `Type` returns a type of object to create, `Parameters` returns types of other objects required to create\nthis object and finally `Create` creates and returns a new object and its destructor (use`kdone.Noop`, not nil,\nif object has no destructor).\n\nTo register a constructor in the container use the `Provide` method.\n\nThe container allows to have only one constructor for each type. However, the `reflect.Type` is the interface, and\nyou can implement it as you want, e.g. as following:\n\n```go\ntype NamedType stuct {\n\treflect.Type\n\tName string\n}\n```\n\nJust keep in mind that the container uses a simple comparison of `reflect.Type` instances when looks up for\nnecessary constructors (as well as processors and already created objects).\n\n### Processors\n\nProcessors are entities that process already created objects. The container applies processors immediately after\nthe object creation and before an object will be injected as a dependency at the first time. Processors have the\nfollowing interface:\n\n```go\ntype Processor interface {\n\t\n\tType() reflect.Type\n\t\n\tParameters() []reflect.Type\n\n\tProcess(obj reflect.Value, a ...reflect.Value) error\n\t\n}\n```\n\nHere `Type` returns a type of object to process, `Parameters` returns types of other objects required to process\nthis object and finally `Process` processes an object.\n\nTo register a processor in the container use the `Attach` method.\n\nThe container allows to have an unlimited number of processors for each type but doesn't guarantee the order of\ntheir calling.\n\n### Functors\n\nFunctors represent functions to be run in the container and have the following interface:\n\n```go\ntype Functor interface {\n\t\n\tParameters() []reflect.Type\n\t\n\tCall(a ...reflect.Value) ([]Functor, error)\n\t\n}\n```\n\nHere `Parameters` returns types of objects required to call a function and `Call` calls a function and may return\n*further functors*.\n\nTo run functors in the container use the `Run` method.\n\nAt the start of run the container creates so-called *arena* that holds all created objects (only one object\nfor each type). If some object required as a dependency is already on the arena it will be used, otherwise\nit will be firstly created and processed. All objects that are on the arena at the end of run will be\nautomatically destroyed.\n\nThe container runs given functors sequentially. Their dependencies are resolved recursively using registered\nconstructors and processors. If functor (let's call it *branched*) returns further functors, the container runs\nall of them before continue running functors following the branched one. This is called the *Depth-First Run*.\n  \n## KInitX\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/go-kata/kinit/kinitx.svg)](https://pkg.go.dev/github.com/go-kata/kinit/kinitx)\n\nThis subpackage provides the expansion set includes default handy implementations of main library interfaces\nalong with other handy tools. In most cases the **KInitX** is all you need to use the entire **KInit** functionality.\n\nThere are following implementations:\n\n**Constructor** represents a constructor based on a function. It accepts `func(...) T`, `func(...) (T, error)` and\n`func(...) (T, kdone.Destructor, error)` signatures where `T` is an arbitrary Go type.\n\n```go\nkinitx.MustProvide(func(config *Config) (*Object, kdone.Destructor, error) { ... })\n```\n\n**Opener** represents a constructor based on a function that creates an implementation of the `io.Closer` interface.\nIt accepts `func(...) C` and `func(...) (C, error)` signatures where `C` is an arbitrary implementation of the\n`io.Closer` interface.\n\n```go\nkinitx.MustProvide(func(logger *log.Logger) (*sql.DB, error) { ... })\n```\n\n**Initializer** represents a memberwise initializer of a struct. It accepts a template struct like a `YourType{}`\nand a template struct pointer like a `(*YourType)(nil)` or `new(YourType)`.\n\n```go\nkinitx.MustProvide((*Config)(nil))\n```\n\n**Binder** represents a pseudo-constructor that casts an object to an interface. It accepts an interface pointer\nlike a `(*YourInterface)(nil)`.\n\n```go\nkinitx.MustBind((*StorageInterface)(nil), (*PostgresStrorage)(nil))\n```\n\n**Processor** represents a processor based on a function. It accepts `func(T, ...)` and `func(T, ...) error`\nsignatures where `T` is an arbitrary Go type.\n\n```go\nkinitx.MustAttach((*Object).SetOptionalProperty)\n```\n\n**Functor** represents a functor based on a function. It accepts `func(...)`, `func(...) error`,\n`func(...) (kinit.Functor, error)` and `func(...) ([]kinit.Functor, error)` signatures.\n\n```go\nkinitx.MustRun(func(app *Application) error { ... })\n```\n\n## KInitQ\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/go-kata/kinit/kinitq.svg)](https://pkg.go.dev/github.com/go-kata/kinit/kinitq)\n\nThe DI mechanism provided by the main library is reflection-based and works in the runtime. However, this subpackage\nmakes it possible to validate the dependency graph semi-statically thanks to build tags.\n\nJust add two main functions as following:\n\n`main.go`\n\n```go\n// +build !inspect\n\npackage main\n\nimport \"github.com/go-kata/kinit/kinitx\"\n\nfunc main() { kinitx.MustRun(EntryPoint) }\n```\n\n`main_inspect.go`\n\n```go\n// +build inspect\n\npackage main\n\nimport \"github.com/go-kata/kinit/kinitx\"\n\nfunc main() { kinitx.MustInspect(nil) }\n```\n\nNow to validate the dependency graph of your program just run:\n\n`go run -tags inspect`\n\nExample output:\n\n```\n2 errors occurred:\n    #1 🠖 cyclic dependency: *config.Config 🠖 config.Loader 🠖 *config.FileLoader 🠖 *config.Config\n    #2 🠖 unsatisfied dependency: *sql.DB 🠖 *log.Logger\n```\n\nFor more details learn the documentation and explore examples.\n\n## Putting all together\n\nIn the [github.com/go-kata/examples](https://github.com/go-kata/examples) repository you can find examples of\nhow may the code uses this library looks like.\n\n## References\n\n**[KDone](https://github.com/go-kata/kdone)** is the library that provides tools for destroying objects.\n\n**[KError](https://github.com/go-kata/kerror)** is the library that provides tools for handling errors.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgo-kata%2Fkinit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgo-kata%2Fkinit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgo-kata%2Fkinit/lists"}