Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否有与Java';NET中的ClassFileTransformer?(替换类的方法)_C#_.net_Reflection_Classloader_Instrumentation - Fatal编程技术网

C# 是否有与Java';NET中的ClassFileTransformer?(替换类的方法)

C# 是否有与Java';NET中的ClassFileTransformer?(替换类的方法),c#,.net,reflection,classloader,instrumentation,C#,.net,Reflection,Classloader,Instrumentation,我已经找了很长一段时间了,到目前为止运气都不好。在.NET中有与Java等价的吗?基本上,我想创建一个类CustomClassFileTransformer(在Java中实现接口ClassFileTransformer),每当加载一个类时调用该类,并允许对其进行调整并用调整后的版本替换它 我知道有些框架可以做类似的事情,但我一直在寻找更简单的方法,比如实现我自己的ClassFileTransformer。可能吗 编辑#1。有关我为什么需要此功能的更多详细信息: 基本上,我有一个C#应用程序,我

我已经找了很长一段时间了,到目前为止运气都不好。在.NET中有与Java等价的吗?基本上,我想创建一个类
CustomClassFileTransformer
(在Java中实现接口
ClassFileTransformer
),每当加载一个类时调用该类,并允许对其进行调整并用调整后的版本替换它

我知道有些框架可以做类似的事情,但我一直在寻找更简单的方法,比如实现我自己的
ClassFileTransformer
。可能吗


编辑#1。有关我为什么需要此功能的更多详细信息:

基本上,我有一个C#应用程序,我需要监控它想要运行的指令,以便检测对字段的读或写操作(操作和),并在读/写发生之前插入一些指令

我知道如何做到这一点(除了需要调用我来替换类的部分):对于我要监视其代码的每个方法,我必须:

  • 获取该方法的使用情况
  • 使用将其转换为字节数组。它返回的
    字节[]
    包含字节码
  • 按说明分析字节码,可能插入新指令或通过更改数组内容删除/修改现有指令
  • 创建一个新方法并使用新字节码创建其主体,其中
    il
    是带有字节码的数组。 我将所有这些经过调整的方法放在一个新类中,并使用新类替换最初要加载的类
  • 替换类的另一种方法是在调用方法时以某种方式得到通知。然后,我会用对我自己的调整方法的调用来替换对该方法的调用,我只会在第一次调用时对其进行调整,然后我会将其放入字典中供将来使用,以减少开销(对于将来的调用,我只需查找该方法并调用它;我不需要再次分析字节码)。我目前正在研究实现这一点的方法,看起来很有趣,但是如果有类似于
    ClassFileTransformer
    的东西,它会简单得多:我只是重写类,替换它,让代码运行,而不监视任何内容

    另请注意:这些类可能是密封的。我希望能够替换任何类型的类,我不能对它们的属性施加限制


    编辑#2。为什么我需要在运行时这样做

    我需要监控正在进行的一切,以便能够检测到对数据的每次访问。这也适用于库类的代码。但是,我无法提前知道将使用哪些类,即使我知道可能会加载的每个类,调整所有类而不是等待它们是否真正被调用,这将是一个巨大的性能损失


    可能的(但相当核心的)解决方案。如果有人感兴趣(我看到这个问题是伪造的,所以我猜有人感兴趣),这就是我现在要看的。基本上,我必须实现评测API,并且在JIT编译开始时,我将注册我感兴趣的事件。博文摘录:

    • 在ICorProfilerCallback2::ModuleLoadFinished回调中,调用ICorProfilerInfo2::GetModuleMetadata以获取指向该模块上元数据接口的指针
    • QI用于所需的元数据接口。在MSDN中搜索“IMetaDataImport”,并在目录中搜索元数据接口上的主题
    • 一旦进入元数据领域,您就可以访问模块中的所有类型,包括它们的字段和函数原型。您可能需要解析元数据签名,此签名解析器可能对您有用
    • 在ICorProfilerCallback2::JITComilationStarted回调中,可以使用ICorProfilerInfo2::GetILFunctionBody检查原始IL,使用ICorProfilerInfo2::GetILFunctionBodyAllocator,然后使用ICorProfilerInfo2::SetILFunctionBody用自己的IL替换该IL
    好消息:当JIT编译开始时,我会得到通知,我可以在那里替换字节码,而不必担心替换类等。不太好的消息:您不能从API的回调方法调用托管代码,这很有意义,但意味着我正在自己解析IL代码,等等,而不是能够使用塞西尔,那将是轻而易举的事


    我认为没有一种更简单的方法可以不使用AOP框架(例如)来实现这一点。如果有人有任何其他想法,请告诉我。我还没有将问题标记为已回答。

    我不知道在.NET中有直接对应的问题


    但是,有一些方法可以实现类似的功能,例如使用
    Reflection.Emit
    按需生成程序集和类型,使用
    RealProxy
    为接口和
    MarshalByRefObject
    对象创建代理对象。然而,为了建议使用什么,了解更多实际用例是很重要的。

    经过一番研究后,我回答了自己的问题:在.NET中没有与
    ClassFileTransformer
    等价的方法,也没有任何直接的方法来替换类

    通过托管CLR可以获得对类加载过程的控制,但这是非常低级的,您必须小心使用它,并且这不可能在所有场景中都实现。例如,如果您在服务器上运行,则可能没有托管CLR的权限。此外,如果您正在运行ASP.NET应用程序,则无法执行此操作,因为ASP.NET已提供CLR主机

    很遗憾.NET不支持这一点;这对他们来说很容易做到,他们只需在类加载之前通知您,并给您修改类b的机会