c# - 使用 serilog 解构开放泛型
问题描述
是否可以基于开放的泛型来解构 serilog 事件数据?例如,我正在尝试这样做:
.Destructure.ByTransforming<CosmosResponse<T>>(
transform =>
new
{
transform.StatusCode,
transform.RequestCharge,
transform.ActivityId,
})
这样我就可以获取任何Cosmos 响应对象并仅提取应记录的特定信息位。但是,它似乎不起作用 - 我的回调从未被调用。
我也试过打电话ByTransformingWhere
并总是回来true
。我很惊讶地看到每个日志调用都会调用它,而不仅仅是那些处理CosmosResponse<T>
. 尽管它确实为 Cosmos 响应对象调用了我的谓词,但它仍然没有调用回调来转换对象。
更新
这是迄今为止我能做到的最好的:
.Destructure.ByTransformingWhere<dynamic>(
t => t.IsGenericType && t.GenericTypeArguments.Length == 1 && t.IsSubclassOf(typeof(CosmosResponse<>).MakeGenericType(t.GenericTypeArguments[0])),
r =>
new
{
r.StatusCode,
r.RequestCharge,
r.ActivityId
})
这有点令人担忧,因为每次日志调用都会调用谓词,但我找不到任何其他解决方法。
更新 2
在这种情况下,更好的方法是完全避免解构,而是向 Cosmos 客户端添加自定义处理程序。这有助于拦截所有请求,并且我关心的各种信息(状态代码、请求费用等)都存在于响应标头中。
当然,这是特定于 Cosmos DB 的客户端库的,对原始问题只字未提。如果您确实需要基于开放的泛型类型进行解构,那么上面仍然是最知名的选项 afaik。
解决方案
我期待这样的事情可以完成这项工作:
.Destructure.ByTransformingWhere<dynamic>(
t => t.GetGenericTypeDefinition() == typeof(CosmosResponse<>),
o => new { o.Whatever })
正如文档所说,虽然:
解构对象时,如果谓词返回 true,则使用提供的函数转换指定类型的实例。小心避免谓词中的任何密集工作,因为它会显着减慢管道。
因此,了解如何优化或避免这些反射调用可能是一个好主意。
更新
要进行适当的智能感知/类型检查,您应该能够:
.Destructure.ByTransformingWhere<CosmosResponse<object>>(
t => t.IsGenericType && t.GenericTypeArguments.Length == 1 && t.IsSubclassOf(typeof(CosmosResponse<>).MakeGenericType(t.GenericTypeArguments[0])),
r =>
new
{
r.StatusCode,
r.RequestCharge,
r.ActivityId
})
(即提供CosmosResponse<object>
作为类型参数而不是dynamic
,以便CosmosResponse
点亮存在的属性)
推荐阅读
- node.js - 命令“ng serve”在命令提示符下工作,但对同一项目的代码不起作用
- wireshark - 从 pcap 卸载协议
- amazon-web-services - VS Code 和 AWS SAM 本地调用问题
- php - 联系表格不适用于 PHP 7.4 版
- python - 如何将元组键更改为多级字典
- java - 当结果集非常小(0 或 1 次命中)时,ResultSet.next() 有时会花费大量时间
- node.js - MQTT.js 订阅者在断开重新连接后收到重复消息
- python - 如何使用python对连续对的字符串进行标记?
- python - Cartopy:显示轴的刻度线
- javascript - 如何在 sequelize 中返回创建的实例