【发布时间】:2016-01-01 20:38:41
【问题描述】:
我想在每次调用我的 Web 服务时记录到文件,记录被调用方法的名称以及调用数据。
要写入此文件,我使用Nlog,但我不想在我的每个服务操作中进行日志记录调用。我宁愿以某种方式自动执行此日志记录调用作为横切关注点。
有可能吗?
【问题讨论】:
我想在每次调用我的 Web 服务时记录到文件,记录被调用方法的名称以及调用数据。
要写入此文件,我使用Nlog,但我不想在我的每个服务操作中进行日志记录调用。我宁愿以某种方式自动执行此日志记录调用作为横切关注点。
有可能吗?
【问题讨论】:
您可以使用支持拦截器的 DI 容器来记录任何带有输入值的 WCF 方法调用。这是Ninject 和旧的怪异 ASMX 服务的示例(对于 WCF,想法是相同的):
让我们考虑以下客户端类:
public partial class LegacyClient : System.ServiceModel.ClientBase<Legacy>, Legacy
因为这个类是部分的,我们可以很容易地向类添加接口ILegacyClient,其中包含我们想要调用的方法。 ReSharper 在一秒钟内提取界面。所以将部分类声明放在单独的文件中:
public partial class LegacyClient : ILegacyClient {}
在 DI 配置中,添加拦截器:
Kernel.Bind(typeof(ILegacyClient))
.To<LegacyClient>()
.InRequestScope() //carefully choose a scope
.Intercept()
.With<LogRequestInterceptor>();
LogRequestInterceptor 是最有趣的部分:
using Ninject;
using Ninject.Extensions.Interception;
public class LogRequestInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
MethodInfo method = invocation.Request.Method;
var parameters = method.GetParameters();
var builder = new StringBuilder();
for (int index = 0; index < parameters.Length; index++)
{
object argument = invocation.Request.Arguments[index];
ParameterInfo parameterInfo = parameters[index];
if (!parameterInfo.IsOut)
{
//use any serialization you like
string text = $"{parameterInfo.Name} = {argument.ToJson()}, ";
builder.Append(text);
}
}
string joinedParameters = builder.ToString();
YourLogging(method.Name, joinedParameters);
//LegacyClient method call, don't forget this line
invocation.Proceed();
}
}
最后一部分让事情顺利进行。通过 DI 创建代理对象并使用它:
ILegacyClient client = Kernel.GetService<ILegacyClient>();
client.AnyMethodCall(...);
直接创建只是一个例子,当然你可以使用构造函数或属性注入来代替,如果需要的话,可以用工厂替换客户端接口。
希望对你有帮助!
【讨论】:
您可以尝试使用 Windsor Castle、PostSharp 或其他提供 AOP 的第三方库来使用面向方面编程 (AOP)。此外,您可以使用这些库中的拦截器。
WCF Extension 可能是进行此类日志记录的另一个地方。
使用 WCF 跟踪。您可以通过配置启用 WCF 跟踪来查看服务调用、消息级别详细信息等。
【讨论】:
Agalo 的答案是正确的,但过于笼统,所以我只想添加一个如何实现 #2 的链接。我想这正是作者想要的问题。
简而言之,您可以实现自己的参数检查器 (IParameterInspector) 并使用服务行为 (IServiceBehavior) 将其注入。 Here you can find complete example how to do that 用于记录。
【讨论】: