如何使用 Autofac 和 DynamicProxy 来确定目标代理的命名空间 class

How to use Autofac with DynamicProxy to determine the namespace of the target proxy class

我正在使用 IInterceptor 拦截某些 classes 中的方法调用。 拦截器设置为 so:public class InstrumentationInterceptor: IInterceptor { public InstrumentationInterceptor() { Measure.Configure(新的 StatsdConfig()); }

    public void Intercept(IInvocation invocation)
    {
        var instrumentationId = new StringBuilder();
        instrumentationId.Append(typeof(Program).Namespace.Replace(".", string.Empty).ToLower());
        instrumentationId.Append(".");
        instrumentationId.Append("response");
        instrumentationId.Append(".");
        // The following will split the camel case simple name of the proxied class,
        //  where 'Consumer' suffix has been removed, and also convert to lower case
        instrumentationId.Append(Regex.Replace(invocation.TargetType.Name.Replace("Consumer", string.Empty), "(\B[A-Z])", "_").ToLowerInvariant());
        instrumentationId.Append(".");
        instrumentationId.Append("duration");
        using (
            Measure.StartTimer(instrumentationId.ToString()))
        {
            invocation.Proceed();
            Measure.Counter(instrumentationId.ToString(), 1);
        }
    }
}

然后在 Autofac 模块中像这样连接:

var builder = new ContainerBuilder();
builder.RegisterType<DataConsumer>().
            As<IConsumer<DataRequest>>().
            EnableInterfaceInterceptors().
            InterceptedBy(typeof (InstrumentationInterceptor));
builder.Build();

我正在使用它来测量花费的时间并计算调用此方法的实例。我希望能够将其推送到我拥有的外部库,但我将失去获取调用程序的命名空间的能力。有什么方法可以使用 IInvocation 到达目标命名空间吗?

对此的任何想法都会有用。

谢谢。

好的,比我想象的要容易。

invocation.InvocationTarget.ToString() 

给你目标的命名空间class;顾名思义:)

谢谢

您可以在调用中使用GetConcreteMethodInvocationTarge方法来获取您实际拦截的MethodInfo实例。

GetConcreteMethodInvocationTarget :

  • Summary: Returns the concrete instantiation of IInvocation.MethodInvocationTarget, with any generic parameters bound to real types. For interface proxies, this will point to the System.Reflection.MethodInfo on the target class.
  • Returns: The concrete instantiation of IInvocation.MethodInvocationTarget, or IInvocation.MethodInvocationTarget if not a generic method.

使用 MethodInfo 您可以获得类型,然后是命名空间。

String namespace = invocation.GetConcreteMethodInvocationTarget().DeclaringType.Namespace;

另一种解决方案是使用InvocationTarget 属性 然后调用.GetType() 方法来检索拦截的类型,但在某些复杂的情况下它可能不起作用。

String namespace = invocation.InvocationTarget.GetType().Namespace;