Mammoth.Extensions.DependencyInjection is a utility library providing advanced extensions for Microsoft.Extensions.DependencyInjection (v10.0.0+).
Extend the standard DI container with:
- Decorator pattern support for wrapping services (interface-based and class-based)
- DependsOn extensions to register services with explicit keyed dependencies
- Keyed services management utilities
- Service provider factory with advanced registration tracking and resolution diagnostics
- Language: C# 14.0 with nullable reference types and implicit usings enabled
- Target Frameworks:
netstandard2.0,net8.0,net9.0,net10.0 - Testing: MSTest with coverlet code coverage
- Versioning: GitVersion (based on Git tags)
- Packaging: NuGet with source link support
# Restore and build
dotnet restore ./src/Mammoth.Extensions.DependencyInjection.sln
dotnet build ./src/Mammoth.Extensions.DependencyInjection.sln --configuration Release
# Run tests
dotnet test ./src/Mammoth.Extensions.DependencyInjection.sln
# Create NuGet package
dotnet pack ./src/Mammoth.Extensions.DependencyInjection.sln --configuration Release --output ./artifactsUse build.ps1 for local packaging (restore tools, versioning, build, pack). Testing is separate; run the full test suite on Windows before distributing packages. CI runs tests before its independently gated pack/publish stages. See CONTRIBUTING.md for local packaging and test commands.
- Work in
src/directory - Solution file:
src/Mammoth.Extensions.DependencyInjection.sln - Main project:
src/Mammoth.Extensions.DependencyInjection/ - Tests:
src/Mammoth.Extensions.DependencyInjection.Tests/ - Common settings:
src/Directory.Build.props
The library uses partial classes to organize extension methods by functionality:
| File | Purpose |
|---|---|
ServiceCollectionExtensions.cs |
Base installer pattern |
ServiceCollectionExtensions.Decorators.cs |
Decorator registration methods |
ServiceCollectionExtensions.KeyedService.cs |
Keyed service helpers |
ServiceCollectionExtensions.Registration.cs |
Advanced registration utilities |
ServiceProviderExtensions.cs |
Service provider query methods |
ServiceProviderExtensions.Registration.cs |
Factory and registration tracking |
ServiceProviderExtensions.Reflection.cs |
Reflection-based utilities |
ServiceIdentifier: Uniquely identifies registered servicesServiceDescriptorExtensions: Utilities for analyzing service descriptorsTypeExtensions: Type inspection and filtering helpersServiceProviderFactory: Advanced provider configurationDetectIncorrectUsageOfTransientDisposables: Diagnostic checksResolutionContext: Tracks service resolution graphConfiguration/subfolder: Configuration and diagnostic utilitiesInspector/subfolder: Assembly inspection for type discovery
Tests follow a 1:1 naming pattern with source files:
ServiceCollectionExtensions.Decorators.Tests.cs→ Tests for decoratorsServiceProviderExtensions.Resolution.Tests.cs→ Tests for resolutionServiceProviderExtensions.Registration.Tests.cs→ Tests for registrationInjectAnArrayOfDependenciesTests.cs→ Feature-specific testsTestServices.cs→ Shared test fixtures and utilities
- XML Documentation: All public types/methods must have
///documentation - Nullability: Strict null checking enabled (
<Nullable>enable</Nullable>) - Implicit Usings: Enabled to reduce boilerplate
- Analysis: Latest recommended .NET analyzers enabled with code style enforcement
- Code Style: Enforced during build (
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>)
- Extension methods use
ServiceCollectionExtensionsandServiceProviderExtensionspartial classes - Service identifiers use
ServiceIdentifierstruct for uniqueness - Decorator factories prefix with
Decorate - Keyed service methods include
Keyedin the name
- Fluent Extension Methods: All service registration methods return the collection for chaining
- Generic Methods with Constraints: Extensive use of generic constraints for type safety
- Factory Pattern: Services often registered via factory delegates
- Descriptor Inspection: Extension methods analyze
ServiceDescriptorto apply transformations
- Framework: MSTest (v4.0.2)
- Coverage: coverlet (v6.0.4)
- Diagnostics: Microsoft.Extensions.Diagnostics.Testing
- Test files match source file names with
.Tests.cssuffix - Use
[TestMethod]attribute - Group related tests in
[TestClass]classes - Leverage
TestServices.csfor common fixtures
# All tests
dotnet test ./src/Mammoth.Extensions.DependencyInjection.sln
# Specific test class
dotnet test --filter ClassName=ServiceCollectionExtensions.Decorators.Tests
# With coverage
dotnet test --collect:"XPlat Code Coverage"-
Service Decoration: Wraps existing service registrations with decorators without modifying the original
- Works with transient, scoped, singleton, and keyed services
- Supports interface-based and class-based decoration
- Handles factory-registered services
-
Keyed Services: Built on .NET 8.0+ keyed service infrastructure
DependsOnextensions enable explicit keyed dependency registration- Service identifiers include both type and key information
-
Reflection-Based Resolution: Optional advanced diagnostics
ServiceProviderExtensions.Reflection.csprovides introspection capabilitiesResolutionContextTrackingServiceProviderDecoratortracks resolution chains (disabled by default)
- Transient Disposables: Use
DetectIncorrectUsageOfTransientDisposablesto catch services that shouldn't be transient - Circular Dependencies: Decoration chains must not create cycles
- Frame-level Compatibility: Some reflection features require specific .NET versions (see
.Disabled.csfiles)
- GitHub: PrimordialCode/Mammoth.Extensions.DependencyInjection
- License: MIT
- Changelog:
Changelog.md- tracks features, breaking changes, and bug fixes - GitVersion Config:
GitVersion.yml- semantic versioning rules
- Check
Changelog.mdfor recent breaking changes and version constraints - Verify target framework support in
Directory.Build.props - Understand whether changes affect single or multiple target frameworks
- Check if the feature is platform-specific (see
.Disabled.csfiles)
- Update the appropriate partial class file based on functionality
- Add XML documentation with examples
- Create corresponding test file or add tests to existing one
- Update
Changelog.mdunder vNext section - Ensure changes work across all supported target frameworks
- Add new extension method: Add to the appropriate
ServiceCollectionExtensions.*.csorServiceProviderExtensions.*.cspartial class - Add diagnostics: Extend
DetectIncorrectUsageOfTransientDisposablesor configuration utilities - Enable reflection features: Modify condition checks in
ServiceProviderExtensions.Reflection.cs - Update supported versions: Modify
Directory.Build.propsand adjust compatibility checks