{"id":18595438,"url":"https://github.com/svenruppert/dynamic-cdi","last_synced_at":"2026-01-11T17:05:35.641Z","repository":{"id":31388471,"uuid":"34951592","full_name":"svenruppert/dynamic-cdi","owner":"svenruppert","description":"Dynamic Context Dependency Injection","archived":false,"fork":false,"pushed_at":"2025-06-05T20:22:37.000Z","size":1342,"stargazers_count":9,"open_issues_count":2,"forks_count":3,"subscribers_count":10,"default_branch":"develop","last_synced_at":"2025-08-16T01:54:43.036Z","etag":null,"topics":["cdi","dependency-injection","dynamic-dependency-injection","java","java-library","jdk10","jdk11","jdk12","jdk8","jdk9","ruppert","sven"],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"YMFE/yapi","license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/svenruppert.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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}},"created_at":"2015-05-02T14:54:16.000Z","updated_at":"2024-12-13T14:33:34.000Z","dependencies_parsed_at":"2025-04-10T16:41:26.119Z","dependency_job_id":"63da6ed3-9a36-4635-b387-36d30e006721","html_url":"https://github.com/svenruppert/dynamic-cdi","commit_stats":null,"previous_names":["dynamic-dependency-injection/dynamic-cdi","rapidpm/dynamic-cdi"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/svenruppert/dynamic-cdi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svenruppert%2Fdynamic-cdi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svenruppert%2Fdynamic-cdi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svenruppert%2Fdynamic-cdi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svenruppert%2Fdynamic-cdi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/svenruppert","download_url":"https://codeload.github.com/svenruppert/dynamic-cdi/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svenruppert%2Fdynamic-cdi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28314264,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T14:58:17.114Z","status":"ssl_error","status_checked_at":"2026-01-11T14:55:53.580Z","response_time":60,"last_error":"SSL_read: 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":["cdi","dependency-injection","dynamic-dependency-injection","java","java-library","jdk10","jdk11","jdk12","jdk8","jdk9","ruppert","sven"],"created_at":"2024-11-07T01:19:45.948Z","updated_at":"2026-01-11T17:05:35.623Z","avatar_url":"https://github.com/svenruppert.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Welcome to the Project Dynamic CDI\n\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.rapidpm.dynamic-cdi/rapidpm-dynamic-cdi/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.rapidpm.dynamic-cdi/rapidpm-dynamic-cdi)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/1b039c89fb9f4baa91f5d7b906bf13f6)](https://www.codacy.com/app/sven-ruppert/dynamic-cdi?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=Dynamic-Dependency-Injection/dynamic-cdi\u0026amp;utm_campaign=Badge_Grade)\n\n\n## JDK Informations\nActual version is running from JDK8 up to JDK13.\nThe version 1.0.x is based on JDK8.\n\n\nThe implementation is covered with over 90% mutation test coverage.\nThe last report you can find under **_docu/**\n\n![_docu/20180319/pit_overview.png](_docu/20180319/pit_overview.png)\n\n\n## How DDI will resolve the corresponding Implementation?\n\nif you write ``@Inject Interface``\n\n1 ClassResolver means: 1 ClassResolver responsible for the given Interface. You can have n ClassResolver inside your classpath.\nBut for every Interface only one that is responsible for it.\n\n* Interface , no Impl. -\u003e Exception\n* Interface , no Impl., 1 Producer for the Interface  -\u003e Producer for the Interface will be used\n\n* Interface , 1 Impl. -\u003e will use the Impl.\n* Interface , 1 Impl., 1 Producer for Impl. -\u003e Producer for the Impl will be used\n* Interface , 1 Impl., n Producer for Impl. -\u003e Exception\n* Interface , 1 Impl., 1 Producer for Interface -\u003e Producer for the Interface will be used\n* Interface , 1 Impl., n Producer for Interface -\u003e Exception\n\n* Interface , 1 Impl., 1 Producer for Interface , 1 Producer for Impl. -\u003e Exception\n\n* Interface , n Impl. -\u003e Exception\n* Interface , n Impl., 1 responsible ClassResolver -\u003e result of the ClassResolver will be used\n* Interface , n Impl., 1 Producer for Interface -\u003e Producer for the Interface will be used\n* Interface , n Impl., 1-n Producer for Impl. -\u003e Exception\n\n* Interface , n Impl., 1 responsible ClassResolver, 1 Producer for Interface -\u003e Producer for the Interface will be used\n* Interface , n Impl., 1 responsible ClassResolver, 1-n Producer for Impl. -\u003e will use the resolved Class or corresponding Producer if available\n* Interface , n Impl., n responsible ClassResolver -\u003e Exception\n\n* Interface, 1 Impl., n Producer for Impl, 1 ProducerResolver for Impl -\u003e selected Producer from ProducerResolver\n* Interface, n Impl., 1 responsible ClassResolver, 0-n Producer for every Impl, 1 ProducerResolver for every Impl -\u003e selected Producer from ProducerResolver, for selected Impl from ClassResolver\n\n\nif you write ``@Inject Impl.``\n\n* Impl. -\u003e will use the Impl.\n* Impl., 1 Producer -\u003e will use the Producer for the Impl.\n\n## How to write Mocks for Interfaces or classes ?\nYou can use this framework for the mocking too. \nThe concept is based on the Designpattern ObjectAdapter. \nYou can have too versions of an ObjectAdapter , based on the implementations the ProxyBuilder will give you. \nVersion one is a DynamicObjectAdapter. \nThis you could only use if you have an interface available. \nThe DynamicObjectAdapterBuilder will be created during the compile phase \nif you annotate the corresponding interface with the Annotation @DynamicObjectAdapterBuilder. \nPlease check the documentation about the DynamicObjectAdapter for more details.\n\nVersion two is a StaticObjectAdapter. This you could use for Interfaces and Classes. \nTo create a StaticObjectAdapter for your target you have to annotate the the target class or \ninterface with the Annotation @StaticObjectAdapter. \nAfter the compile phase you could find the generated classes at target/generated-sources (if you are using maven).\n\n## Mocking\nIf you want to use a Mock for an jUnitTest, you have to use a ClassResolver or \nProducerResolver to make the decision for the Mock explicit for your test. \nThe easiest way is the usage of an Producer that will create the Mock. \nWith this you could mock something that is deep inside your system, \nwithout creating the full hierarchy with frameworks like Mockito. \nMostly this will lead to constructions that are much more like the production system.\n\n### example with one interface and one production class\nInside the production source path you will have an interface and one implementation.\n\n```java \n  public interface Service {\n    String doWork(String txt);\n  }\n\n  public static class ServiceA implements Service {\n    public String doWork(String txt) {\n      return txt + \"A\";\n    }\n  }\n```\n\nDuring the runtime the solution is very simple, \nbecause there is only on implementation available. \nBut now we would like to activate a Mock during the jUnit test. \nFor this we need a second implementation called ServiceB\n\n```java\n public static class ServiceB implements Service {\n    public String doWork(String txt) {\n      return txt + \"B\";\n    }\n  }\n```\n\nTo activate this mock only for the jUnit Tests we have \nto config the DI Container in a way that the ServiceB will be available. \nThis means, during the startup phase **@Before** we are clearing the existing \nReflection Model to make sure there is no other config from any other test anymore. \nAfter this we re activating only production classes and the package from the test itself.\n\n```java\n  @Before\n  public void setUp() throws Exception {\n    DI.clearReflectionModel();\n    DI.activatePackages(\"org.rapidpm\");\n    DI.activatePackages(this.getClass());\n  }\n```\nNow we have the mock inside the reflection model, too. \nThis means we have to give the container a possibility to resolve this. \nFor this we have to create a ClassResolver. \nThis will be instantiated and asked for the solution.\n\n\n```java\n  @ResponsibleFor(Service.class)\n  public static class ServiceClassResolver implements ClassResolver\u003cService\u003e {\n    @Override\n    public Class\u003c? extends Service\u003e resolve(final Class\u003cService\u003e interf) {\n      return ServiceB.class;\n    }\n  }\n```\nNow the container is able to ask the ClassResolver, \nwhat will be the right implementation to use. In our case, the mock.\n\nHere you can see, one of the jUnit Tests that we are using to test the ClassResolver. \nClassResolverTest014.java\n\n```java\n  @Before\n  public void setUp() throws Exception {\n    DI.clearReflectionModel();\n    DI.activatePackages(\"org.rapidpm\");\n    DI.activatePackages(this.getClass());\n  }\n\n  public static Boolean toggle = true;\n\n  @Test\n  public void test001() throws Exception {\n    Assert.assertEquals(ServiceB.class, DI.activateDI(Service.class).getClass());\n    Assert.assertEquals(ServiceA.class, DI.activateDI(Service.class).getClass());\n    Assert.assertEquals(ServiceB.class, DI.activateDI(Service.class).getClass());\n    DI.clearReflectionModel();\n  }\n\n  public interface Service {\n    String doWork(String txt);\n  }\n\n  public static class ServiceA implements Service {\n    public String doWork(String txt) {\n      return txt + \"A\";\n    }\n  }\n\n  public static class ServiceB implements Service {\n    public String doWork(String txt) {\n      return txt + \"B\";\n    }\n  }\n\n  @ResponsibleFor(Service.class)\n  public static class ServiceClassResolver implements ClassResolver\u003cService\u003e {\n    @Override\n    public Class\u003c? extends Service\u003e resolve(final Class\u003cService\u003e interf) {\n      toggle = !toggle;\n      System.out.println(\"toggle = \" + toggle);\n      return (toggle) ? ServiceA.class : ServiceB.class;\n    }\n  }\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsvenruppert%2Fdynamic-cdi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsvenruppert%2Fdynamic-cdi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsvenruppert%2Fdynamic-cdi/lists"}