如何使用 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;
我正在使用 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
, orIInvocation.MethodInvocationTarget
if not a generic method.
使用 MethodInfo
您可以获得类型,然后是命名空间。
String namespace = invocation.GetConcreteMethodInvocationTarget().DeclaringType.Namespace;
另一种解决方案是使用InvocationTarget
属性 然后调用.GetType()
方法来检索拦截的类型,但在某些复杂的情况下它可能不起作用。
String namespace = invocation.InvocationTarget.GetType().Namespace;