Как использовать Autofac с DynamicProxy для определения пространства имен целевого прокси-класса
Я использую IInterceptor для перехвата вызовов методов в определенных классах. Перехватчик устанавливается следующим образом: открытый класс InstrumentationInterceptor: IInterceptor { public InstrumentationInterceptor() { Measure.Configure(new 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])", "_$1").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, чтобы добраться до целевого пространства имен?
Любые мысли по этому поводу будут полезны.
Благодарю.
2 ответа
Вы можете использовать GetConcreteMethodInvocationTarge
метод в вызове, чтобы получить MethodInfo
экземпляр, который вы на самом деле перехватывают.
GetConcreteMethodInvocationTarget
:
- Резюме: возвращает конкретный экземпляр
IInvocation.MethodInvocationTarget
с любыми общими параметрами, связанными с реальными типами. Для интерфейсных прокси это будет указывать на System.Reflection.MethodInfo в целевом классе.- Возвращает: конкретная реализация
IInvocation.MethodInvocationTarget
, или жеIInvocation.MethodInvocationTarget
если не универсальный метод.
С MethodInfo
Вы можете получить тип, а затем пространство имен.
String namespace = invocation.GetConcreteMethodInvocationTarget().DeclaringType.Namespace;
Другое решение было бы использовать InvocationTarget
собственность, а затем вызывая .GetType()
метод для получения перехваченного типа, но в некоторых сложных случаях он может не работать.
String namespace = invocation.InvocationTarget.GetType().Namespace;
ОК, это было проще, чем я думал.
invocation.InvocationTarget.ToString()
дает вам пространство имен целевого класса; как следует из названия:)
Спасибо