简体   繁体   English

使用 Mono.Cecil 导入方法

[英]Method import using Mono.Cecil

Help me please with method import.请帮我导入方法。 I want to weave assembly and inject method call reference from base class defined in the other assembly (in fact it's the assembly where weaving code is defined).我想编织程序集并从另一个程序集中定义的基类注入方法调用引用(实际上它是定义编织代码的程序集)。

private void InsertCallSetReference()
{
    //Get the load instruction to replace
    var ilProcessor = Property.SetMethod.Body.GetILProcessor();
    var argumentLoadInstructions = ilProcessor.Body.Instructions.ToList();

    MethodReference methodReference = ImportMethod("SetReference");

    foreach (var instruction in argumentLoadInstructions)
    {
        if (instruction.OpCode == OpCodes.Stfld)
        {
            ilProcessor.InsertAfter(instruction, ilProcessor.Create(OpCodes.Call, methodReference));
            ilProcessor.InsertAfter(instruction, ilProcessor.Create(OpCodes.Ldarg_1));
            ilProcessor.InsertAfter(instruction, ilProcessor.Create(OpCodes.Ldstr, DBFieldName));
            ilProcessor.InsertAfter(instruction, ilProcessor.Create(OpCodes.Ldarg_0));
            ilProcessor.Remove(instruction);
            break;
        }
    }
}

Method import code works just fine and returns method reference方法导入代码工作正常并返回方法引用

private MethodReference ImportMethod(string name)
{
     var type = MongoConnectModule.Import(typeof(BaseDataObject));
     return MongoConnectModule.Import(type.Resolve().Methods.First(m => m.Name == name));
}

But after AssemblyDefinition Write call it throws me an error:但是在 AssemblyDefinition Write 调用之后,它抛出了一个错误:

C:\\dev\\MongoConnect\\WeavingTaskTest\\Weaving\\CodeWeaving.targets(32,5): error MSB4018: System.ArgumentException: Member 'System.Void MongoConnect.BaseDataObject::SetProperty(System.String,System.Object)' is declared in another module and needs to be imported C:\\dev\\MongoConnect\\WeavingTaskTest\\Weaving\\CodeWeaving.targets(32,5): error MSB4018: System.ArgumentException: Member 'System.Void MongoConnect.BaseDataObject::SetProperty(System.String,System.Object)'被声明在另一个模块中,需要导入

_assemblyDefinition.Write(_assemblyPath, new WriterParameters() { WriteSymbols = true, SymbolWriterProvider = debugWriterProvider });

Any idea how I could do that?知道我怎么做吗?

I've found the solution.我找到了解决方案。 The reason was really funny.原因真的很搞笑。

Module.Import() method must be called from current module we want to modify, not the module where method is defined. Module.Import()方法必须从我们要修改的当前模块中调用,而不是从定义方法的模块中调用。 It is not clear from original docs .从原始文档中不清楚。

For example, we want to add some method defined in the Referenced.dll assembly to our Main.dll assembly.例如,我们想将在Referenced.dll程序Main.dll定义的一些方法添加到我们的Main.dll程序Main.dll Then we have to find main module of our Main.dll assembly and then call MainModule.Import(methodFromReferencedAssembly);然后我们必须找到我们的Main.dll程序集的主模块,然后调用MainModule.Import(methodFromReferencedAssembly);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM