Table of Contents

DotNetBlocks.Extensions.DependencyInjection

Adds functionality to the Microsoft.Extensions namespace to solve Lazy DI and other missing functionality problems.

Getting started

NuGet : DotNetBlocks.Extensions.DependencyInjection

Licensing and other information

Functionality

DependencyInjection

To improve performance, design patterns use the injection of Lazy in their constructors to delay the cost of initiation to JustInTime. Microsoft DI does not support LAZY Service types. Options are to use a different DI provider or use these extensions.

Problems Solved

Lack of support for lazy types in Microsoft.Extensions.DependencyInjection

#Examples

Dependency Injection Problem Solved.

Microsoft DI is the simplest DI system available and does not support inferring Lazy using already registered service types. The most effective solution to wasting resources when injecting Services via class constructor parameters is using a Lazy<Service pattern. This delays the construction of the resource until first use.

If you use MS DI, you have to registee the Lazy for every class that may be lazy, and we want the DI container to generically support Lazy for our constructors.

We need to add the functionality to create any Lazy class if the service is already registered.

Alternatives

A better solution is to use AutoFac or other open source DI systems and leverage the more advanced functionality.

The Solution

References

Microsoft DI Default Service Container Replacement

Implementation notes

A first attempt was to use a lighter facade factory pattern using implicit type conventions, but issues with Di type conversion testing on implicit classes prevented its use. The final lazy implementation had to exactly match the lazy signature, so extending the class with DI support became the easiest solution. You also can't use a generic factory method and a dynamic keyword because there is no way to add a parameter that can be used for dynamic type discovery.

Solution inspiration is this discussion aboard Solution ideas discussion - for credit

details

This library implements two solutions internally. One uses a Lazy Implementation class that inherits from Lazy but with a constructor with DI support. This is a simple but effective solution to the problem and is the soution implementation when you "add Lazy Support" to the service collection. It registers this LazyService type for use in all lazy requests.

The second implementation is a "true lazy" implementation using a delegate constructor to create an true Lazy class with a dynamic costructor. This is the solution used when you use a Lazy registration for a type or the AsLazy registration extension method. The "true" implementation is modeled on the standard microsoft libraries, using copied and modified versions of the microsoft DI service registration and service descriptor static methods.

The internal pattern is to create ServiceDescriptors using the "describe" pattern and add those to the service collection. The describe method creates the appropriate factories and lifetimes supporting the requeted lazy usage registration type.

Factory methods

The factory methods use methodInfo to close the types and invoke the factory method builder, but its important to note this does not have a performance impact, because the builder method is only called during registration to create an appropriate delegate that is passed to the dependency registration. This technique is faster than building the lambdas using code and more maintainable.