{"id":48137862,"url":"https://github.com/studiole/di","last_synced_at":"2026-05-16T13:05:27.400Z","repository":{"id":345923615,"uuid":"1187279841","full_name":"StudioLE/di","owner":"StudioLE","description":"Rust libraries for dependency injection","archived":false,"fork":false,"pushed_at":"2026-05-11T20:01:26.000Z","size":74,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-11T20:14:12.670Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StudioLE.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-20T14:44:52.000Z","updated_at":"2026-05-11T19:58:07.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/StudioLE/di","commit_stats":null,"previous_names":["studiole/di"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/StudioLE/di","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StudioLE%2Fdi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StudioLE%2Fdi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StudioLE%2Fdi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StudioLE%2Fdi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StudioLE","download_url":"https://codeload.github.com/StudioLE/di/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StudioLE%2Fdi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32912681,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-11T17:09:15.040Z","status":"ssl_error","status_checked_at":"2026-05-11T17:08:45.420Z","response_time":120,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2026-04-04T16:47:49.055Z","updated_at":"2026-05-11T21:04:59.745Z","avatar_url":"https://github.com/StudioLE.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dependency Injection for Rust\n\n## Highlights\n\n- Sync and Async constructors\n- Resolve by type or trait\n- Singleton or transient services\n\n## Usage\n\n### Define services\n\nImplement `FromServices` to describe how a type is constructed from the container:\n\n```rust\nuse studiole_di::prelude::*;\n\nstruct Config {\n    port: u16,\n}\n\nstruct Database {\n    config: Arc\u003cConfig\u003e,\n}\n\nimpl FromServices for Database {\n    type Error = ResolveError;\n\n    fn from_services(services: \u0026ServiceProvider) -\u003e Result\u003cSelf, Report\u003cResolveError\u003e\u003e {\n        let config = services.get::\u003cConfig\u003e()?;\n        Ok(Self { config })\n    }\n}\n```\n\n### Register and resolve\n\n```rust\nlet services = ServiceBuilder::new()\n    .with_instance(Config { port: 8080 })\n    .with_type::\u003cDatabase\u003e()\n    .build();\n\nlet db = services.get::\u003cDatabase\u003e().expect(\"should resolve\");\nassert_eq!(db.config.port, 8080);\n```\n\n### Transient services\n\nBy default, services are singletons. Use the `_transient` variants for a fresh instance on every resolution:\n\n```rust\nlet services = ServiceBuilder::new()\n    .with_type_transient::\u003cDatabase\u003e()\n    .build();\n```\n\n### Trait objects\n\n*Requires nightly + `traits` feature*\n\nRegister a concrete type and resolve it as one or more trait objects:\n\n```rust\nlet services = ServiceBuilder::new()\n    .with_trait::\u003cdyn Get, MemoryCache\u003e()\n    .with_trait::\u003cdyn Set, MemoryCache\u003e()\n    .build();\n\nlet cache = services.get_trait::\u003cdyn Get\u003e().expect(\"should resolve\");\n```\n\nBoth trait registrations share the same concrete singleton.\n\n### Async services\n\n*Requires `async` feature*\n\nImplement `FromServicesAsync` for services that need async construction:\n\n```rust\nstruct AsyncDatabase {\n    config: Arc\u003cConfig\u003e,\n}\n\nimpl FromServicesAsync for AsyncDatabase {\n    type Error = ResolveError;\n\n    async fn from_services_async(\n        services: \u0026ServiceProvider,\n    ) -\u003e Result\u003cSelf, Report\u003cResolveError\u003e\u003e {\n        let config = services.get::\u003cConfig\u003e()?;\n        Ok(Self { config })\n    }\n}\n```\n\n```rust\nlet services = ServiceBuilder::new()\n    .with_instance(Config { port: 8080 })\n    .with_type_async::\u003cAsyncDatabase\u003e()\n    .build();\n\nlet db = services.get_async::\u003cAsyncDatabase\u003e().await.expect(\"should resolve\");\n```\n\nAsync trait objects work the same way with `with_trait_async` and `get_trait_async`.\n\n## Migration\n\n- [0.2 to 0.3](docs/migration-guides/0.2-to-0.3.md)\n\n## License\n\nThis repository and its libraries are provided open source with the [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.en.html) license that requires you must disclose your source code when you distribute, publish, or provide access to modified or derivative software.\n\nDevelopers who wish to keep modified or derivative software proprietary or closed source can [get in touch for a commercial license agreements](https://studiole.uk/contact/)\n\n\u003e Copyright © Laurence Elsdon 2025-2026\n\u003e\n\u003e This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n\u003e\n\u003e This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.\n\u003e\n\u003e You should have received a copy of the GNU Affero General Public License along with this program. If not, see \u003chttps://www.gnu.org/licenses/\u003e.\n\n→ [GNU Affero General Public License](LICENSE.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstudiole%2Fdi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstudiole%2Fdi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstudiole%2Fdi/lists"}