我希望 Serilog 解构实现接口的任何类(因此我不必手动将它们全部包含在内。)以下似乎不起作用:
public interface ITest { }
public class Test : ITest { }
public class Program
{
public static int Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.Destructure.ByTransforming<ITest>(i => new { str = "Blah" })
.CreateLogger();
Log.Logger.Debug("We have issues with {@test}", new Test());
}
}
Run Code Online (Sandbox Code Playgroud)
不是{str="Blah"}像我那样使用类解构,我得到{}
了让解构触发所有实现接口的技巧吗?
我找到了一种方法来做到这一点。我在网上找不到任何文档或示例,但我尝试并弄清楚了如何使用解构策略。只需创建一个继承IDestructuringPolicy并实现该TryDestructure方法的类即可。作为 的参数TryDestructure,您将获得要解构的值,一个可用于构造结果的工厂对象,最后一个参数是结果的输出参数。true如果解构成功,该函数应该返回,false否则返回。
我创建了一个解构策略来检查传入对象的类型。如果它与我想要的接口类型匹配,我会像平常一样解构它并返回 true。
这是我创建的一个示例:
public class ResponseDestructuringPolicy : IDestructuringPolicy
{
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result)
{
if (value is IResponse response)
{
result = propertyValueFactory.CreatePropertyValue( new {response.Message} );
return true;
}
result = null;
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您在创建它时将其挂接到记录器,如下所示:
Log.Logger = new LoggerConfiguration()
.Destructure.With(new ResponseDestructuringPolicy())
.CreateLogger();
Run Code Online (Sandbox Code Playgroud)
该Destructure.With()函数可以采用任意数量的策略。看起来 Serilog 检查已注册的类型解构,然后它将运行每个策略并TryDestructure在每个策略上运行函数,直到获得true。如果没有true收到,则按照默认方式继续解构。