到目前为止,我一直在搜索这个问题但没有运气。在.NET中是否有与Java ClassFileTransformer
相当的东西?基本上,我想创建一个类CustomClassFileTransformer
(在Java中实现接口ClassFileTransformer
),只要加载一个类就会调用它,并允许调整它并用调整后的版本替换它。
我知道有些框架可以做类似的事情,但我正在寻找更直接的东西,比如实现我自己的ClassFileTransformer
。有可能吗?
编辑#1 。关于我为什么需要这个的更多细节:
基本上,我有一个C#应用程序,我需要监视它想要运行的指令,以便检测对字段(操作Ldfld
和Stfld
)的读或写操作,并在之前插入一些指令读/写发生。
我知道如何执行此操作(除了需要调用以替换类的部分):对于我想要监视其代码的每个方法,我必须:
MethodBody
MethodBase.GetMethodBody()
MethodBody.GetILAsByteArray()
将其转换为字节数组。它返回的byte[]
包含字节码。MethodBuilder.CreateMethodBody(byte[] il, int count)
创建一个新方法并使用新字节码创建其正文,其中il
是包含字节码的数组。
我将所有这些调整过的方法放在一个新类中,并使用新类替换最初要加载的类。替换类的替代方法将以某种方式在调用方法时得到通知。然后我用调用我自己的调整方法替换对该方法的调用,我只会在第一次调用时进行调整,然后我将它放在字典中以备将来使用,以减少开销(对于将来的调用)我只是查找方法并调用它;我不需要再次分析字节码)。我正在研究如何做到这一点,LinFu看起来非常有趣,但是如果有类似ClassFileTransformer
之类的内容会更简单:我只是重写类,替换它,然后让代码在没有监控任何事情的情况下运行。
另外注意:课程可以密封。我希望能够替换任何类,我不能对其属性施加限制。
编辑#2 。为什么我需要在运行时执行此操作。
我需要监控正在进行的所有,以便我可以检测每次访问数据。这也适用于库类的代码。但是,我事先无法知道将要使用哪些类,即使我知道每个可能的类可能被加载,所以调整所有类而不是等待它将是一个巨大的性能影响。看看他们是否真的被调用了。
可能(但是很难)解决方案。如果有人感兴趣(我看到这个问题已经存在,我猜有人会这样),this就是我现在正在看的。基本上我必须实现分析API,我将注册我感兴趣的事件,就我的情况而言,每当JIT编译开始时。博文摘录:
好消息:当JIT编译开始时我收到通知,我可以在那里替换字节码,而不必担心替换类等等。不太好的消息:你不能从中调用托管代码API的回调方法,这有意义,但意味着我自己解析IL代码等,而不是能够使用Cecil,这将是一件轻而易举的事。
我认为没有使用AOP框架(例如PostSharp)有更简单的方法可以做到这一点。如果有人有任何其他想法,请告诉我。我还没有回答这个问题。
答案 0 :(得分:1)
我不知道.NET中的直接等价物。
但是,有一些方法可以实现类似的功能,例如使用Reflection.Emit
按需生成程序集和类型,使用RealProxy
为接口和MarshalByRefObject
对象创建代理对象。但是,要建议使用什么,了解更多有关实际用例的信息非常重要。
答案 1 :(得分:1)
经过相当多的研究后,我正在回答我自己的问题:没有相当于.NET中的ClassFileTransformer
,或任何直接替换类的方法。
通过托管CLR可以控制类加载过程,但这是非常低级的,你必须小心它,并且在每种情况下都不可能。例如,如果您在服务器上运行,则可能无权托管CLR。此外,如果您正在运行ASP.NET应用程序,则无法执行此操作,因为ASP.NET已提供CLR主机。
很可惜.NET不支持这个;他们这么容易做到这一点,他们只需要在加载一个类之前通知你,并让你有机会修改类,然后再将它传递给CLR加载它。