.Net Aspire初体验
今天参加了Post Microsoft Build & AI Day深圳的集会,众多大佬分享了非常优质前沿的技术和实践,实在受益良多,为了消化吸收关于张队分享的.Net Aspire的内容,特实操一遍小示例并记录如下:
1、以VS2022为例,先升级到最新的版本v17.10.3,新建.NET Aspire Starter应用程序项目,选择文件夹及Redis勾选和勾选生成Tests(HTTPS不能去除勾选)。
生成的文件夹结构如下:
可以看到按模板生成了一个ApiService(这里是以前的天气广播内容);一个Web项目;一个AppHost( 一个Host,把ApiService及Web前端给引用进来);一个ServiceDefaults扩展类;一个Tests测试项目。
AspireApp1.ApiService项目的主要内容:
Program.cs:
1 var builder = WebApplication.CreateBuilder(args);
2
3 // Add service defaults & Aspire components.
4 builder.AddServiceDefaults();
5
6 // Add services to the container.
7 builder.Services.AddProblemDetails();
8
9 var app = builder.Build();
10
11 // Configure the HTTP request pipeline.
12 app.UseExceptionHandler();
13
14 var summaries = new[]
15 {
16 "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
17 };
18
19 app.MapGet("/weatherforecast", () =>
20 {
21 var forecast = Enumerable.Range(1, 5).Select(index =>
22 new WeatherForecast
23 (
24 DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
25 Random.Shared.Next(-20, 55),
26 summaries[Random.Shared.Next(summaries.Length)]
27 ))
28 .ToArray();
29 return forecast;
30 });
31
32 app.MapDefaultEndpoints();
33
34 app.Run();
35
36 record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
37 {
38 public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
39 }
AspireApp1.Web项目的主要内容:
Program.cs:
1 using AspireApp1.Web;
2 using AspireApp1.Web.Components;
3
4 var builder = WebApplication.CreateBuilder(args);
5
6 // Add service defaults & Aspire components.
7 builder.AddServiceDefaults();
8
9 // Add services to the container.
10 builder.Services.AddRazorComponents()
11 .AddInteractiveServerComponents();
12
13 builder.Services.AddOutputCache();
14
15 builder.Services.AddHttpClient<WeatherApiClient>(client => client.BaseAddress = new("http://apiservice"));
16
17 var app = builder.Build();
18
19 if (!app.Environment.IsDevelopment())
20 {
21 app.UseExceptionHandler("/Error", createScopeForErrors: true);
22 }
23
24 app.UseStaticFiles();
25 app.UseAntiforgery();
26
27 app.UseOutputCache();
28
29 app.MapRazorComponents<App>()
30 .AddInteractiveServerRenderMode();
31
32 app.MapDefaultEndpoints();
33
34 app.Run();
WeatherApiClient.cs:
1 namespace AspireApp1.Web;
2
3 public class WeatherApiClient(HttpClient httpClient)
4 {
5 public async Task<WeatherForecast[]> GetWeatherAsync(int maxItems = 10, CancellationToken cancellationToken = default)
6 {
7 List<WeatherForecast>? forecasts = null;
8
9 await foreach (var forecast in httpClient.GetFromJsonAsAsyncEnumerable<WeatherForecast>("/weatherforecast", cancellationToken))
10 {
11 if (forecasts?.Count >= maxItems)
12 {
13 break;
14 }
15 if (forecast is not null)
16 {
17 forecasts ??= [];
18 forecasts.Add(forecast);
19 }
20 }
21
22 return forecasts?.ToArray() ?? [];
23 }
24 }
25
26 public record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
27 {
28 public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
29 }
AspireApp1.ServiceDefaults项目的主要内容:
Extensions.cs:
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 OpenTelemetry;
7 using OpenTelemetry.Metrics;
8 using OpenTelemetry.Trace;
9
10 namespace Microsoft.Extensions.Hosting;
11
12 // Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry.
13 // This project should be referenced by each service project in your solution.
14 // To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults
15 public static class Extensions
16 {
17 public static IHostApplicationBuilder AddServiceDefaults(this IHostApplicationBuilder builder)
18 {
19 builder.ConfigureOpenTelemetry();
20
21 builder.AddDefaultHealthChecks();
22
23 builder.Services.AddServiceDiscovery();
24
25 builder.Services.ConfigureHttpClientDefaults(http =>
26 {
27 // Turn on resilience by default
28 http.AddStandardResilienceHandler();
29
30 // Turn on service discovery by default
31 http.AddServiceDiscovery();
32 });
33
34 return builder;
35 }
36
37 public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicationBuilder builder)
38 {
39 builder.Logging.AddOpenTelemetry(logging =>
40 {
41 logging.IncludeFormattedMessage = true;
42 logging.IncludeScopes = true;
43 });
44
45 builder.Services.AddOpenTelemetry()
46 .WithMetrics(metrics =>
47 {
48 metrics.AddAspNetCoreInstrumentation()
49 .AddHttpClientInstrumentation()
50 .AddRuntimeInstrumentation();
51 })
52 .WithTracing(tracing =>
53 {
54 tracing.AddAspNetCoreInstrumentation()
55 // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package)
56 //.AddGrpcClientInstrumentation()
57 .AddHttpClientInstrumentation();
58 });
59
60 builder.AddOpenTelemetryExporters();
61
62 return builder;
63 }
64
65 private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostApplicationBuilder builder)
66 {
67 var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
68
69 if (useOtlpExporter)
70 {
71 builder.Services.AddOpenTelemetry().UseOtlpExporter();
72 }
73
74 // Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.AspNetCore package)
75 //if (!string.IsNullOrEmpty(builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]))
76 //{
77 // builder.Services.AddOpenTelemetry()
78 // .UseAzureMonitor();
79 //}
80
81 return builder;
82 }
83
84 public static IHostApplicationBuilder AddDefaultHealthChecks(this IHostApplicationBuilder builder)
85 {
86 builder.Services.AddHealthChecks()
87 // Add a default liveness check to ensure app is responsive
88 .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]);
89
90 return builder;
91 }
92
93 public static WebApplication MapDefaultEndpoints(this WebApplication app)
94 {
95 // Adding health checks endpoints to applications in non-development environments has security implications.
96 // See https://aka.ms/dotnet/aspire/healthchecks for details before enabling these endpoints in non-development environments.
97 if (app.Environment.IsDevelopment())
98 {
99 // All health checks must pass for app to be considered ready to accept traffic after starting
100 app.MapHealthChecks("/health");
101
102 // Only health checks tagged with the "live" tag must pass for app to be considered alive
103 app.MapHealthChecks("/alive", new HealthCheckOptions
104 {
105 Predicate = r => r.Tags.Contains("live")
106 });
107 }
108
109 return app;
110 }
111 }
AspireApp1.AppHost项目的主要内容:
Program.cs:
1 var builder = DistributedApplication.CreateBuilder(args);
2
3 var apiService = builder.AddProject<Projects.AspireApp1_ApiService>("apiservice");
4
5 builder.AddProject<Projects.AspireApp1_Web>("webfrontend")
6 .WithExternalHttpEndpoints()
7 .WithReference(apiService);
8
9 builder.Build().Run();
还有一个Tests测试项目的内容:
WebTests.cs:
1 using System.Net;
2
3 namespace AspireApp1.Tests;
4
5 public class WebTests
6 {
7 [Fact]
8 public async Task GetWebResourceRootReturnsOkStatusCode()
9 {
10 // Arrange
11 var appHost = await DistributedApplicationTestingBuilder.CreateAsync<Projects.AspireApp1_AppHost>();
12 await using var app = await appHost.BuildAsync();
13 await app.StartAsync();
14
15 // Act
16 var httpClient = app.CreateHttpClient("webfrontend");
17 var response = await httpClient.GetAsync("/");
18
19 // Assert
20 Assert.Equal(HttpStatusCode.OK, response.StatusCode);
21 }
22 }
2、我们将AspireApp1.AppHost项目设为启动项目,按F5运行。项目即启动生成和运行,可在输出窗口看到对应信息。等程序运行起来会自动打开一个浏览器概览仪表盘窗口如下:
点击对应项目的终结点,即可看到对应的内容:
AspireApp1.ApiService:
AspireApp1.Web:
在仪表盘可以看到资源、控制台、结构化、跟踪、指标几个栏目,没有写一句代码,你的可观测、生产就绪的云原生分布式应用程序就搭建完成了。
以下是一些图示:
另外多嘴一句,并不是用了Aspire就一定要上云,我突然有个主意,边缘运算、单体程序照样也可以用Aspire。另外Aspire和Dapr应该是有益的补充,而不是替代关系。
.Net Aspire初体验的更多相关文章
- .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验
不知不觉,“.NET平台开源项目速览“系列文章已经15篇了,每一篇都非常受欢迎,可能技术水平不高,但足够入门了.虽然工作很忙,但还是会抽空把自己知道的,已经平时遇到的好的开源项目分享出来.今天就给大家 ...
- Xamarin+Prism开发详解四:简单Mac OS 虚拟机安装方法与Visual Studio for Mac 初体验
Mac OS 虚拟机安装方法 最近把自己的电脑升级了一下SSD固态硬盘,总算是有容量安装Mac 虚拟机了!经过心碎的安装探索,尝试了国内外的各种安装方法,最后在youtube上找到了一个好方法. 简单 ...
- Spring之初体验
Spring之初体验 Spring是一个轻量级的Java Web开发框架,以IoC(Inverse of Control 控制反转)和 ...
- Xamarin.iOS开发初体验
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKwAAAA+CAIAAAA5/WfHAAAJrklEQVR4nO2c/VdTRxrH+wfdU84pW0
- 【腾讯Bugly干货分享】基于 Webpack & Vue & Vue-Router 的 SPA 初体验
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57d13a57132ff21c38110186 导语 最近这几年的前端圈子,由于 ...
- 【Knockout.js 学习体验之旅】(1)ko初体验
前言 什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular.React啊,再不赶紧的话,他们也要变out了哦.身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包, ...
- 在同一个硬盘上安装多个 Linux 发行版及 Fedora 21 、Fedora 22 初体验
在同一个硬盘上安装多个 Linux 发行版 以前对多个 Linux 发行版的折腾主要是在虚拟机上完成.我的桌面电脑性能比较强大,玩玩虚拟机没啥问题,但是笔记本电脑就不行了.要在我的笔记本电脑上折腾多个 ...
- 百度EChart3初体验
由于项目需要在首页搞一个订单数量的走势图,经过多方查找,体验,感觉ECharts不错,封装的很细,我们只需要看自己需要那种类型的图表,搞定好自己的json数据就OK.至于说如何体现出来,官网的教程很详 ...
- Python导出Excel为Lua/Json/Xml实例教程(二):xlrd初体验
Python导出Excel为Lua/Json/Xml实例教程(二):xlrd初体验 相关链接: Python导出Excel为Lua/Json/Xml实例教程(一):初识Python Python导出E ...
- Docker初体验
## Docker初体验 安装 因为我用的是mac,所以安装很简单,下载dmg下来之后拖拽安装即可完成. 需要注意的就是由于之前的docker是基于linux开发,不支持mac,所以就出现了docke ...
随机推荐
- 1024程序员节,写最棒的coding,做最靓的仔
Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 1024程序员节,写最棒的coding,做最靓的仔 日期: ...
- 初识python day1记录
程序语言中的分类 在程序中有分为高级语言Java python go与低级语言C 汇编,每种语言都有自己的规则,但是最终目的都是给计算机识别的,所以他的底层肯定是一些二进制010101,像java/p ...
- 面试官:告诉我为什么static和transient关键字修饰的变量不能被序列化?
一.写在开头 在上一篇学习序列化的文章中我们提出了这样的一个问题: "如果在我的对象中,有些变量并不想被序列化应该怎么办呢?" 当时给的回答是:不想被序列化的变量我们可以使用tra ...
- 记一个,生产遇到的redission锁,释放问题:lock.tryLock(0, 0, TimeUnit.SECONDS)
package com.aswatson.cdc.test; import org.redisson.Redisson; import org.redisson.api.RLock; import o ...
- Linux系统的硬件信息
查看Linux系统的硬件信息 [1]查看内核信息 uname 用于显示系统的内核信息 option -s:显示内核名称 -r:显示内核版本 [root@bogon /]# uname -a Linux ...
- java springboot监听事件和处理事件
在Spring Boot中,监听和处理事件是一种常用的模式,用于在应用程序的不同部分之间传递信息.Spring 的事件发布/订阅模型允许我们创建自定义事件,并在这些事件发生时由注册的监听器进行处理.这 ...
- node.js (原生模板引擎模板)
app01 // 引入http模块 const http = require('http'); //连接数据库 require('./model/connects'); // 创建网站服务器 cons ...
- 2022 开源之夏 | Curve 邀你与中国存储软件共成长,赢万元奖金
Curve 社区携手开源之夏,邀你开展有趣而精彩的开源之旅,直面社区大咖,积累项目经历,摘取丰厚奖金,共同推进我国基础软件自主创新 2022 年,Curve 社区再次加入系列高校开源活动 -- 开源之 ...
- canvas绘制飞线效果
在我们做的可视化大屏项目中,经常会遇到飞线的效果. 在我们的大屏编辑器中,可以通过拖拽+配置参数的方式很快就能够实现.下面是我们使用大屏编辑器实现的一个项目效果: 中间地图就有飞线的效果. 抛开编辑器 ...
- webpack4.15.1 学习笔记(六) — 代码拆分(Code Splitting)
目录 入口起点 防止重复 动态导入(dynamic imports) 代码拆分能够将代码分离到不同的 bundle 中,然后可以按需加载或并行加载这些文件.代码拆分可以用于获取更小的 bundle,以 ...