使用方法Mono.Cecil能做到进口 [英] Method import using Mono.Cecil
问题描述
帮我进口的方法讨好。
我想编织组装和从其他装配定义的基类注射方法调用引用(实际上它是在那里编织码定义的程序集)。
私人无效InsertCallSetReference()
{
//获取加载指令来代替
VAR ilProcessor = Property.SetMethod.Body.GetILProcessor();
VAR argumentLoadInstructions = ilProcessor.Body.Instructions.ToList();
MethodReference methodReference = ImportMethod(SetReference);
的foreach(在argumentLoadInstructions VAR指令)
{
如果(instruction.OpCode == OpCodes.Stfld)
{
ilProcessor.InsertAfter(指令, ilProcessor.Create(OpCodes.Call,methodReference));
ilProcessor.InsertAfter(指令,ilProcessor.Create(OpCodes.Ldarg_1));
ilProcessor.InsertAfter(指令,ilProcessor.Create(OpCodes.Ldstr,DBFieldName));
ilProcessor.InsertAfter(指令,ilProcessor.Create(OpCodes.Ldarg_0));
ilProcessor.Remove(指令);
中断;
}
}
}
方法导入代码工作得很好并返回方法参照
私人MethodReference ImportMethod(字符串名称)
{
变种类型= MongoConnectModule.Import (typeof运算(BaseDataObject));
返回MongoConnectModule.Import(type.Resolve()方法。首先(M = GT; m.Name ==名));
}
但经过AssemblyDefinition写调用它引发我一个错误:
C:\dev\MongoConnect\WeavingTaskTest\Weaving\CodeWeaving.targets(32,5):
错误MSB4018:系统.ArgumentException:成员'System.Void
MongoConnect.BaseDataObject ::的SetProperty(System.String,System.Object的)'
的另一模块声明并需要导入
块引用>
_assemblyDefinition.Write(_assemblyPath,新WriterParameters(){WriteSymbols = TRUE,SymbolWriterProvider = debugWriterProvider});
任何想法,我怎么能这样做呢?
解决方案我已经找到了解决办法。
的原因是真的很有趣。
Module.Import()
方法必须从当前模块调用我们要修改,而不是模块的方法在哪里被定义为。它不是由原来的文档清晰。
有关例如,我们要添加在
Referenced.dll
组装定义为我们的Main.dll
组装一些方法。然后,我们必须找到我们的Main.dll
组装主模块,然后调用MainModule.Import(methodFromReferencedAssembly);
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:
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
_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. It is not clear from original docs.For example, we want to add some method defined in the
Referenced.dll
assembly to ourMain.dll
assembly. Then we have to find main module of ourMain.dll
assembly and then callMainModule.Import(methodFromReferencedAssembly);
这篇关于使用方法Mono.Cecil能做到进口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!