{"id":16092342,"url":"https://github.com/alecthomas/inject","last_synced_at":"2025-06-13T11:35:11.789Z","repository":{"id":66600206,"uuid":"50327918","full_name":"alecthomas/inject","owner":"alecthomas","description":"Guice-ish dependency injection for Go.","archived":false,"fork":false,"pushed_at":"2023-12-02T14:55:15.000Z","size":41,"stargazers_count":32,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-28T02:10:31.670Z","etag":null,"topics":["dependency-injection","go","injection"],"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/alecthomas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-01-25T05:18:53.000Z","updated_at":"2025-02-25T05:52:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"f2ed3f9b-f1e3-48a7-8dcb-71ee82d7d260","html_url":"https://github.com/alecthomas/inject","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Finject","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Finject/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Finject/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Finject/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alecthomas","download_url":"https://codeload.github.com/alecthomas/inject/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243871904,"owners_count":20361380,"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":["dependency-injection","go","injection"],"created_at":"2024-10-09T16:07:09.451Z","updated_at":"2025-03-17T17:30:56.344Z","avatar_url":"https://github.com/alecthomas.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Inject - Guice-ish dependency-injection for Go.\n[![](https://godoc.org/github.com/alecthomas/inject?status.svg)](http://godoc.org/github.com/alecthomas/inject) [![Build Status](https://travis-ci.org/alecthomas/inject.png)](https://travis-ci.org/alecthomas/inject) [![Gitter chat](https://badges.gitter.im/alecthomas.png)](https://gitter.im/alecthomas/Lobby)\n\nInject provides dependency injection for Go. For small Go applications,\nmanually constructing all required objects is more than sufficient. But for\nlarge, modular code bases, dependency injection can alleviate a lot of\nboilerplate.\n\nIn particular, Inject provides a simple way of wiring together modular\napplications. Each module contains configuration and logic to create the\nobjects it provides. The main application installs all of these modules, then\ncalls its main entry point using the injector. The injector resolves any\ndependencies of the main function and injects them.\n\n\u003c!-- MarkdownTOC --\u003e\n\n- [Example usage](#example-usage)\n- [Value bindings](#value-bindings)\n- [Singletons](#singletons)\n- [Literals](#literals)\n- [Mapping bindings](#mapping-bindings)\n- [Sequence bindings](#sequence-bindings)\n- [Named bindings](#named-bindings)\n- [Interfaces](#interfaces)\n- [Modules](#modules)\n- [Validation](#validation)\n\n\u003c!-- /MarkdownTOC --\u003e\n\n## Example usage\n\nThe following example illustrates a simple modular application.\n\nFirst, the main package installs configured modules and calls an entry point:\n\n```go\npackage main\n\nfunc run(db *mgo.Database, log *log.Logger) {\n  log.Println(\"starting application\")\n  // ...\n}\n\nfunc main() {\n  injector := New()\n  injector.Install(\n    \u0026MongoModule{URI: \"mongodb://db1.example.net,db2.example.net:2500/?replicaSet=test\u0026connectTimeoutMS=300000\"\"\"},\n    \u0026LoggingModule{Flags: log.Ldate | log.Ltime | log.Llongfile},\n  )\n  injector.Call(run)\n}\n```\n\nNext we have a simple Mongo module with a configurable URI:\n\n```go\npackage db\n\ntype MongoModule struct {\n  URI string\n}\n\nfunc (m *MongoModule) ProvideMongoDB() (*mgo.Database, error) {\n  return mgo.Dial(m.URI)\n}\n```\n\nThe logging package shows idiomatic use of inject; it is just a thin wrapper\naround normal Go constructors. This is the least invasive way of using\ninjection, and preferred.\n\n```go\npackage logging\n\n// LoggingModule provides a *log.Logger that writes log lines to a Mongo collection.\ntype LoggingModule struct {\n  Flags int\n}\n\nfunc (l *LoggingModule) ProvideMongoLogger(db *mgo.Database) *log.Logger {\n  return NewMongoLogger(db, l.Flags)\n}\n\ntype logEntry struct {\n  Text string `bson:\"text\"`\n}\n\nfunc NewMongoLogger(db *mgo.Database, flags int) *log.Logger {\n  return log.New(\u0026mongologWriter{c: db.C(\"logs\")}, \"\", flags)\n}\n\ntype mongoLogWriter struct {\n  buf string\n  c *mgo.Collection\n}\n\nfunc (m *mongoLogWriter) Write(b []byte) (int, error) {\n  m.buf = m.buf + string(b)\n  for {\n    eol := strings.Index(m.buf, \"\\n\")\n    if eol == -1 {\n      return len(b), nil\n    }\n    line := m.buf[:eol]\n    err := m.c.Insert(\u0026logEntry{line})\n    if err != nil {\n      return len(b), err\n    }\n    m.buf = m.buf[eol:]\n  }\n}\n```\n\n## Value bindings\n\nThe simplest form of binding simply binds a value directly:\n\n```go\ninjector.Bind(http.DefaultServeMux)\n```\n\n## Singletons\n\nFunction bindings are not singleton by default. For example, the following\nfunction binding will be called each time an int is requested:\n\n```go\nvalue := 0\ninjector.Bind(func() int {\n  value++\n  return value\n})\n```\n\nWrap the function in `Singleton()` to ensure it is called only once:\n\n```go\ninjector.Bind(Singleton(func() int {\n  return 10\n}))\n```\n\n## Literals\n\nTo bind a function as a value, use Literal:\n\n```go\ninjector.Bind(Literal(fmt.Sprintf))\n```\n\n## Mapping bindings\n\nMappings can be bound explicitly:\n\n```go\ninjector.Bind(Mapping(map[string]int{\"one\": 1}))\ninjector.Bind(Mapping(map[string]int{\"two\": 2}))\ninjector.Bind(Mapping(func() map[string]int { return map[string]int{\"three\": 3} }))\ninjector.Call(func(m map[string]int) {\n  // m == map[string]int{\"one\": 1, \"two\": 2, \"three\": 3}\n})\n```\n\nOr provided via a Provider method that includes the term `Mapping` in its name:\n\n```go\nfunc (m *MyModule) ProvideStringIntMapping() map[string]int {\n  return map[string]int{\"one\": 1, \"two\": 2}\n}\n```\n\n## Sequence bindings\n\nSequences can be bound explicitly:\n\n```go\ninjector.Bind(Sequence([]int{1, 2}))\ninjector.Bind(Sequence([]int{3, 4}))\ninjector.Bind(Sequence(func() []int { return  []int{5, 6} }))\ninjector.Call(func(s []int) {\n  // s = []int{1, 2, 3, 4, 5, 6}\n})\n```\n\nOr provided via a Provider method that includes the term `Sequence` in its name:\n\n```go\nfunc (m *MyModule) ProvideIntSequence() []int {\n  return []int{1, 2}\n}\n```\n\n## Named bindings\n\nThe equivalent of \"named\" values can be achieved with type aliases:\n\n```go\ntype UserName string\n\ninjector.Bind(UserName(\"Bob\"))\ninjector.Call(func (username UserName) {})\n```\n\n## Interfaces\n\nInterfaces can be explicitly bound to implementations:\n\n```go\ntype stringer string\nfunc (s stringer) String() string { return string(s) }\n\ninjector.BindTo((*fmt.Stringer)(nil), stringer(\"hello\"))\ninjector.Call(func(s fmt.Stringer) {\n  fmt.Println(s.String())\n})\n```\n\nHowever, if an explicit interface binding is not present, any bound object\nimplementing that interface will be used:\n\n```go\ninjector.Bind(stringer(\"hello\"))\ninjector.Call(func(s fmt.Stringer) {\n  fmt.Println(s.String())\n})\n```\n\nSimilarly, if sequences/maps of interfaces are injected, explicit bindings\nwill be used first, then inject will fallback to sequences/maps of objects\nimplementing that interface.\n\n## Modules\n\nSimilar to injection frameworks in other languages, inject includes the\nconcept of modules. A module is a struct whose methods are providers. This is\nuseful for grouping configuration data together with providers.\n\nAny method starting with \"Provide\" will be bound as a Provider. If the method\nname contains \"Multi\" it will not be a singleton provider. If the method name\ncontains \"Sequence\" it will contribute to a sequence of its return type.\nSimilarly, if the method name contains \"Mapping\" it will contribute to a\nmapping of its return type.\n\n```go\ntype MyModule struct {}\n\n// Singleton provider.\nfunc (m *MyModule) ProvideLog() *log.Logger { return log.New() }\n\ntype Randomness int\n\n// \"Multi\" provider, called every time an \"int\" is injected.\nfunc (m *MyModule) ProvideMultiRandomness() Randomness { return Randomness(rand.Int()) }\n```\n\n## Validation\n\nFinally, after binding all of your types to the injector you can validate that\na function is constructible via the Injector by calling `Validate(f)`.\n\nOr you can live on the edge and simply use `Call(f)` which will panic if\ninjection is not possible.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falecthomas%2Finject","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falecthomas%2Finject","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falecthomas%2Finject/lists"}