DevExpress XAF是一款强大的现代应用程序框架,允许同时开发ASP.NET和WinForms。DevExpress XAF采用模块化设计,开发人员可以选择内建模块,也可以自行创建,从而以更快的速度和比开发人员当前更强有力的方式创建应用程序。
.NET Aspire是一组工具、模板和包,用于构建可观察的、可生产的应用程序。DevExpress XAF团队花费了一些时间考虑Aspire的功能,试图找到最好的集成点,让XAF开发人员能够利用Aspire开箱即用的业务流程特性。
DevExpress技术交流群11:749942875 欢迎一起进群讨论
在最近的一篇文章中我们介绍了如何对一个 XAF Blazor 项目进行调整,来支持 .NET Aspire(点击这里回顾>>)。通过对启动逻辑进行一些修改——包括标准的 XAF 项目模板和 Aspire 的 Visual Studio 向导生成的代码,已经可以让 XAF Blazor 项目作为 Aspire 编排体系的一部分运行了。但那只是最小规模的编排,只有一个模块!接下来我们将会把部署方面的内容留到第三篇(敬请关注!),接下来得系列文章将介绍在示例项目中为实现以下三个场景所做的修改:
- 通过 OpenTelemetry 将自定义活动和指标记录到 Aspire 仪表盘
- 将 SQL Server 作为一个由 Aspire 协调运行的容器化依赖项
- 在编排中添加一个额外的服务,展示更复杂的系统结构
完整示例项目已托管在这个 GitHub 仓库中。下面基于我在第一篇文章中描述的项目初始状态,展开说明新的功能实现。
利用 OpenTelemetry 支持自定义指标与活动日志
Aspire 仪表盘的集成,是许多应用项目在启用 Aspire 后最直观的新特性之一。正如在演示项目的第一步中看到的,启用默认的跟踪和指标来源非常简单。接下来我们就会思考:如何将遥测系统用于我们自己的场景,比如记录自定义日志、报告业务指标与活动?
第一步,我创建了文件 XafAspireDemo.Blazor.Server/Controllers/ImportantBusinessOperationsController.cs,它实现了一个基本的 XAF 控制器,并提供了一个动作(Action)。该操作会自动出现在用户界面中,因此可以用作交互式测试触发器。以下是代码:
namespace XafAspireDemo.Blazor.Server.Controllers { public class ImportantBusinessOperationsController : Controller { SimpleAction importantBusinessAction; IServiceProvider serviceProvider; public ImportantBusinessOperationsController() { importantBusinessAction = new SimpleAction( this, "ImportantBusinessAction", PredefinedCategory.View ); importantBusinessAction.Execute += ImportantBusinessAction_Execute; } [ActivatorUtilitiesConstructor] public ImportantBusinessOperationsController(IServiceProvider serviceProvider) : this() { this.serviceProvider = serviceProvider; } private async void ImportantBusinessAction_Execute( object sender, SimpleActionExecuteEventArgs e ) { var logger = serviceProvider.GetRequiredService< ILogger<ImportantBusinessOperationsController> >(); importantBusinessAction.Enabled["ImportantBusinessActionRunning"] = false; logger.LogInformation("ImportantBusinessAction started."); try { // This is where we perform the magic for the important business action. // Run a task that waits a random time between half a second and five seconds. await Task.Run(() => { Thread.Sleep(new Random().Next(500, 5000)); }); } catch (Exception ex) { logger.LogError(ex, "ImportantBusinessAction failed."); throw; } finally { importantBusinessAction.Enabled["ImportantBusinessActionRunning"] = true; } } protected override void OnActivated() { base.OnActivated(); var logger = serviceProvider.GetRequiredService< ILogger<ImportantBusinessOperationsController> >(); logger.LogInformation("ImportantBusinessOperationsController activated."); } protected override void OnDeactivated() { var logger = serviceProvider.GetRequiredService< ILogger<ImportantBusinessOperationsController> >(); logger.LogInformation("ImportantBusinessOperationsController deactivated."); base.OnDeactivated(); } } }
如你所见,这段代码已经加入了日志记录的逻辑。它使用的是 .NET 提供的标准 ILogger<T> 接口,并结合了构造函数依赖注入(通过 IServiceProvider 获取服务实例),这是XAF推荐的方式。
ASP.NET Core 的日志基础设施会自动将这些日志输出集成到 Aspire 仪表盘中。完成上述更改后,运行程序并点击Important Business Action按钮,即可在仪表盘中查看相关日志输出。按钮会被随机禁用一段时间,并在初始化与交互过程开始时输出日志内容,在仪表盘的“结构化日志(Structured Logs)”页面即可查看这些信息。


要记录 OpenTelemetry 的活动(Activity)并使用计量器(Meter),您需要在应用启动时初始化这些对象,并确保相关代码能够访问到它们。可以通过全局单例模式实现,但在这个示例项目中,更合理的方式是继续使用依赖注入机制,并让它来处理生命周期管理。
以下是 XafAspireDemo.Blazor.Server.Telemetry 类的实现:
namespace XafAspireDemo.Blazor.Server { public class Telemetry : IDisposable { public ActivitySource ActivitySource { get; } public Meter Meter { get; } public string MeterName => Meter.Name; public Counter<long> ImportantBusinessOperationCounter { get; } public Histogram<double> ImportantBusinessOperationDuration { get; } public Telemetry( string serviceName = "XafAspireDemo.Blazor.Server", string version = "1.0.0" ) { ActivitySource = new ActivitySource(serviceName, version); Meter = new Meter(serviceName, version); ImportantBusinessOperationCounter = Meter.CreateCounter<long>( "important_business_operation.execution_count" ); ImportantBusinessOperationDuration = Meter.CreateHistogram<double>( "important_business_operation.execution_duration" ); } public void Dispose() { ActivitySource.Dispose(); Meter.Dispose(); } } }
这里的 ActivitySource、Meter、Counter<T> 和 Histogram<T> 类型都来自 System.Diagnostics.Metrics 命名空间。这个类在应用启动时创建相关对象,在应用结束时自动释放。
您只需要在 Startup.cs 中注册该类为单例服务即可:
builder.AddEntityFrameworkCoreInstrumentation(); }); --> var telemetry = new Telemetry(); --> services.AddSingleton(telemetry); --> services --> .AddOpenTelemetry() --> .WithTracing(tracing => tracing.AddSource("XafAspireDemo.Blazor.Server")) --> .WithMetrics(metrics => --> { --> metrics.AddMeter(telemetry.MeterName); --> }); services.AddSingleton( typeof(Microsoft.AspNetCore.SignalR.HubConnectionHandler<>),
接下来我们要将遥测功能应用到前面创建的业务操作中,只需在 ImportantBusinessAction_Execute 方法中添加几行代码即可:
private async void ImportantBusinessAction_Execute( object sender, SimpleActionExecuteEventArgs e ) { --> var telemetry = serviceProvider.GetRequiredService<Telemetry>(); var logger = serviceProvider.GetRequiredService< ILogger<ImportantBusinessOperationsController> >(); importantBusinessAction.Enabled["ImportantBusinessActionRunning"] = false; --> using var activity = telemetry.ActivitySource.StartActivity("ImportantBusinessAction"); logger.LogInformation("ImportantBusinessAction started."); try { ... } catch (Exception ex) { logger.LogError(ex, "ImportantBusinessAction failed."); --> activity?.SetStatus(ActivityStatusCode.Error); --> activity?.AddException(ex); throw; } finally { --> activity?.Stop(); importantBusinessAction.Enabled["ImportantBusinessActionRunning"] = true; --> telemetry.ImportantBusinessOperationCounter.Add(1); --> telemetry.ImportantBusinessOperationDuration.Record( --> activity.Duration.TotalMilliseconds --> ); } }
在方法开始处,我们通过依赖注入获取遥测服务,然后开启一个活动(Activity)。如果执行过程中发生错误,会记录异常信息,并将活动状态设为错误,最后记录计数器和直方图的相关指标值。
这样,当您执行该业务操作时,Aspire 仪表盘便能显示相应的指标与活动信息。值得注意的是,OpenTelemetry 会自动关联活动与指标(如执行时长记录),不需要你手动建立连接。


未完待续,我们下期再见!更多产品资讯及授权,欢迎来电咨询:023-68661681
关于慧都科技
慧都是⼀家⾏业数字化解决⽅案公司,专注于软件、⽯油与⼯业领域,以深⼊的业务理解和⾏业经验,帮助企业实现智能化转型与持续竞争优势。
慧都科技是DevExpress的中国区的合作伙伴,DevExpress作为用户界面领域的优秀产品,帮助企业高效构建权限管理、数据可视化(如网格/图表/仪表盘)、跨平台系统(WinForms/ASP.NET/.NET MAUI)及行业定制解决方案,加速开发并强化交互体验。
欢迎任何形式的转载,但请务必注明出处,尊重他人劳动成果
转载请注明:文章转载自:DevExpress控件中文网 [https://www.devexpresscn.com/]
本文地址:https://www.devexpresscn.com/post/5207.html
相关产品: .NET开发框架eXpressApp Framework(XAF), DevExpress Universal Subscription,