.NET MAUI Android下获取CSharpCompilation的MetadataReference遇阻求替代方案
问题:Release模式下获取程序集字节流用于运行时编译
我需要在运行时编译类,必须引用System.Linq.dll、System.Collections.dll这类程序集,但Release模式构建时,Assembly.Location只返回程序集名称而非文件路径,导致无法用MetadataReference.CreateFromFile创建引用。有没有替代方案?
已尝试但无效的方案
- 方案1:反射调用
GetRawBytes
var methodInfo = assembly.GetType().GetMethod("GetRawBytes", BindingFlags.Instance | BindingFlags.NonPublic); byte[] assemblyBytes = (byte[])methodInfo.Invoke(assembly, null); var reference = MetadataReference.CreateFromImage(assemblyBytes);
问题:
GetRawBytes在新版.NET中已被移除,无法调用。
- 方案2:通过
Hash类反射获取原始数据
var hash = new Hash(assembly); var dllAsArray = (byte[])hash.GetType().GetMethod("GetRawData", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(hash, new object[0]); var reference = MetadataReference.CreateFromImage(dllAsArray);
问题:
Hash是Windows专属API,跨平台场景下无法使用。
- 方案3:用
BinaryFormatter序列化程序集
var formatter = new BinaryFormatter(); var ms = new MemoryStream(); formatter.Serialize(ms, assembly); var reference = MetadataReference.CreateFromImage(ms.GetBuffer());
问题:
BinaryFormatter已被官方弃用,编译阶段直接报错。
另外,尝试过FastReport仓库的Android适配方案,但调用TryGetRawMetadata()扩展方法时触发NotImplementedException。
可行的替代方案
方法1:使用Module.GetRawBytes(推荐,跨平台兼容新版.NET)
对于已加载的程序集,可通过其清单模块直接获取原始字节流,这是官方公开的API,无需反射,兼容性好:
byte[] assemblyBytes = assembly.ManifestModule.GetRawBytes(); var reference = MetadataReference.CreateFromImage(assemblyBytes);
方法2:从应用目录读取程序集文件
如果能确定程序集文件在应用运行目录下(比如未被单文件打包),可以直接读取文件字节:
string assemblyPath = Path.Combine(AppContext.BaseDirectory, "System.Linq.dll"); if (File.Exists(assemblyPath)) { byte[] assemblyBytes = File.ReadAllBytes(assemblyPath); var reference = MetadataReference.CreateFromImage(assemblyBytes); }
注意:如果项目启用了单文件发布,需要在发布设置中保留必要的程序集文件,或者调整打包策略。
方法3:嵌入程序集为资源并读取
将需要引用的程序集添加到项目,设置“生成操作”为“嵌入的资源”,然后通过资源流读取:
// 资源名称格式:项目命名空间 + 程序集文件名 using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("YourAppNamespace.System.Linq.dll"); if (stream != null) { using var ms = new MemoryStream(); stream.CopyTo(ms); var reference = MetadataReference.CreateFromImage(ms.ToArray()); }
内容的提问来源于stack exchange,提问作者Vitor P. Carneiro
相关产品推荐
相关产品推荐

