geoder101.MoqProxy.DependencyInjection.Microsoft
1.0.25-alpha
dotnet add package geoder101.MoqProxy.DependencyInjection.Microsoft --version 1.0.25-alpha
NuGet\Install-Package geoder101.MoqProxy.DependencyInjection.Microsoft -Version 1.0.25-alpha
<PackageReference Include="geoder101.MoqProxy.DependencyInjection.Microsoft" Version="1.0.25-alpha" />
<PackageVersion Include="geoder101.MoqProxy.DependencyInjection.Microsoft" Version="1.0.25-alpha" />
<PackageReference Include="geoder101.MoqProxy.DependencyInjection.Microsoft" />
paket add geoder101.MoqProxy.DependencyInjection.Microsoft --version 1.0.25-alpha
#r "nuget: geoder101.MoqProxy.DependencyInjection.Microsoft, 1.0.25-alpha"
#:package geoder101.MoqProxy.DependencyInjection.Microsoft@1.0.25-alpha
#addin nuget:?package=geoder101.MoqProxy.DependencyInjection.Microsoft&version=1.0.25-alpha&prerelease
#tool nuget:?package=geoder101.MoqProxy.DependencyInjection.Microsoft&version=1.0.25-alpha&prerelease
MoqProxy.DependencyInjection.Microsoft
Microsoft.Extensions.DependencyInjection integration for MoqProxy - enabling proxy pattern mocking within ASP.NET Core and other dependency injection scenarios.
What is this?
This library provides extension methods to seamlessly integrate MoqProxy with Microsoft's dependency injection container. It allows you to wrap existing service registrations with Moq proxies for testing, enabling you to:
- Verify calls to services registered in your DI container
- Spy on real implementations without changing production code
- Test integration scenarios with partial mocking
- Observe service interactions in complex dependency graphs
Installation
dotnet add package geoder101.MoqProxy.DependencyInjection.Microsoft
Quick Start
using Microsoft.Extensions.DependencyInjection;
using Moq;
// Set up your services as usual
var services = new ServiceCollection();
services.AddSingleton<IEmailService, EmailService>();
services.AddSingleton<IUserService, UserService>();
// Wrap a service with a Moq proxy for testing
var emailMock = new Mock<IEmailService>();
services.AddMoqProxy(emailMock);
// Build and use the container
var provider = services.BuildServiceProvider();
var userService = provider.GetRequiredService<IUserService>();
// The UserService will receive the proxied EmailService
userService.RegisterUser("john@example.com");
// Verify the real EmailService was called through the proxy
emailMock.Verify(e => e.SendWelcomeEmail("john@example.com"), Times.Once);
How It Works
AddMoqProxy<TService>() decorates an existing service registration with a Moq proxy using the decorator pattern:
- Resolves the original service implementation from the container
- Sets up the mock as a proxy that forwards all calls to the original implementation
- Replaces the service registration with the mock object
This means:
- ✅ The real implementation runs normally
- ✅ You can verify all interactions via Moq
- ✅ You can override specific behaviors if needed
- ✅ Works with interfaces and classes
Usage Examples
Basic Service Proxying
var services = new ServiceCollection();
services.AddSingleton<ICalculator, Calculator>();
var mock = new Mock<ICalculator>();
services.AddMoqProxy(mock);
var provider = services.BuildServiceProvider();
var calculator = provider.GetRequiredService<ICalculator>();
// Calls are forwarded to the real Calculator implementation
var result = calculator.Add(2, 3); // Returns 5
// But you can still verify the call
mock.Verify(c => c.Add(2, 3), Times.Once);
Testing Service Dependencies
var services = new ServiceCollection();
services.AddSingleton<IRepository, Repository>();
services.AddSingleton<IBusinessLogic, BusinessLogic>(); // Depends on IRepository
// Proxy the repository to observe calls from BusinessLogic
var repoMock = new Mock<IRepository>();
services.AddMoqProxy(repoMock);
var provider = services.BuildServiceProvider();
var businessLogic = provider.GetRequiredService<IBusinessLogic>();
// Execute business logic that uses the repository
businessLogic.ProcessOrder(orderId: 123);
// Verify the repository was called correctly
repoMock.Verify(r => r.GetOrder(123), Times.Once);
repoMock.Verify(r => r.SaveOrder(It.IsAny<Order>()), Times.Once);
Selective Behavior Override
var services = new ServiceCollection();
services.AddSingleton<IPaymentGateway, StripePaymentGateway>();
var mock = new Mock<IPaymentGateway>();
services.AddMoqProxy(mock);
// Override specific behavior for testing
mock.Setup(p => p.IsAvailable()).Returns(false);
var provider = services.BuildServiceProvider();
var gateway = provider.GetRequiredService<IPaymentGateway>();
// Overridden behavior
Assert.False(gateway.IsAvailable()); // Returns false from setup
// Other calls still forward to StripePaymentGateway
gateway.ProcessPayment(amount: 100); // Calls real implementation
Integration Testing with ASP.NET Core
public class IntegrationTests : IClassFixture<WebApplicationFactory<Program>>
{
[Fact]
public async Task Registration_ShouldSendEmail()
{
// Arrange
var emailMock = new Mock<IEmailService>();
var factory = new WebApplicationFactory<Program>()
.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
// Proxy the email service
services.AddMoqProxy(emailMock);
});
});
var client = factory.CreateClient();
// Act
var response = await client.PostAsJsonAsync("/api/users/register", new { Email = "test@example.com" });
// Assert
response.EnsureSuccessStatusCode();
emailMock.Verify(e => e.SendWelcomeEmail("test@example.com"), Times.Once);
}
}
Multiple Service Proxying
var services = new ServiceCollection();
services.AddSingleton<ILogger, ConsoleLogger>();
services.AddSingleton<ICache, RedisCache>();
services.AddSingleton<IApi, ExternalApi>();
// Proxy multiple services
var loggerMock = new Mock<ILogger>();
var cacheMock = new Mock<ICache>();
var apiMock = new Mock<IApi>();
services.AddMoqProxy(loggerMock);
services.AddMoqProxy(cacheMock);
services.AddMoqProxy(apiMock);
var provider = services.BuildServiceProvider();
// All services are now proxied and verifiable
// ... run your test scenario ...
// Verify all interactions
loggerMock.Verify(l => l.Log(It.IsAny<string>()), Times.AtLeastOnce);
cacheMock.Verify(c => c.Get(It.IsAny<string>()), Times.Once);
apiMock.Verify(a => a.FetchData(), Times.Once);
Requirements
- The service of type
TServicemust already be registered in theIServiceCollection - Requires geoder101.MoqProxy package (installed as a dependency)
- Requires geoder101.Microsoft.Extensions.DependencyInjection for decorator support
API Reference
AddMoqProxy<TService>
public static IServiceCollection AddMoqProxy<TService>(
this IServiceCollection services,
Mock<TService> mock)
where TService : class
Parameters:
services- The service collection containing the service to proxymock- The Moq mock instance that will wrap the original implementation
Returns: The IServiceCollection for method chaining
Remarks:
- The service must be registered before calling
AddMoqProxy - The mock is automatically configured to proxy all calls using
SetupAsProxy() - The original service lifetime (Singleton, Scoped, Transient) is preserved
Technical Requirements
- .NET 8.0 or later - The library targets .NET 8.0
- Microsoft.Extensions.DependencyInjection 9.0.10 or later
- MoqProxy - The core proxy functionality (installed as a dependency)
- Moq 4.20.72 or later
Related Projects
- MoqProxy - The core proxy pattern extension for Moq
- Moq - The popular .NET mocking library
- Microsoft.Extensions.DependencyInjection - Microsoft's DI container
Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
License
This project is licensed under the MIT License - see the LICENSE.txt file for details.
Co-authored with Artificial Intelligence
This repository is part of an ongoing exploration into human-AI co-creation.
The code, comments, and structure emerged through dialogue between human intent and LLM reasoning — reviewed, refined, and grounded in human understanding.
| Product | Versions 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. |
-
net8.0
- geoder101.Microsoft.Extensions.DependencyInjection (>= 1.0.2-alpha)
- geoder101.MoqProxy (>= 1.0.25-alpha)
- Microsoft.Extensions.DependencyInjection (>= 9.0.10)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.25-alpha | 36 | 11/4/2025 |
| 1.0.22-alpha | 50 | 11/2/2025 |
| 1.0.12-alpha | 110 | 10/21/2025 |
| 1.0.6-alpha | 114 | 10/20/2025 |
| 1.0.1-alpha | 119 | 10/19/2025 |