Skip to content

Commit bed60d8

Browse files
Adds Aspire (#859)
* Added aspire projects * Added Aspire test project * Renamend aspire tests file * Final commit for adding aspire
1 parent 92a5f22 commit bed60d8

File tree

14 files changed

+347
-14
lines changed

14 files changed

+347
-14
lines changed

.template.config/template.json

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,72 @@
11
{
2-
"$schema": "http://json.schemastore.org/template",
3-
"author": "Steve Smith @ardalis, Erik Dahl",
4-
"classifications": [
5-
"Web","ASP.NET","Clean Architecture"
6-
],
7-
"tags": {
2+
"$schema": "http://json.schemastore.org/template",
3+
"author": "Steve Smith @ardalis, Erik Dahl",
4+
"classifications": [
5+
"Web",
6+
"ASP.NET",
7+
"Clean Architecture"
8+
],
9+
"tags": {
810
"language": "C#",
9-
"type":"project"
10-
},
11-
"identity": "Ardalis.CleanArchitecture.Template",
12-
"name": "ASP.NET Clean Architecture Solution",
13-
"shortName": "clean-arch",
14-
"sourceName": "Clean.Architecture",
15-
"preferNameDirectory": true
16-
}
11+
"type": "project"
12+
},
13+
"identity": "Ardalis.CleanArchitecture.Template",
14+
"name": "ASP.NET Clean Architecture Solution",
15+
"shortName": "clean-arch",
16+
"sourceName": "Clean.Architecture",
17+
"preferNameDirectory": true,
18+
"symbols": {
19+
"aspire": {
20+
"type": "parameter",
21+
"datatype": "bool",
22+
"defaultValue": "false",
23+
"description": "Include .NET Aspire."
24+
}
25+
},
26+
"sources": [
27+
{
28+
"modifiers": [
29+
{
30+
"condition": "(!aspire)",
31+
"exclude": [
32+
"src/Clean.Architecture.AspireHost/**",
33+
"src/Clean.Architecture.ServiceDefaults/**",
34+
"tests/Clean.Architecture.AspireTests/**"
35+
]
36+
},
37+
{
38+
"condition": "(aspire)",
39+
"include": [
40+
"src/Clean.Architecture.AspireHost/**",
41+
"src/Clean.Architecture.ServiceDefaults/**",
42+
"tests/Clean.Architecture.AspireTests/**"
43+
]
44+
}
45+
]
46+
}
47+
],
48+
"primaryOutputs": [{
49+
"path": "src/Clean.Architecture.AspireHost/Clean.Architecture.AspireHost.csproj"
50+
},
51+
{
52+
"path": "src/Clean.Architecture.ServiceDefaults/Clean.Architecture.ServiceDefaults.csproj"
53+
},
54+
{
55+
"path": "tests/Clean.Architecture.AspireTests/Clean.Architecture.AspireTests.csproj"
56+
}
57+
],
58+
"postActions": [{
59+
"condition": "(aspire)",
60+
"description": "Add Aspire projects to solution",
61+
"manualInstructions": [{
62+
"text": "Add generated project to solution manually."
63+
}
64+
],
65+
"args": {
66+
"isRoot": "true"
67+
},
68+
"actionId": "D396686C-DE0E-4DE6-906D-291CD29FC5DE",
69+
"continueOnError": true
70+
}
71+
]
72+
}

Clean.Architecture.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1919
CleanArchitecture.nuspec = CleanArchitecture.nuspec
2020
Directory.Build.props = Directory.Build.props
2121
Directory.Packages.props = Directory.Packages.props
22+
template.json = template.json
2223
EndProjectSection
2324
EndProject
2425
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Clean.Architecture.FunctionalTests", "tests\Clean.Architecture.FunctionalTests\Clean.Architecture.FunctionalTests.csproj", "{7D84EFEE-A7D9-44AD-A0A3-38EC7882D94C}"

Directory.Packages.props

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,16 @@
3838
<PackageVersion Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" />
3939
<PackageVersion Include="xunit" Version="2.9.2" />
4040
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.0-pre.35" />
41+
<!--#if (aspire) -->
42+
<PackageVersion Include="Aspire.Hosting.AppHost" Version="9.0.0-rc.1.24511.1" />
43+
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="8.10.0" />
44+
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="9.0.0-rc.1.24511.1" />
45+
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
46+
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
47+
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
48+
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
49+
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.9.0" />
50+
<PackageVersion Include="Aspire.Hosting.Testing" Version="9.0.0-rc.1.24511.1" />
51+
<!--#endif -->
4152
</ItemGroup>
4253
</Project>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0-rc.1.24511.1" />
4+
5+
<PropertyGroup>
6+
<OutputType>Exe</OutputType>
7+
<TargetFramework>net9.0</TargetFramework>
8+
<ImplicitUsings>enable</ImplicitUsings>
9+
<Nullable>enable</Nullable>
10+
<IsAspireHost>true</IsAspireHost>
11+
<UserSecretsId>c540eeb6-e06b-4456-a539-be58dd8b88c7</UserSecretsId>
12+
</PropertyGroup>
13+
14+
<ItemGroup>
15+
<PackageReference Include="Aspire.Hosting.AppHost" />
16+
</ItemGroup>
17+
18+
<ItemGroup>
19+
<ProjectReference Include="..\Clean.Architecture.Web\Clean.Architecture.Web.csproj" />
20+
</ItemGroup>
21+
<ItemGroup>
22+
<!-- The IsAspireProjectResource attribute tells .NET Aspire to treat this
23+
reference as a standard project reference and not attempt to generate
24+
a metadata file -->
25+
<ProjectReference Include="..\Clean.Architecture.ServiceDefaults\Clean.Architecture.ServiceDefaults.csproj"
26+
IsAspireProjectResource="false" />
27+
</ItemGroup>
28+
29+
</Project>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
var builder = DistributedApplication.CreateBuilder(args);
2+
3+
builder.AddProject<Projects.Clean_Architecture_Web>("web");
4+
5+
builder.Build().Run();
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"$schema": "https://json.schemastore.org/launchsettings.json",
3+
"profiles": {
4+
"https": {
5+
"commandName": "Project",
6+
"dotnetRunMessages": true,
7+
"launchBrowser": true,
8+
"applicationUrl": "https://localhost:17143;http://localhost:15258",
9+
"environmentVariables": {
10+
"ASPNETCORE_ENVIRONMENT": "Development",
11+
"DOTNET_ENVIRONMENT": "Development",
12+
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21007",
13+
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22245"
14+
}
15+
},
16+
"http": {
17+
"commandName": "Project",
18+
"dotnetRunMessages": true,
19+
"launchBrowser": true,
20+
"applicationUrl": "http://localhost:15258",
21+
"environmentVariables": {
22+
"ASPNETCORE_ENVIRONMENT": "Development",
23+
"DOTNET_ENVIRONMENT": "Development",
24+
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19187",
25+
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20134"
26+
}
27+
}
28+
}
29+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
}
8+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning",
6+
"Aspire.Hosting.Dcp": "Warning"
7+
}
8+
}
9+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<IsAspireSharedProject>true</IsAspireSharedProject>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<FrameworkReference Include="Microsoft.AspNetCore.App" />
12+
13+
<PackageReference Include="Microsoft.Extensions.Http.Resilience" />
14+
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" />
15+
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" />
16+
<PackageReference Include="OpenTelemetry.Extensions.Hosting" />
17+
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
18+
<PackageReference Include="OpenTelemetry.Instrumentation.Http" />
19+
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" />
20+
</ItemGroup>
21+
22+
</Project>
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
using Microsoft.AspNetCore.Builder;
2+
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.Extensions.Diagnostics.HealthChecks;
5+
using Microsoft.Extensions.Logging;
6+
using Microsoft.Extensions.ServiceDiscovery;
7+
using OpenTelemetry;
8+
using OpenTelemetry.Metrics;
9+
using OpenTelemetry.Trace;
10+
11+
namespace Microsoft.Extensions.Hosting;
12+
13+
// Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry.
14+
// This project should be referenced by each service project in your solution.
15+
// To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults
16+
public static class Extensions
17+
{
18+
public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
19+
{
20+
builder.ConfigureOpenTelemetry();
21+
22+
builder.AddDefaultHealthChecks();
23+
24+
builder.Services.AddServiceDiscovery();
25+
26+
builder.Services.ConfigureHttpClientDefaults(http =>
27+
{
28+
// Turn on resilience by default
29+
http.AddStandardResilienceHandler();
30+
31+
// Turn on service discovery by default
32+
http.AddServiceDiscovery();
33+
});
34+
35+
// Uncomment the following to restrict the allowed schemes for service discovery.
36+
// builder.Services.Configure<ServiceDiscoveryOptions>(options =>
37+
// {
38+
// options.AllowedSchemes = ["https"];
39+
// });
40+
41+
return builder;
42+
}
43+
44+
public static TBuilder ConfigureOpenTelemetry<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
45+
{
46+
builder.Logging.AddOpenTelemetry(logging =>
47+
{
48+
logging.IncludeFormattedMessage = true;
49+
logging.IncludeScopes = true;
50+
});
51+
52+
builder.Services.AddOpenTelemetry()
53+
.WithMetrics(metrics =>
54+
{
55+
metrics.AddAspNetCoreInstrumentation()
56+
.AddHttpClientInstrumentation()
57+
.AddRuntimeInstrumentation();
58+
})
59+
.WithTracing(tracing =>
60+
{
61+
tracing.AddAspNetCoreInstrumentation()
62+
// Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package)
63+
//.AddGrpcClientInstrumentation()
64+
.AddHttpClientInstrumentation();
65+
});
66+
67+
builder.AddOpenTelemetryExporters();
68+
69+
return builder;
70+
}
71+
72+
private static TBuilder AddOpenTelemetryExporters<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
73+
{
74+
var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
75+
76+
if (useOtlpExporter)
77+
{
78+
builder.Services.AddOpenTelemetry().UseOtlpExporter();
79+
}
80+
81+
// Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.AspNetCore package)
82+
//if (!string.IsNullOrEmpty(builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]))
83+
//{
84+
// builder.Services.AddOpenTelemetry()
85+
// .UseAzureMonitor();
86+
//}
87+
88+
return builder;
89+
}
90+
91+
public static TBuilder AddDefaultHealthChecks<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
92+
{
93+
builder.Services.AddHealthChecks()
94+
// Add a default liveness check to ensure app is responsive
95+
.AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]);
96+
97+
return builder;
98+
}
99+
100+
public static WebApplication MapDefaultEndpoints(this WebApplication app)
101+
{
102+
// Adding health checks endpoints to applications in non-development environments has security implications.
103+
// See https://aka.ms/dotnet/aspire/healthchecks for details before enabling these endpoints in non-development environments.
104+
if (app.Environment.IsDevelopment())
105+
{
106+
// All health checks must pass for app to be considered ready to accept traffic after starting
107+
app.MapHealthChecks("/health");
108+
109+
// Only health checks tagged with the "live" tag must pass for app to be considered alive
110+
app.MapHealthChecks("/alive", new HealthCheckOptions
111+
{
112+
Predicate = r => r.Tags.Contains("live")
113+
});
114+
}
115+
116+
return app;
117+
}
118+
}

0 commit comments

Comments
 (0)