Myth.DependencyInjection 3.0.4

There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Myth.DependencyInjection --version 3.0.4
                    
NuGet\Install-Package Myth.DependencyInjection -Version 3.0.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Myth.DependencyInjection" Version="3.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Myth.DependencyInjection" Version="3.0.4" />
                    
Directory.Packages.props
<PackageReference Include="Myth.DependencyInjection" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Myth.DependencyInjection --version 3.0.4
                    
#r "nuget: Myth.DependencyInjection, 3.0.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Myth.DependencyInjection@3.0.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Myth.DependencyInjection&version=3.0.4
                    
Install as a Cake Addin
#tool nuget:?package=Myth.DependencyInjection&version=3.0.4
                    
Install as a Cake Tool

Myth.DependencyInjection

NuGet Version NuGet Version

License

pt-br en

A .NET library that simplifies dependency injection with automatic type discovery and convention-based service registration. Eliminate boilerplate code and enable plugin architectures with powerful assembly scanning and type resolution capabilities.

Features

  • Type Discovery: Automatically discover and scan application assemblies and types
  • Convention-based Registration: Auto-register services based on interface naming conventions
  • Assembly Scanning: Load and analyze all assemblies in your application domain
  • Type Filtering: Find types implementing specific interfaces or base classes
  • Namespace Detection: Automatically detect your application's base namespace
  • Minimal Configuration: Reduce boilerplate DI registration code
  • Plugin Support: Enable plugin architectures with dynamic type loading

Installation

dotnet add package Myth.DependencyInjection

Quick Start

Automatic Service Registration

Register all implementations of an interface automatically based on naming conventions:

using Microsoft.Extensions.DependencyInjection;
using Myth.Extensions;

var services = new ServiceCollection();

// Automatically finds and registers all repository implementations
services.AddServiceFromType<IRepository>();

// Result: IPersonRepository -> PersonRepository (Scoped)
//         IOrderRepository -> OrderRepository (Scoped)
//         IProductRepository -> ProductRepository (Scoped)

Type Discovery

Discover and analyze types in your application:

using Myth.ValueProviders;

// Get base namespace
var baseNamespace = TypeProvider.BaseApplicationNamespace;
// Returns: "MyApp" (from MyApp.Domain, MyApp.Services, etc.)

// Get all application assemblies
var assemblies = TypeProvider.ApplicationAssemblies;
// Returns: All loaded assemblies from your application

// Get all concrete types
var types = TypeProvider.ApplicationTypes;
// Returns: All non-abstract, non-interface types

// Find types implementing specific interface
var handlers = TypeProvider.GetTypesAssignableFrom<ICommandHandler>();
// Returns: All types implementing ICommandHandler

Usage Scenarios

1. Repository Pattern Auto-Registration

Eliminate manual repository registration:

// Before: Manual registration for each repository
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IOrderRepository, OrderRepository>();
services.AddScoped<IProductRepository, ProductRepository>();
// ... dozens more

// After: One-line registration
services.AddServiceFromType<IRepository>();

Convention: The implementation class name must contain the interface name.

  • IUserRepositoryUserRepository (valid)
  • IOrderRepositoryOrderRepository (valid)
  • IProductRepositoryProductRepositoryImpl (valid)

2. CQRS Handler Registration

Automatically register command and query handlers:

// Register all command handlers
services.AddServiceFromType<ICommandHandler>(ServiceLifetime.Transient);

// Register all query handlers
services.AddServiceFromType<IQueryHandler>(ServiceLifetime.Transient);

// Register all event handlers
services.AddServiceFromType<IEventHandler>(ServiceLifetime.Scoped);

3. Plugin Architecture

Dynamically discover and load plugins:

// Find all plugin types
var pluginTypes = TypeProvider.GetTypesAssignableFrom<IPlugin>();

foreach (var pluginType in pluginTypes) {
    var plugin = (IPlugin)Activator.CreateInstance(pluginType);
    plugin.Initialize();

    Console.WriteLine($"Loaded plugin: {plugin.Name}");
}

4. Custom Service Lifetime

Specify service lifetime when registering:

// Register as Singleton
services.AddServiceFromType<ICache>(ServiceLifetime.Singleton);

// Register as Transient
services.AddServiceFromType<IValidator>(ServiceLifetime.Transient);

// Register as Scoped (default)
services.AddServiceFromType<IUnitOfWork>(ServiceLifetime.Scoped);

5. Domain-Driven Design (DDD)

Auto-register domain services and repositories:

public class Startup {
    public void ConfigureServices(IServiceCollection services) {
        // Infrastructure layer
        services.AddServiceFromType<IRepository>(ServiceLifetime.Scoped);

        // Domain services
        services.AddServiceFromType<IDomainService>(ServiceLifetime.Scoped);

        // Application services
        services.AddServiceFromType<IApplicationService>(ServiceLifetime.Scoped);
    }
}

6. Assembly Analysis and Documentation

Generate documentation about your application structure:

using Myth.ValueProviders;

public class AssemblyAnalyzer {
    public void PrintApplicationStructure() {
        Console.WriteLine($"Base Namespace: {TypeProvider.BaseApplicationNamespace}");

        Console.WriteLine("\nAssemblies:");
        foreach (var assembly in TypeProvider.ApplicationAssemblies) {
            Console.WriteLine($"  - {assembly.GetName().Name} v{assembly.GetName().Version}");
        }

        Console.WriteLine("\nService Implementations:");
        var services = TypeProvider.GetTypesAssignableFrom<IService>();
        foreach (var service in services) {
            Console.WriteLine($"  - {service.FullName}");
        }
    }
}

API Reference

TypeProvider

Static class for type and assembly discovery.

Properties
// Gets the first part of your application namespace
public static string? BaseApplicationNamespace { get; }

// Gets all assemblies from your application
public static IEnumerable<Assembly> ApplicationAssemblies { get; }

// Gets all concrete types exported by your application
public static IEnumerable<Type> ApplicationTypes { get; }
Methods
// Gets types derived from or implementing the specified type
public static IEnumerable<Type> GetTypesAssignableFrom<TType>()

Examples:

// Get base namespace
var ns = TypeProvider.BaseApplicationNamespace;
// "MyCompany" from "MyCompany.ECommerce.Domain"

// Get all assemblies
var assemblies = TypeProvider.ApplicationAssemblies;

// Get all types
var allTypes = TypeProvider.ApplicationTypes;

// Get types implementing interface
var repositories = TypeProvider.GetTypesAssignableFrom<IRepository>();
var handlers = TypeProvider.GetTypesAssignableFrom<IHandler>();
var validators = TypeProvider.GetTypesAssignableFrom<IValidator>();

ServiceCollectionExtensions

Extension methods for IServiceCollection.

Methods
// Adds all implementations of the specified type to the service collection
public static IServiceCollection AddServiceFromType<TType>(
    this IServiceCollection services,
    ServiceLifetime serviceLifetime = ServiceLifetime.Scoped
)

Parameters:

  • TType: The base interface or type to search for implementations
  • serviceLifetime: The service lifetime (Scoped, Transient, or Singleton). Default: Scoped

Returns: The service collection for chaining

Throws:

  • InterfaceNotFoundException: When an implementation doesn't have a corresponding interface

Naming Convention: The method finds implementations by matching the interface name within the implementation name.

  • Interface: IPersonRepository → Implementation: PersonRepository (match: "PersonRepository")
  • Interface: IOrderService → Implementation: OrderService (match: "OrderService")

Examples:

// Scoped (default)
services.AddServiceFromType<IRepository>();

// Transient
services.AddServiceFromType<IValidator>(ServiceLifetime.Transient);

// Singleton
services.AddServiceFromType<ICache>(ServiceLifetime.Singleton);

Best Practices

1. Organize by Layers

Structure your DI registration by architectural layer:

public void ConfigureServices(IServiceCollection services) {
    // Persistence Layer
    services.AddServiceFromType<IRepository>(ServiceLifetime.Scoped);

    // Domain Layer
    services.AddServiceFromType<IDomainService>(ServiceLifetime.Scoped);

    // Application Layer
    services.AddServiceFromType<IApplicationService>(ServiceLifetime.Scoped);

    // Infrastructure Layer
    services.AddServiceFromType<IExternalService>(ServiceLifetime.Transient);
}

2. Use Marker Interfaces

Create marker interfaces for auto-registration:

// Marker interface for domain services
public interface IDomainService { }

public interface IOrderService : IDomainService {
    Task<Order> CreateOrderAsync(CreateOrderCommand command);
}

public class OrderService : IOrderService {
    public async Task<Order> CreateOrderAsync(CreateOrderCommand command) {
        // Implementation
    }
}

// Auto-register all domain services
services.AddServiceFromType<IDomainService>();

3. Follow Naming Conventions

Ensure consistent naming for automatic discovery:

// Good: Name matches interface
public interface IUserRepository { }
public class UserRepository : IUserRepository { }

// Good: Implementation name contains interface name
public interface IProductRepository { }
public class ProductRepositoryImpl : IProductRepository { }

// Bad: No naming correlation
public interface IOrderRepository { }
public class OrderDataAccess : IOrderRepository { }  // Won't be auto-discovered

4. Combine with Manual Registration

Use auto-registration for conventions, manual for exceptions:

// Auto-register most services
services.AddServiceFromType<IRepository>();
services.AddServiceFromType<IService>();

// Manually register special cases
services.AddSingleton<IConfiguration>(configuration);
services.AddScoped<ICurrentUser, CurrentUserAccessor>();
services.AddTransient<IEmailSender, SendGridEmailSender>();

5. Validate Registrations

Check that types were registered correctly:

var serviceProvider = services.BuildServiceProvider();

// Verify critical services are registered
var userRepo = serviceProvider.GetService<IUserRepository>();
if (userRepo == null) {
    throw new InvalidOperationException("IUserRepository not registered");
}

// Or use GetRequiredService to throw if not found
var orderService = serviceProvider.GetRequiredService<IOrderService>();

How It Works

Type Discovery Process

  1. Assembly Loading: Scans AppDomain.CurrentDomain.BaseDirectory for all .dll files
  2. Dynamic Loading: Loads assemblies not yet loaded into the current AppDomain
  3. Filtering: Excludes dynamic assemblies and keeps only concrete types
  4. Caching: Results are computed once per property access for performance

Auto-Registration Process

  1. Type Scanning: Finds all types implementing the specified base type/interface
  2. Interface Matching: For each implementation, finds the corresponding interface by name
  3. Registration: Creates a ServiceDescriptor and adds to the service collection
  4. Validation: Throws InterfaceNotFoundException if no matching interface is found

Performance Considerations

  • Assembly Scanning: Performed once per ApplicationAssemblies access; results are not cached between accesses
  • Type Discovery: Filters are applied efficiently using LINQ
  • Registration Time: Auto-registration happens at application startup, not runtime
  • Large Codebases: For applications with hundreds of assemblies, consider manual registration for critical paths

Integration with Other Myth Libraries

Myth.DependencyInjection works seamlessly with other Myth libraries:

using Myth.Extensions;
using Myth.ValueProviders;

var builder = WebApplication.CreateBuilder(args);

// Auto-register repositories (Myth.Repository)
builder.Services.AddServiceFromType<IRepository>();

// Add Flow pipeline support (Myth.Flow)
builder.Services.AddFlow();

// Add Guard validation (Myth.Guard)
builder.Services.AddGuard();

// Build with global provider support
var app = builder.BuildApp();

app.Run();

Troubleshooting

InterfaceNotFoundException

Problem: InterfaceNotFoundException: Not found a interface that corresponds to type

Solution: Ensure your implementation class name contains the interface name:

// Problematic
public interface IUserRepository { }
public class UserDataAccess : IUserRepository { }  // Name doesn't contain "IUserRepository"

// Fixed
public interface IUserRepository { }
public class UserRepository : IUserRepository { }  // Contains "UserRepository"

Types Not Discovered

Problem: Expected types are not found by GetTypesAssignableFrom<T>()

Solution:

  1. Ensure the assembly is loaded (referenced in your project)
  2. Verify types are concrete (not abstract or interfaces)
  3. Check that types are public and accessible

Multiple Interfaces per Implementation

Problem: A class implements multiple interfaces

Solution: The auto-registration finds the first interface containing the class name. For precise control, register manually:

// Auto-registration picks one interface
services.AddServiceFromType<IService>();

// Manual registration for multiple interfaces
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IReadOnlyUserRepository, UserRepository>();

License

This project is licensed under the Apache 2.0 License - see the LICENSE for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  • Myth.Flow: Pipeline orchestration with Result pattern
  • Myth.Flow.Actions: CQRS and event-driven architecture
  • Myth.Guard: Fluent validation and data integrity
  • Myth.Repository: Generic repository pattern implementation
  • Myth.Specification: Query specification pattern
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Myth.DependencyInjection:

Package Downloads
Myth.Repository.EntityFramework

Entity Framework Core implementations of repository pattern with Unit of Work, specification support, expression handling, and transaction management for robust data access with EF Core.

Harpy.IoC

Basis for the ioc layer of the Harpy Framework

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.5-preview.14 24 11/12/2025
3.0.5-preview.13 41 11/12/2025
3.0.5-preview.12 36 11/11/2025
3.0.5-preview.11 35 11/11/2025
3.0.5-preview.10 35 11/11/2025
3.0.5-preview.9 43 11/10/2025
3.0.5-preview.8 46 11/8/2025
3.0.5-preview.7 46 11/8/2025
3.0.5-preview.6 47 11/8/2025
3.0.5-preview.5 48 11/8/2025
3.0.5-preview.4 48 11/7/2025
3.0.5-preview.3 127 11/4/2025
3.0.5-preview.2 125 11/4/2025
3.0.5-preview.1 126 11/4/2025
3.0.4 204 11/3/2025
3.0.4-preview.19 68 11/2/2025
3.0.4-preview.18 63 11/1/2025
3.0.4-preview.17 65 11/1/2025
3.0.4-preview.16 65 11/1/2025
3.0.4-preview.15 61 10/31/2025
3.0.4-preview.14 128 10/31/2025
3.0.4-preview.13 127 10/30/2025
3.0.4-preview.12 125 10/23/2025
3.0.4-preview.11 119 10/23/2025
3.0.4-preview.10 120 10/23/2025
3.0.4-preview.9 118 10/23/2025
3.0.4-preview.8 112 10/22/2025
3.0.4-preview.6 112 10/21/2025
3.0.4-preview.5 112 10/21/2025
3.0.4-preview.4 117 10/20/2025
3.0.4-preview.3 117 10/20/2025
3.0.4-preview.2 38 10/18/2025
3.0.4-preview.1 125 10/7/2025
3.0.3 220 8/30/2025
3.0.2 116 8/23/2025
3.0.2-preview.4 122 8/21/2025
3.0.2-preview.3 102 8/16/2025
3.0.2-preview.1 72 5/23/2025
3.0.1 236 3/12/2025
3.0.1-preview.2 146 3/11/2025
3.0.1-preview.1 92 2/5/2025
3.0.0.2-preview 139 12/10/2024
3.0.0.1-preview 169 6/29/2024
3.0.0 179 12/10/2024
3.0.0-preview 166 6/28/2024
2.0.0.16 297 12/15/2023
2.0.0.15 195 12/15/2023
2.0.0.11 1,359 8/11/2022
2.0.0.10 1,317 7/20/2022
2.0.0.9 1,384 7/15/2022
2.0.0.8 1,373 7/12/2022
2.0.0.7 1,408 6/20/2022
2.0.0.6 1,451 5/23/2022
2.0.0.5 1,435 5/18/2022