[英]Method Interception using Reflection in C#
I wrote an abstract class that uses reflection to find fields marked with an Attribute in the constructor, like this: 我编写了一个抽象类,该类使用反射在构造函数中查找带有Attribute标记的字段,如下所示:
[AttributeUsage(AttributeTargets.Field)]
public class TrackedField : Attribute {}
public class ATrackedObject {
public ATrackedObject() {
Type objType = this.GetType();
foreach(FieldInfo f in objType.GetFields()) {
if(f.IsDefined(typeof(TrackedField)), false)) {
//Add field to list to keep tabs on periodically
}
}
}
}
What I would like to do, is: 我想做的是:
I have seen a number of SE threads discussing how to do this, and all of the answers relied on being able to use a third party library - however, none of the questions seemed to match my use case exactly - I can ensure 100% that every object that needs to have methods tracked will inherit from the class that does the tracking. 我已经看到许多SE线程在讨论如何执行此操作,所有答案都取决于能够使用第三方库-但是,所有问题似乎都不完全符合我的用例-我可以确保100%每个需要跟踪方法的对象都将从进行跟踪的类继承。
I don't know for sure this is possible, but I am wondering since IoC/AOP libraries like PostSharp and others exist, surely they must operate by some kind of mechanism - I assume Reflection.Emit plays a part - but what, and how? 我不确定这是否可行,但我想知道自从IoC / AOP库(如PostSharp等)存在以来,它们肯定必须通过某种机制运行-我认为Reflection.Emit发挥了作用-但作用和方式?
Here are some similar questions, which did not have what seemed to me to be answers to my specific scenario, or relied on third party libraries: 这是一些类似的问题,在我看来,这些问题并没有解决我的特定情况,或者没有依赖第三方库:
custom-attribute-to-process-info-before-a-method-is-called 自定义属性对工艺信息前方的一个法,是所谓的
how-do-i-intercept-a-method-call-in-c (this was helpful, but missing the crucial component of how to actually inject code 我如何在C语言中拦截方法调用 (这很有用,但缺少了如何实际注入代码的关键组成部分
Is there a way to make this technique (Attribute -> Base Class Constructor -> Reflection -> Method Interception) viable? 有没有办法使这种技术(属性->基类构造函数->反射->方法拦截)可行?
Could something like this work for what you need? 这样的东西可以满足您的需求吗?
[AttributeUsage(AttributeTargets.Field)]
public class TrackedField : Attribute { }
public class ATrackedObject
{
public ATrackedObject()
{
Type objType = this.GetType();
foreach (FieldInfo f in objType.GetFields())
{
if (f.IsDefined(typeof(TrackedField), false)) {
if (f.FieldType == typeof(Action))
{
var currentValue = f.GetValue(this) as Action;
Action newValue = () =>
{
Console.WriteLine($"Tracking {f.Name}");
currentValue.Invoke();
};
f.SetValue(this, newValue);
}
}
}
}
[TrackedField]
public Action SomeMethod = () => Console.WriteLine("Some Method Called");
}
this is done with a simple Action
property but it could be extended to use Func<>
这是通过简单的
Action
属性完成的,但可以扩展为使用Func<>
edit: forgot to include usage and output. 编辑:忘记包括用法和输出。
usage: 用法:
static void Main(string[] args)
{
var obj = new ATrackedObject();
obj.SomeMethod();
Console.Read();
}
output: 输出:
Tracking SomeMethod
Some Method Called
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.