{"id":13413445,"url":"https://github.com/golobby/container","last_synced_at":"2025-03-14T19:32:12.381Z","repository":{"id":40302549,"uuid":"210399392","full_name":"golobby/container","owner":"golobby","description":"A lightweight yet powerful IoC dependency injection container for the Go programming language","archived":false,"fork":false,"pushed_at":"2024-07-11T00:38:40.000Z","size":122,"stargazers_count":548,"open_issues_count":6,"forks_count":36,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-07-31T20:52:21.118Z","etag":null,"topics":["container","dependency-injection","di-container","di-framework","go","golang","golang-package","inversion-of-control","ioc","ioc-container"],"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/golobby.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-23T16:12:50.000Z","updated_at":"2024-07-20T18:29:46.000Z","dependencies_parsed_at":"2024-10-26T09:09:59.708Z","dependency_job_id":"8c97d704-7d61-44bd-8426-c26c26d71603","html_url":"https://github.com/golobby/container","commit_stats":null,"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/golobby%2Fcontainer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/golobby%2Fcontainer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/golobby%2Fcontainer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/golobby%2Fcontainer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/golobby","download_url":"https://codeload.github.com/golobby/container/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243635425,"owners_count":20322937,"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":["container","dependency-injection","di-container","di-framework","go","golang","golang-package","inversion-of-control","ioc","ioc-container"],"created_at":"2024-07-30T20:01:40.571Z","updated_at":"2025-03-14T19:32:12.074Z","avatar_url":"https://github.com/golobby.png","language":"Go","readme":"[![Go Reference](https://pkg.go.dev/badge/github.com/golobby/container.svg)](https://pkg.go.dev/github.com/golobby/container)\n[![CI](https://github.com/golobby/container/actions/workflows/ci.yml/badge.svg)](https://github.com/golobby/container/actions/workflows/ci.yml)\n[![CodeQL](https://github.com/golobby/container/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/golobby/container/actions/workflows/codeql-analysis.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/golobby/container)](https://goreportcard.com/report/github.com/golobby/container)\n[![Coverage Status](https://coveralls.io/repos/github/golobby/container/badge.svg)](https://coveralls.io/github/golobby/container?branch=master)\n[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)  \n\n# Container\nGoLobby Container is a lightweight yet powerful IoC (dependency injection) container for Go projects.\nIt's built neat, easy-to-use, and performance-in-mind to be your ultimate requirement.\n\nFeatures:\n- Singleton and Transient bindings\n- Named dependencies (bindings)\n- Resolve by functions, variables, and structs\n- Must helpers that convert errors to panics\n- Optional lazy loading of bindings\n- Global instance for small applications\n- 100% Test coverage!\n\n## Documentation\n### Required Go Versions\nIt requires Go `v1.11` or newer versions.\n\n### Installation\nTo install this package, run the following command in your project directory.\n\n```bash\ngo get github.com/golobby/container/v3\n```\n\nNext, include it in your application:\n\n```go\nimport \"github.com/golobby/container/v3\"\n```\n\n### Introduction\nGoLobby Container is used to bind abstractions to their implementations.\nBinding is the process of introducing appropriate concretes (implementations) of abstractions to an IoC container.\nIn this process, you also determine the resolving type, singleton or transient.\nIn singleton bindings, the container provides an instance once and returns it for all the requests.\nIn transient bindings, the container always returns a brand-new instance for each request.\nAfter the binding process, you can ask the IoC container to make the appropriate implementation of the abstraction that your code needs.\nThen your code will depend on abstractions, not implementations!\n\n### Quick Start\nThe following example demonstrates a simple binding and resolving.\n\n```go\n// Bind Config interface to JsonConfig struct\nerr := container.Singleton(func() Config {\n    return \u0026JsonConfig{...}\n})\n\nvar c Config\nerr := container.Resolve(\u0026c)\n// `c` will be the instance of JsonConfig\n```\n\n### Typed Binding\n#### Singleton\nThe following snippet expresses singleton binding.\n\n```go\nerr := container.Singleton(func() Abstraction {\n  return Implementation\n})\n\n// If you might return an error...\n\nerr := container.Singleton(func() (Abstraction, error) {\n  return Implementation, nil\n})\n```\n\nIt takes a resolver (function) whose return type is the abstraction and the function body returns the concrete (implementation).\n\nThe example below shows a singleton binding.\n\n```go\nerr := container.Singleton(func() Database {\n  return \u0026MySQL{}\n})\n```\n\n#### Transient\nThe example below shows a transient binding.\n\n```go\nerr := container.Transient(func() Shape {\n  return \u0026Rectangle{}\n})\n```\n\n### Named Bindings\nYou may have different concretes for an abstraction.\nIn this case, you can use named bindings instead of typed bindings.\nNamed bindings take the dependency name into account as well.\nThe rest is similar to typed bindings.\nThe following examples demonstrate some named bindings.\n\n```go\n// Singleton\nerr := container.NamedSingleton(\"square\", func() Shape {\n    return \u0026Rectangle{}\n})\nerr := container.NamedSingleton(\"rounded\", func() Shape {\n    return \u0026Circle{}\n})\n\n// Transient\nerr := container.NamedTransient(\"sql\", func() Database {\n    return \u0026MySQL{}\n})\nerr := container.NamedTransient(\"noSql\", func() Database {\n    return \u0026MongoDB{}\n})\n```\n\n### Resolver Errors\n\nThe process of creating concrete (resolving) might face an error.\nIn this case, you can return the error as the second return value like the example below.\n\n```go\nerr := container.Transient(func() (Shape, error) {\n  return nil, errors.New(\"my-app: cannot create a Shape implementation\")\n})\n```\n\nIt could be applied to other binding types.\n\n### Resolving\nContainer resolves the dependencies with the `Resolve()`, `Call()`, and `Fill()` methods.\n\n#### Using References\nThe `Resolve()` method takes reference of the abstraction type and fills it with the appropriate concrete.\n\n```go\nvar a Abstraction\nerr := container.Resolve(\u0026a)\n// `a` will be an implementation of the Abstraction\n```\n\nExample of resolving using references:\n\n```go\nvar m Mailer\nerr := container.Resolve(\u0026m)\n// `m` will be an implementation of the Mailer interface\nm.Send(\"contact@miladrahimi.com\", \"Hello Milad!\")\n```\n\nExample of named-resolving using references:\n\n```go\nvar s Shape\nerr := container.NamedResolve(\u0026s, \"rounded\")\n// `s` will be an implementation of the Shape that named rounded\n```\n\n#### Using Closures\nThe `Call()` method takes a receiver (function) with arguments of abstractions you need.\nIt calls it with parameters of appropriate concretes.\n\n```go\nerr := container.Call(func(a Abstraction) {\n    // `a` will be an implementation of the Abstraction\n})\n```\n\nExample of resolving using closures:\n\n```go\nerr := container.Call(func(db Database) {\n  // `db` will be an implementation of the Database interface\n  db.Query(\"...\")\n})\n```\n\nYou can also resolve multiple abstractions like the following example:\n\n```go\nerr := container.Call(func(db Database, s Shape) {\n  db.Query(\"...\")\n  s.Area()\n})\n```\n\nYou are able to raise an error in your receiver function, as well.\n\n```go\nerr := container.Call(func(db Database) error {\n  return db.Ping()\n})\n// err could be `db.Ping()` error.\n```\n\nCaution: The `Call()` method does not support named bindings.\n\n#### Using Structs\nThe `Fill()` method takes a struct (pointer) and resolves its fields.\n\nThe example below expresses how the `Fill()` method works.\n\n```go\ntype App struct {\n    mailer Mailer   `container:\"type\"`\n    sql    Database `container:\"name\"`\n    noSql  Database `container:\"name\"`\n    other  int\n}\n\nmyApp := App{}\n\nerr := container.Fill(\u0026myApp)\n\n// [Typed Bindings]\n// `myApp.mailer` will be an implementation of the Mailer interface\n\n// [Named Bindings]\n// `myApp.sql` will be a sql implementation of the Database interface\n// `myApp.noSql` will be a noSql implementation of the Database interface\n\n// `myApp.other` will be ignored since it has no `container` tag\n```\n\n#### Binding time\nYou can resolve dependencies at the binding time if you need previous dependencies for the new one.\n\nThe following example shows resolving dependencies at binding time.\n\n```go\n// Bind Config to JsonConfig\nerr := container.Singleton(func() Config {\n    return \u0026JsonConfig{...}\n})\n\n// Bind Database to MySQL\nerr := container.Singleton(func(c Config) Database {\n    // `c` will be an instance of `JsonConfig`\n    return \u0026MySQL{\n        Username: c.Get(\"DB_USERNAME\"),\n        Password: c.Get(\"DB_PASSWORD\"),\n    }\n})\n```\n\n### Standalone Instance\nBy default, the Container keeps your bindings in the global instance.\nSometimes you may want to create a standalone instance for a part of your application.\nIf so, create a standalone instance like the example below.\n\n```go\nc := container.New()\n\nerr := c.Singleton(func() Database {\n    return \u0026MySQL{}\n})\n\nerr := c.Call(func(db Database) {\n    db.Query(\"...\")\n})\n```\n\nThe rest stays the same.\nThe global container is still available.\n\n### Must Helpers\n\nYou might believe that the container shouldn't raise any error and/or you prefer panics.\nIn this case, Must helpers are for you.\nMust helpers are global methods that panic instead of returning errors.\n\n```go\nc := container.New()\n// Global instance:\n// c := container.Global\n\ncontainer.MustSingleton(c, func() Shape {\n    return \u0026Circle{a: 13}\n})\n\ncontainer.MustCall(c, func(s Shape) {\n    // ...\n})\n\n// Other Must Helpers:\n// container.MustSingleton()\n// container.MustSingletonLazy()\n// container.MustNamedSingleton()\n// container.MustNamedSingletonLazy()\n// container.MustTransient()\n// container.MustTransientLazy()\n// container.MustNamedTransient()\n// container.MustNamedTransientLazy()\n// container.MustCall()\n// container.MustResolve()\n// container.MustNamedResolve()\n// container.MustFill()\n```\n\n### Lazy Binding\nBoth the singleton and transient binding calls have a lazy version.\nLazy versions defer calling the provided resolver function until the first call.\nFor singleton bindings, It calls the resolver function only once and stores the result.\n\nLazy binding methods:\n* `container.SingletonLazy()`\n* `container.NamedSingletonLazy()`\n* `container.TransientLazy()`\n* `container.NamedTransientLazy()`\n\n### Performance\nThe package Container inevitably uses reflection for binding and resolving processes. \nIf performance is a concern, try to bind and resolve the dependencies where it runs only once, like the main and init functions.\n\n## License\n\nGoLobby Container is released under the [MIT License](http://opensource.org/licenses/mit-license.php).\n","funding_links":[],"categories":["Miscellaneous","Go","Microsoft Office","杂项","其他杂项","Dependency Injection"],"sub_categories":["Dependency Injection","依赖注入","依赖性注入"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgolobby%2Fcontainer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgolobby%2Fcontainer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgolobby%2Fcontainer/lists"}