Внедрение GeneratedCodeAttribute с Mono.Cecil - PullRequest
2 голосов
/ 17 января 2011

Я манипулирую своими сборками .net 2.0 с помощью Mono.Cecil.После манипуляции я хочу пометить сборку как обработанную путем введения атрибута модуля

var stringType = _module.Import(typeof(string));
var baseCtor = _module.Import(typeof(GeneratedCodeAttribute).GetConstructor(new[] { typeof(string), typeof(string) }));
var result = new CustomAttribute(baseCtor);
result.ConstructorArguments.Add(new CustomAttributeArgument(stringType, "ProcessedBySomething"));
result.ConstructorArguments.Add(new CustomAttributeArgument(stringType, "1.0"));

. После сохранения сборки она становится зависимой от .net 4.0, поскольку манипулирование приложением написано на .net 4.0.GeneratedCodeAttribute существует в .net 2.0, так что я делаю не так?

1 Ответ

6 голосов
/ 17 января 2011

Ты угадаешь правильно. Поскольку манипулирующее приложение работает в .net 4.0, а typeof является функцией времени выполнения, оно возвращает тип для текущей версии времени выполнения.

Чтобы это исправить, проще всего создать ссылки для версии mscorlib, на которую ссылается модифицируемый вами модуль, используя Cecil, чтобы открыть сборку. Ваш код станет:

var stringType = _module.TypeSystem.String;
var corlib = (AssemblyNameReference) _module.TypeSystem.Corlib;
var system = _module.AssemblyResolver.Resolve (new AssemblyNameReference ("System", corlib.Version) {
    PublicKeyToken = corlib.PublicKeyToken,
});
var generatedCodeAttribute = system.MainModule.GetType ("System.CodeDom.Compiler.GeneratedCodeAttribute");
var generatedCodeCtor = generatedCodeAttribute.Methods.First (m => m.IsConstructor && m.Parameters.Count == 2);

var result = new CustomAttribute (_module.Import (generatedCodeCtor));
result.ConstructorArguments.Add(new CustomAttributeArgument(stringType, "ProcessedBySomething"));
result.ConstructorArguments.Add(new CustomAttributeArgument(stringType, "1.0"));
...