Is there an equivalent Java ClassFileTransformer in .NET? (way to replace class)

I searched for this for quite some time, until I got lucky. Is there an equivalent Java ClassFileTransformer in .NET? Basically, I want to create a CustomClassFileTransformer class (which in Java will implement the ClassFileTransformer interface), which will be called whenever the class is loaded, and it is allowed to configure it and replace it with the modified version.

I know that there are frameworks that do similar things, but I was looking for something simpler, for example, to implement my own ClassFileTransformer . Is it possible?


EDIT No. 1 . More on why I need this:

Basically, I have a C # application, and I need to control the instructions that it wants to run in order to detect the read or write operations in the fields ( Ldfld and Stfld ) and insert some instructions before starting to read / write.

I know how to do this (except for the part where I need to call to replace the class): for each method whose code I want to control, I have to:

An alternative to replacing classes will somehow get notified when the method is called. Then I would replace the call with this method by calling my own modified method, which I would only activate for the first time, and then I put it in a dictionary for future use in order to reduce overhead (for future calls, I will just look at the method and call it I won’t need to parse the bytecode again). I'm learning ways to do this now, and LinFu looks pretty interesting, but if it were something like ClassFileTransformer , it would be much simpler: I just rewrite the class, replace it and skip the code without monitoring.

Additional note: classes can be sealed. I want to be able to replace any class, I can not impose restrictions on their attributes.


CHANGE No. 2 . Why do I need this at runtime.

I need to track everything so that I can detect every data access. This also applies to the class class of the library. However, I cannot know in advance which classes will be used, and even if I knew all the possible classes that could be loaded, it would be a huge success to set them all up, instead of waiting for them to be really caused or not.


POSSIBLE (BUT ONLY HARDORIOUS) SOLUTION . In case anyone is interested (and I see that a question has been found, so I think someone is), this is what I'm looking for right now. Basically, I will have to implement a profiling API, and I will register for events that interest me, in my case, when the JIT compilation begins. Blog Extract:

  • In your ICorProfilerCallback2 :: ModuleLoadFinished callback, you call ICorProfilerInfo2 :: GetModuleMetadata to get a pointer to the metadata interface in this module.
  • QI for the metadata interface you want. Find the MSDN for "IMetaDataImport" and browse the contents of the table of contents to find topics on the metadata interfaces.
  • Once you are in the metadata zone, you have access to all types of modules, including their fields and function prototypes. You may need to analyze metadata signatures, and this signature parser may be useful to you.
  • In your ICorProfilerCallback2 :: JITCompilationStarted callback, you can use ICorProfilerInfo2 :: GetILFunctionBody to check the source IL and ICorProfilerInfo2 :: GetILFunctionBodyAllocator and then ICorProfilerInfo2 :: SetILFunctionBody to replace this IL with your own.

Great news: I get a notification when the JIT compilation starts, and I can replace the bytecode right there without worrying about replacing the class, etc. Not very good news: you cannot call managed code from the API, which makes sense, but means that I myself deal with IL code, etc., and not with Cecil, which would be a breeze.

I don't think there is an easier way to do this without using AOP frameworks (such as PostSharp ). If anyone has any other idea, please let me know. I will not mark the question as I answered.

+4
source share
2 answers

After some research, I answer my question: in .NET there is no equivalent to ClassFileTransformer , or an easy way to replace classes.

It is possible to gain control over the process of loading a class by placing the CLR, but this is pretty low-level, you have to be careful with it, and this is not possible in every scenario. For example, if you are running a server, you may not have permission to host the CLR. Also, if you are using an ASP.NET application, you cannot do this because ASP.NET already provides the CLR host.

It is a pity that .NET does not support this; it would be so easy for them to do this, they just have to notify you before loading the class and give you the opportunity to modify the class before passing it to the CLR to load it.

+1
source

I do not know about the direct equivalent in .NET for this.

However, there are some ways to implement similar functions, such as using Reflection.Emit to generate assemblies and types on demand, uing RealProxy to create proxy objects for interfaces and MarshalByRefObject objects. However, in order to advise what to use, it would be important to learn more about the actual use case.

+1
source

Source: https://habr.com/ru/post/1306608/


All Articles