{"id":15045009,"url":"https://github.com/amayaframework/amaya-di","last_synced_at":"2025-04-10T00:43:29.618Z","repository":{"id":49853220,"uuid":"492270794","full_name":"AmayaFramework/amaya-di","owner":"AmayaFramework","description":"A framework responsible for monitoring and automating the dependency injection process.","archived":false,"fork":false,"pushed_at":"2025-02-14T21:29:50.000Z","size":370,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-04-10T00:43:20.234Z","etag":null,"topics":["11","17","21","dependency","dependency-injection","dependency-injection-framework","di","di-framework","fast","fast-dependency-injection","fast-di","framework","inject","injection","java","java-11","java-17","java-21","java-di"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AmayaFramework.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":"2022-05-14T16:36:38.000Z","updated_at":"2025-03-31T09:44:06.000Z","dependencies_parsed_at":"2024-02-08T22:56:05.488Z","dependency_job_id":"eb9d6d9e-465a-4373-9f35-fe633efdb0f7","html_url":"https://github.com/AmayaFramework/amaya-di","commit_stats":{"total_commits":58,"total_committers":2,"mean_commits":29.0,"dds":0.03448275862068961,"last_synced_commit":"d032930620b782042e3bd5d70dd00d2be58a695d"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AmayaFramework%2Famaya-di","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AmayaFramework%2Famaya-di/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AmayaFramework%2Famaya-di/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AmayaFramework%2Famaya-di/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AmayaFramework","download_url":"https://codeload.github.com/AmayaFramework/amaya-di/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248137998,"owners_count":21053775,"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":["11","17","21","dependency","dependency-injection","dependency-injection-framework","di","di-framework","fast","fast-dependency-injection","fast-di","framework","inject","injection","java","java-11","java-17","java-21","java-di"],"created_at":"2024-09-24T20:51:20.839Z","updated_at":"2025-04-10T00:43:29.587Z","avatar_url":"https://github.com/AmayaFramework.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# amaya-di [![maven-central](https://img.shields.io/maven-central/v/io.github.amayaframework/amaya-di?color=blue)](https://repo1.maven.org/maven2/io/github/amayaframework/amaya-di)\n\nA framework responsible for monitoring and automating the dependency injection process.\n\u003cbr\u003e\nIt is only **1.27 times** (15.829 vs 12.427) slower than manual injection! (see benchmark section).\n\n[Russian version](README_RUS.md)\n\n## Philosophy\n\nTaking into account the features of both existing implementations, and the JVM and the Java language in general,\nthe framework was created in strict accordance with the following principles:\n\n* Support only for new versions of java (11+)\n* The minimum possible size of the framework\n* The minimum possible set of dependencies\n* No transitive dependencies (i.e., when you get a framework, you get only it and\n  several service libraries necessary for its operation)\n* No dependencies outside the jdk (no plugins, utilities, or scripts)\n* No built-in integrations\n* Maximum possible flexibility to adapt the framework to support specifications of any format\n* Avoiding making difficult decisions (if something cannot be unambiguously determined in a finite time,\n  it will not be determined)\n\n## Getting Started\n\nTo install it, you will need:\n\n* java 11+\n* Maven/Gradle\n\n## Installing\n\n### Gradle dependency\n\n```Groovy\ndependencies {\n    implementation group: 'io.github.amayaframework', name: 'amaya-di', version: '2.3.1'\n    // ASM stub implementation\n    implementation group: 'io.github.amayaframework', name: 'amaya-di-asm', version: '1.0.0'\n    // Or reflect stub implementation\n    implementation group: 'io.github.amayaframework', name: 'amaya-di-reflect', version: '1.0.0'\n}\n```\n\n### Maven dependency\n\n```\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.amayaframework\u003c/groupId\u003e\n    \u003cartifactId\u003eamaya-di\u003c/artifactId\u003e\n    \u003cversion\u003e2.3.1\u003c/version\u003e\n\u003c/dependency\u003e\n\u003c!--ASM stub implementation--\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.amayaframework\u003c/groupId\u003e\n    \u003cartifactId\u003eamaya-di-asm\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n\u003c!--Reflect stub implementation--\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.amayaframework\u003c/groupId\u003e\n    \u003cartifactId\u003eamaya-di-reflect\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## ASM or reflect stub factory\n\nThe choice between asm and reflect implementations depends only on how DI is used.\n1) If you create a container once (or many times) and request service implementations ONCE, \nthen you should use amaya-di-reflect.\n2) If you request service implementations MANY TIMES (that is, constantly throughout the lifetime of the application), \nthen you should use amaya-di-asm.\n\nOr you can always create your own implementation :)\n\n## Benchmark\n\nThe time spent requesting the implementation of a service \nwith multiple dependencies from already built container is measured.\n\nSee [asm benchmark](amaya-di-asm/src/jmh/java/io/github/amayaframework/di/asm/ServiceProviderBenchmark.java) and\n[reflect benchmark](amaya-di-reflect/src/jmh/java/io/github/amayaframework/di/asm/ServiceProviderBenchmark.java) and\nRunning on your machine:\n\n```\ngradle amaya-di-asm:jmh\ngradle amaya-di-reflect:jmh\n```\n\nResults:\n\u003cbr\u003e\n\nASM\n```\n# JMH version: 1.36\n# VM version: JDK 11.0.22, OpenJDK 64-Bit Server VM, 11.0.22+7-LTS\n# VM invoker: ~/.jdks/corretto-11.0.22/bin/java.exe\n\nBenchmark                                      Mode  Cnt   Score   Error  Units\nServiceProviderBenchmark.benchAmayaInjection   avgt   25  15,829 ± 1,685  ns/op\nServiceProviderBenchmark.benchManualInjection  avgt   25  12,427 ± 0,930  ns/op\n```\n\nReflect\n```\n# JMH version: 1.36\n# VM version: JDK 11.0.22, OpenJDK 64-Bit Server VM, 11.0.22+7-LTS\n# VM invoker: ~/.jdks/corretto-11.0.22/bin/java.exe\n\nBenchmark                                      Mode  Cnt   Score   Error  Units\nServiceProviderBenchmark.benchAmayaInjection   avgt   25  59,779 ± 1,011  ns/op\nServiceProviderBenchmark.benchManualInjection  avgt   25  11,582 ± 0,122  ns/op\n```\n\n## Usage example\n\nImportant: the order of transferring services to the builder does NOT matter, no changes and no exceptions will occur,\nthe ServiceProviderBuilder#build() method has not been called yet. \n\nThe benchAmayaInjection() method measures the time of the request from the container, the benchManualInjection() \nmethod measures the time of the \"build\" of an instance of the same service completely manually.\n\n### Hello, world!\n\n```Java\nimport io.github.amayaframework.di.ProviderBuilders;\nimport io.github.amayaframework.di.asm.BytecodeStubFactory;\n\npublic class Main {\n    public static void main(String[] args) {\n        var provider = ProviderBuilders\n                .createChecked(new BytecodeStubFactory())\n                .addInstance(\"Hello, world!\")\n                .build();\n        System.out.println(provider.get(String.class));\n    }\n}\n```\n\n### Two services and a dependent class\n\n```Java\nimport io.github.amayaframework.di.ProviderBuilders;\nimport io.github.amayaframework.di.asm.BytecodeStubFactory;\n\npublic class Main {\n    public static void main(String[] args) {\n        var provider = ProviderBuilders\n                .createChecked(new BytecodeStubFactory())\n                .addTransient(Service1.class)\n                .addSingleton(Service2.class)\n                .addTransient(App.class)\n                .build();\n        System.out.println(provider.get(App.class));\n        System.out.println(provider.get(App.class));\n    }\n\n    public static final class Service1 {\n        @Override\n        public String toString() {\n            return \"Service1, \" + hashCode();\n        }\n    }\n\n    public static final class Service2 {\n        @Override\n        public String toString() {\n            return \"Service2, \" + hashCode();\n        }\n    }\n\n    public static final class App {\n        final Service1 s1;\n        final Service2 s2;\n\n        public App(Service1 s1, Service2 s2) {\n            this.s1 = s1;\n            this.s2 = s2;\n        }\n\n        @Override\n        public String toString() {\n            return \"hash=\" + hashCode() + \"\\ns1=\" + s1 + \"\\ns2=\" + s2;\n        }\n    }\n}\n```\n\nThis code will output:\n\n```\nhash=1852584274\ns1=Service1, 280744458\ns2=Service2, 377478451\nhash=394714818\ns1=Service1, 1952779858\ns2=Service2, 377478451\n```\n\n### Generics\n\n```Java\nimport io.github.amayaframework.di.ProviderBuilders;\nimport io.github.amayaframework.di.asm.BytecodeStubFactory;\nimport com.github.romanqed.jtype.JType;\n\nimport java.util.List;\n\npublic class Main {\n    public static void main(String[] args) {\n        var provider = ProviderBuilders\n                .createChecked(new BytecodeStubFactory())\n                .addInstance(new JType\u003c\u003e(){}, List.of(\"Hi\", \"World\"))\n                .addInstance(new JType\u003c\u003e(){}, List.of(1, 2, 3))\n                .addTransient(App.class)\n                .build();\n        System.out.println(provider.get(App.class));\n    }\n\n    public static final class App {\n        final List\u003cString\u003e s1;\n        final List\u003cInteger\u003e s2;\n\n        public App(List\u003cString\u003e s1, List\u003cInteger\u003e s2) {\n            this.s1 = s1;\n            this.s2 = s2;\n        }\n\n        @Override\n        public String toString() {\n            return \"hash=\" + hashCode() + \"\\ns1=\" + s1 + \"\\ns2=\" + s2;\n        }\n    }\n}\n```\n\nOutput:\n\n```\nhash=1354011814\ns1=[Hi, World]\ns2=[1, 2, 3]\n```\n\n### Fields, methods, multiple constructors\n\n```Java\nimport io.github.amayaframework.di.ProviderBuilders;\nimport io.github.amayaframework.di.asm.BytecodeStubFactory;\n\npublic class Main {\n    public static void main(String[] args) {\n        var provider = ProviderBuilders\n                .createChecked(new BytecodeStubFactory())\n                .addTransient(Service1.class)\n                .addTransient(Service2.class)\n                .addTransient(Service3.class)\n                .addTransient(Service4.class)\n                .addTransient(App.class)\n                .build();\n        System.out.println(provider.get(App.class).s1);\n    }\n\n    public static final class Service1 {\n    }\n\n    public static final class Service2 {\n    }\n\n    public static final class Service3 {\n    }\n\n    public static final class Service4 {\n    }\n\n    public static final class App {\n        @Inject\n        public Service1 s1;\n\n        public App() {\n            System.out.println(\"Empty ctor\");\n        }\n\n        @Inject\n        public App(Service2 s2) {\n            System.out.println(\"Service2=\" + s2);\n        }\n\n        @Inject\n        public void setService3(Service3 s3) {\n            System.out.println(\"Service3=\" + s3);\n        }\n\n        @Inject\n        public static void setService4(App app, Service4 s4) {\n            System.out.println(\"App=\" + app + \", Service4=\" + s4);\n        }\n    }\n}\n\n```\n\nOutput:\n\n```\nService2=io.github.amayaframework.di.Main$Service2@9660f4e\nApp=io.github.amayaframework.di.Main$App@396f6598, Service4=io.github.amayaframework.di.Main$Service4@394e1a0f\nService3=io.github.amayaframework.di.Main$Service3@27a5f880\nio.github.amayaframework.di.Main$Service1@1d29cf23\n```\n\n### Missing dependency\n\n```Java\nimport io.github.amayaframework.di.ProviderBuilders;\nimport io.github.amayaframework.di.asm.BytecodeStubFactory;\n\nimport java.util.List;\n\npublic class Main {\n    public static void main(String[] args) {\n        try {\n            var provider = ProviderBuilders\n                    .createChecked(new BytecodeStubFactory())\n                    .addTransient(App.class)\n                    .build();\n            System.out.println(provider.get(App.class));\n        } catch (TypeNotFoundException e) {\n            System.out.println(e.getType() + \" not found\");\n        }\n    }\n\n    public static final class App {\n        final List\u003cString\u003e s1;\n        final List\u003cInteger\u003e s2;\n\n        public App(List\u003cString\u003e s1, List\u003cInteger\u003e s2) {\n            this.s1 = s1;\n            this.s2 = s2;\n        }\n\n        @Override\n        public String toString() {\n            return \"hash=\" + hashCode() + \"\\ns1=\" + s1 + \"\\ns2=\" + s2;\n        }\n    }\n}\n```\n\nOutput:\n\n```\njava.util.List\u003cjava.lang.String\u003e not found\n```\n\n### Cyclical dependency\n\n```Java\nimport io.github.amayaframework.di.ProviderBuilders;\nimport io.github.amayaframework.di.asm.BytecodeStubFactory;\n\npublic class Main {\n    public static void main(String[] args) {\n        try {\n            var provider = ProviderBuilders\n                    .createChecked(new BytecodeStubFactory())\n                    .addTransient(Service.class)\n                    .addTransient(App.class)\n                    .build();\n            System.out.println(provider.get(App.class));\n        } catch (CycleFoundException e) {\n            System.out.println(\"Found cycle: \" + e.getCycle());\n        }\n    }\n\n    public static final class Service {\n        public Service(App app) {\n        }\n    }\n\n    public static final class App {\n        public App(Service s) {\n        }\n    }\n}\n```\n\nOutput:\n\n```\nFound cycle: [class io.github.amayaframework.di.Main$App, class io.github.amayaframework.di.Main$Service]\n```\n\n## Built With\n\n* [Gradle](https://gradle.org) - Dependency management\n* [ASM](http://asm.ow2.io) - Generation of proxy classes\n* [jeflect](https://github.com/RomanQed/jeflect) - Defining classes from bytecode, utilities for ASM\n* [jfunc](https://github.com/RomanQed/jfunc) - \"Lazy\" containers, functional interfaces, utilities\n* [jtype](https://github.com/RomanQed/jtype) - Utilities for interaction with generic types\n* [jgraph](graph) - Structure and Tarjan's algorithm for oriented graph\n\n## Authors\n\n* [RomanQed](https://github.com/RomanQed) - *Main work*\n\nSee also the list of [contributors](https://github.com/AmayaFramework/amaya-di/contributors) who participated\nin this project.\n\n## License\n\nThis project is licensed under the Apache License Version 2.0 - see the [LICENSE](LICENSE) file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famayaframework%2Famaya-di","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famayaframework%2Famaya-di","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famayaframework%2Famaya-di/lists"}