如何为ILogger挂钩拦截器

时间:2017-02-27 15:16:06

标签: castle-windsor

我正在使用LoggingFacility,并且需要为设施创建的ILogger实例添加拦截器。

到目前为止,我尝试修改ILogger的组件模型,但这并没有起作用,因为使用标准的解析机制(它们是由使用一些包装器的工厂创建)实际上没有解析记录器。

我打算覆盖日志记录子解析器,但kernel.Resolver不允许替换(或包装)设施添加的解析器。

我正在考虑挂钩到Kernel.DependencyResolving,但看起来我无法替换那里的依赖。

最适合放置这种钩子的地方是什么,所以我可以为ILogger添加拦截器。

编辑:经过大量的探索,我带来了一些" hackish"解决方案,不幸的是取决于小的反射使用。

真正的问题似乎是,记录器的构造方式不符合(对我而言)城堡的做事精神。即解析器不使用已注册的记录器工厂,因此无法将拦截器添加到工厂本身。

2 个答案:

答案 0 :(得分:1)

有关CodeProject的一篇很棒的文章:来自Aspect Oriented Programming (AOP) in C# using Castle DynamicProxyLinjith Kunnon。它向您展示了如何定义拦截器

public class LoggingInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        var methodName = invocation.Method.Name;
        try
        {
            Console.WriteLine(string.Format("Entered Method:{0}, Arguments: {1}", methodName, string.Join(",", invocation.Arguments)));
            invocation.Proceed();
            Console.WriteLine(string.Format("Sucessfully executed method:{0}", methodName));
        }
        catch (Exception e)
        {
            Console.WriteLine(string.Format("Method:{0}, Exception:{1}", methodName, e.Message));
            throw;
        }
        finally
        {
            Console.WriteLine(string.Format("Exiting Method:{0}", methodName));
        }
    }
}

以及如何使用Castle.Windsor注册它

kernel.Register(
    Component.For<LoggingInterceptor>()
        .ImplementedBy<LoggingInterceptor>()
    );

kernel.Register(
    Component.For<IRocket>()
        .ImplementedBy<Rocket>()
        .Interceptors(InterceptorReference.ForType<LoggingInterceptor>()).Anywhere
    );

请注意,链接文章中有更多有价值的内容,此处提供的整个代码来自文章而非我。所有的荣誉都归于Linjith Kunnon。

答案 1 :(得分:0)

您需要创建自己的记录器工厂(从与您的日志框架匹配的默认实现派生),然后您可以设置工具以使用此工厂:

container.AddFacility<LoggingFacility>(f => f.UseLog4Net().LogUsing<MyFactory>());

请参阅完整示例here