{"id":19121063,"url":"https://github.com/dadhi/lemptest","last_synced_at":"2026-03-09T04:31:09.619Z","repository":{"id":66273486,"uuid":"278280701","full_name":"dadhi/LempTest","owner":"dadhi","description":"Proof-of-concept compile-time Dependency Injection container using LeMP code-generation from the ECSharp","archived":false,"fork":false,"pushed_at":"2022-04-26T09:39:34.000Z","size":77,"stargazers_count":5,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-19T13:52:46.394Z","etag":null,"topics":["code-generation","compile-time","csharp","dependency-injection","dotnet","dotnet-core","dryioc","ecsharp","ioc-container","lemp","loyc","t4"],"latest_commit_sha":null,"homepage":"","language":"C#","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/dadhi.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":"2020-07-09T06:22:31.000Z","updated_at":"2023-06-12T11:30:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"82eefc6c-77a8-41ff-9016-87757ff52055","html_url":"https://github.com/dadhi/LempTest","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dadhi/LempTest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dadhi%2FLempTest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dadhi%2FLempTest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dadhi%2FLempTest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dadhi%2FLempTest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dadhi","download_url":"https://codeload.github.com/dadhi/LempTest/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dadhi%2FLempTest/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30283411,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T02:57:19.223Z","status":"ssl_error","status_checked_at":"2026-03-09T02:56:26.373Z","response_time":61,"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":["code-generation","compile-time","csharp","dependency-injection","dotnet","dotnet-core","dryioc","ecsharp","ioc-container","lemp","loyc","t4"],"created_at":"2024-11-09T05:15:57.708Z","updated_at":"2026-03-09T04:31:09.380Z","avatar_url":"https://github.com/dadhi.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Proof-of-concept compile-time Dependency Injection container using LeMP code-generation from the ECSharp\n\n## Why at all\n\nCompile-time dependency injection here is \nthe generation of object-graph \"service creation code\" given the interface-implementation registrations provided at compile-time.\nIn a simplest form you may consider \"service creation code\" as a method returning `new A(new B(new C(), new C1(new D()), ...)`. The tool should generate this method at compile-time and make it a part of your project.\n\nThe idea is already implemented in my another project [DryIoc](https://github.com/dadhi/dryioc) using the T4 templates\nbut has a number of [problems](https://github.com/dadhi/DryIoc/issues/212).\n\nIn this repository I want to solve these problems and test the ideas **without much accent on DI itself**. \nNevertheless, the DI should be a functional solution to make the test actually usable and verify the different aspects of the problem.\nOK, the DryIoc supports both compile-time and runtime registrations, because it not always possible to know everything at compile-time.\nTherefore this DI prototype should support this too. \n\nThe typical compile-time service registration will look like this: \n```cs\ndi.Register\u003cX\u003e(resolver =\u003e new X(new A(), resolver.Resolve\u003cB\u003e()));\n```\n\n`resolver.Resolver\u003cB\u003e()` here is the bridge to another registration which can be either compile-time or runtime-one.\nYou can imagine that `X` and `A` are your app services and `B` is a context or configuration provided by \nthe framework at runtime. \n\n## Problems to solve\n\n1. I want the ability to use part of DI to help generate another part of DI at compile-time. It means that I need to reference the code (compiled) from the compile-time template to generate the remaining part of the code. But I don't want to split the first part to another library, then compile it, then load it for the rest of code-generation. So inevitably I am ending-up with the chicken-egg problem. For T4 the hack would be to compile the DI project first with the compile-time generation commented out, then uncomment the generation and load the produced dll to compile the new dll with generated code :/\n\n2. I want to publish the DI as a code-only NuGet package with the template that's supposed to be modified by user - to put the registrations into it. I want the package to be easy (as automated as possible) consumed by modern .NET Core v3.1 applications, like ASP .NET Core MVC/WebAPI. And this combination currently is the real mess. Here is the [one](https://github.com/NuGet/Home/issues/4837) of the many issues. You need to really [hack around](http://diegogiacomelli.com.br/deploying-a-t4-template-with-dotnet-pack) your [way](https://medium.com/@attilah/source-code-only-nuget-packages-8f34a8fb4738) to achieve this. \n\n3. Given that I already invested the time and created the T4 implementation in DryIoc, \nit seems that I need to push it further, probably using the [mono implementation](https://github.com/mono/t4) to support modern targets. \nBut T4 never felt to me like a good fit for C# because it is a different text manipulating tool tearing the C# code into disjoint parts.\nThe errors are cryptic. Assembly loading and references is a quiz.\n\nSo here goes...\n\n## How\n\n### LeMP and ECSharp\n\nThe project site http://ecsharp.net/\n\nLeMP compile-time code-generation similar to T4 is supported starting from the [v2.8.1](https://github.com/qwertie/ecsharp/releases/tag/v2.8.1)\n\n**Update:** There dotnet CLI [LeMP-tool](https://www.nuget.org/packages/LeMP-tool) is available now to install and manage LeMP through NuGet.\n\nLeMP solves the 3rd problem because its compile-time generation capabilities keep the code looking like C# with almost all valid C# syntax.\nAnd ta-ba-dam, ta-ba-dam, ... it solves the 1st problem too via `compileAndRuntime {}` which makes code available for the compile-time tools and keeps the code in the result runtime binary.\n\nOther goodies are Extended CSharp features, macros and sugar.\n\n### The build\n\nThe solution is supposed to be built and tested in VS Code. I did not yet tested it in Visual Studio.\n\n- Add the folder `.nupkg` as a local NuGet source: `dotnet nuget add source full\\path\\to\\.nupkg --name Local`\n- Go to solution folder and built it with `dotnet build`\n- For `.ecs` and `.ecs.include` files you may turn-on the CSharp syntax highlighting via \"Change Language Mode\" command (`Ctrl+K,M`) \n\n\n### CompileTimeDI project\n\nCompileTimeDI is the .NET Standard 2.0 project with the DI implementation contained in a single `CompileTimeDI.ecs`. \nThe project also contains the `ServiceRegistrations.ecs.include` file which is supposed to be edited by DI user.\nThe latter is included into former, then everything is processed by LeMP macro processor at compile-time and the output \nis stored in `CompileTimeDI.Generated.cs` file. Invoke the `dotnet build` to run the processing.\n\nWhen build in the Release configuration `dotnet build -c Release`, \nthe project is packaged into the content-only NuGet package ([yes, you can do this](https://medium.com/@attilah/source-code-only-nuget-packages-8f34a8fb4738))\nand can be found in the \".nupkg\" folder.\n\n### AspNetCoreSample project\n\nAspNetCoreSample is the standard ASP .NET Core v3.1 WebApi dotnet template app consuming the CompileTimeDI package.\nIt installs the \"CompileTimeDI\" package from the Local feed (together with LempDotnetTool) and \nspecifies some test service registrations from the AnotherLib project. **No need for a manual file copying and the prolonged user instructions**.\nStart the app from the project folder via `dotnet run`.\nGo to the listed `localhost:port/services` in web browser to see the results.\nThe compile-time registrations are in `ServiceRegistrations.ecs.include` and the remaing parts are in `WeatherForcastController`.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdadhi%2Flemptest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdadhi%2Flemptest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdadhi%2Flemptest/lists"}