工作中发现一个公共组件因为某个类不带有[Serializable]特性,导致保存到memcache时出错。刚好负责的同事请假不在,尝试了iLSpy反编译方法后,最后决定使用Mono.Cecil直接修改现成的程序集dll解决。

示例代码如下:

class Program
    {
        static void Main(string[] args)
        {
            var asmFile = "TestDll.dll";  // 程序集名
            Console.WriteLine("add serializable attribute for '{0}'.", asmFile);

            var asmDef = AssemblyDefinition.ReadAssembly(asmFile, new ReaderParameters
            {
                ReadSymbols = true        // 标识是否读取修改pdb文件
            });

            // 取类名中包含"Entity"字符串的类
            var types = asmDef.Modules
                .SelectMany(m => m.Types)
                .Where(t => t.Name.Contains("Entity"));

            // 设置类为可序列化
            foreach (var type in types)
            {
                type.IsSerializable = true;
            }

            // 重新保存dll
            var newAsmFileName = "TestDll_new.dll";
            asmDef.Write(newAsmFileName, new WriterParameters
            {
                WriteSymbols = true
            });

            Console.WriteLine("new dll has save as {0}.", newAsmFileName);
        }
    }

Mono.Cecil除了可以更改特性,还能把sealed类更改为public类,功能非常强大。

下载demo

参考资料: 使用Mono.Cecil辅助ASP.NET MVC使用dynamic类型Model