Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,22 @@

namespace FixUnableToResolveServiceIssue.Tests.Controllers
{
internal class UserControllerIntegrationTest
public class UserControllerIntegrationTest
{
private readonly WebApplicationFactory<Program> _application;
private readonly HttpClient _httpClient;

public UserControllerIntegrationTest()
{
var application = new WebApplicationFactory<Program>();
_httpClient = application.CreateClient();
_application = new WebApplicationFactory<Program>();
_httpClient = _application.CreateClient();
}

[OneTimeTearDown]
public void OneTimeTearDown()
{
_httpClient.Dispose();
_application.Dispose();
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand All @@ -10,12 +10,12 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.8" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
<PackageReference Include="NUnit.Analyzers" Version="3.5.0" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.12" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.10.1" />
<PackageReference Include="NUnit" Version="4.6.1" />
<PackageReference Include="NUnit3TestAdapter" Version="6.3.0" />
<PackageReference Include="NUnit.Analyzers" Version="4.15.0" />
<PackageReference Include="coverlet.collector" Version="10.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using FixUnableToResolveServiceIssue.Services;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;

namespace FixUnableToResolveServiceIssue.Tests.Services
{
public class ServiceResolutionTest
{
private WebApplicationFactory<Program> _factory = null!;

[OneTimeSetUp]
public void OneTimeSetUp()
{
_factory = new WebApplicationFactory<Program>();
}

[OneTimeTearDown]
public void OneTimeTearDown()
{
_factory.Dispose();
}

[Test]
public void WhenSmtpSettingsAreBoundToOptions_EmailServiceResolvesWithConfiguredValues()
{
//Arrange
using var scope = _factory.Services.CreateScope();

//Act
var emailService = scope.ServiceProvider.GetRequiredService<EmailService>();

//Assert
Assert.That(emailService.GetServerAddress(), Is.EqualTo("smtp.example.com:587"));
}

[Test]
public void WhenAddHttpClientIsRegistered_HttpClientTypesResolve()
{
//Arrange
using var scope = _factory.Services.CreateScope();
var provider = scope.ServiceProvider;

//Act
var httpClientFactory = provider.GetService<IHttpClientFactory>();
var httpClient = provider.GetService<HttpClient>();
var weatherClient = provider.GetService<WeatherClient>();

//Assert
Assert.That(httpClientFactory, Is.Not.Null);
Assert.That(httpClient, Is.Not.Null);
Assert.That(weatherClient, Is.Not.Null);
Assert.That(httpClientFactory!.CreateClient(nameof(WeatherClient)).BaseAddress,
Is.EqualTo(new Uri("https://api.example.com/")));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.12" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
using FixUnableToResolveServiceIssue.Interfaces;
using FixUnableToResolveServiceIssue.Services;
using FixUnableToResolveServiceIssue.Settings;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();

//Add this line to register the service as a singleton in the dependency injection container:
//Add this line to register the service with a scoped lifetime in the dependency injection container:
builder.Services.AddScoped<IUserService, UserService>();

// A plain string cannot be resolved by type, so the SMTP values are bound to an options class
// and EmailService asks for IOptions<SmtpSettings> instead:
builder.Services.Configure<SmtpSettings>(builder.Configuration.GetSection("Smtp"));
builder.Services.AddScoped<EmailService>();

// Registers IHttpClientFactory and makes a plain HttpClient injectable:
builder.Services.AddHttpClient();

// Registers WeatherClient as a typed client with its own configured HttpClient:
builder.Services.AddHttpClient<WeatherClient>(client =>
{
client.BaseAddress = new Uri("https://api.example.com/");
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
app.MapOpenApi();
}

app.UseHttpsRedirection();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"launchUrl": "api/User",
"applicationUrl": "https://localhost:7027;http://localhost:5073",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using FixUnableToResolveServiceIssue.Settings;
using Microsoft.Extensions.Options;

namespace FixUnableToResolveServiceIssue.Services
{
public class EmailService
{
private readonly SmtpSettings _settings;

// Asking for "string host" here instead would throw
// "Unable to resolve service for type 'System.String'", because the container
// cannot tell which string we mean. IOptions<SmtpSettings> is a type it can resolve.
public EmailService(IOptions<SmtpSettings> options)
{
_settings = options.Value;
}

public string GetServerAddress() => $"{_settings.Host}:{_settings.Port}";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace FixUnableToResolveServiceIssue.Services
{
public class WeatherClient(HttpClient httpClient)
{
public Task<string> GetForecastAsync() => httpClient.GetStringAsync("forecast");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace FixUnableToResolveServiceIssue.Settings
{
public class SmtpSettings
{
public string Host { get; set; } = string.Empty;
public int Port { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",
"Smtp": {
"Host": "smtp.example.com",
"Port": 587
}
}
Loading