Pure DI Templates
$ dotnet add package Pure.DI.TemplatesSupports .NET starting with .NET Framework 2.0, released 2005-10-27, and all newer versions.
Pure.DI is not a framework or library, but a source code generator for creating object graphs. To make them accurate, the developer uses a set of intuitive hints from the Pure.DI API. During the compilation phase, Pure.DI determines the optimal graph structure, checks its correctness, and generates partial class code to create object graphs in the Pure DI paradigm using only basic language constructs. The resulting generated code is robust, works everywhere, throws no exceptions, does not depend on .NET library calls or .NET reflections, is efficient in terms of performance and memory consumption, and is subject to all optimizations. This code can be easily integrated into an application because it does not use unnecessary delegates, additional calls to any methods, type conversions, boxing/unboxing, etc.
Pure.DI is actually a .NET code generator. It uses basic language constructs to create simple code as well as if you were doing it yourself: de facto it's just a bunch of nested constructor calls. This code can be viewed, analyzed at any time, and debugged.
All logic for analyzing the graph of objects, constructors and methods takes place at compile time. Pure.DI notifies the developer at compile time of missing or cyclic dependencies, cases when some dependencies are not suitable for injection, etc. The developer has no chance to get a program that will crash at runtime because of some exception related to incorrect object graph construction. All this magic happens at the same time as the code is written, so you have instant feedback between the fact that you have made changes to your code and the fact that your code is already tested and ready to use.
When using pure DI, no dependencies are added to assemblies because only basic language constructs and nothing more are used.
All generated code runs as fast as your own, in pure DI style, including compile-time and run-time optimization. As mentioned above, graph analysis is done at compile time, and at runtime there are only a bunch of nested constructors, and that's it. Memory is spent only on the object graph being created.
Since the pure DI approach does not use any dependencies or .NET reflection at runtime, it does not prevent the code from running as expected on any platform: Full .NET Framework 2.0+, .NET Core, .NET, UWP/XBOX, .NET IoT, Xamarin, Native AOT, etc.
The Pure.DI API is very similar to the API of most IoC/DI libraries. And this was a conscious decision: the main reason is that programmers don't need to learn a new API.
In Pure.DI it is proposed to use special marker types instead of using open generic types. This allows you to build the object graph more accurately and take full advantage of generic types.
Pure.DI already supports many of BCL types like
Array,IEnumerable<T>,IList<T>,IReadOnlyCollection<T>,IReadOnlyList<T>,ISet<T>,IProducerConsumerCollection<T>,ConcurrentBag<T>,Func<T>,ThreadLocal,ValueTask<T>,Task<T>,MemoryPool<T>,ArrayPool<T>,ReadOnlyMemory<T>,Memory<T>,ReadOnlySpan<T>,Span<T>,IComparer<T>,IEqualityComparer<T>and etc. without any extra effort.
Its high performance, zero memory consumption/preparation overhead, and lack of dependencies make it ideal for building libraries and frameworks.