如何获取.Net Native编译的UWP应用引用程序集的类型?
获取.Net Native编译的UWP应用引用程序集类型的最佳方法
我来帮你搞定这个问题!因为.Net Native的静态编译特性,常规反射获取引用程序集的方式确实会受限,结合你的IOC约定注册需求,我整理了几个实用的方案:
1. 先解决.Net Native的代码裁剪问题
.Net Native会自动裁剪未被直接引用的类型和程序集,所以如果你的引用程序集里的类型只通过反射访问,必须在项目的rd.xml文件里配置保留规则,不然反射根本拿不到这些类型:
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata"> <Application> <!-- 替换成你的引用程序集名称,Dynamic="Required All"表示保留该程序集所有类型供反射使用 --> <Assembly Name="YourReferencedAssemblyName" Dynamic="Required All" /> <!-- 如果有多个引用程序集,逐个添加 --> <Assembly Name="AnotherReferencedAssembly" Dynamic="Required All" /> </Application> </Directives>
2. 正确获取引用程序集的类型
因为.Net Native编译后,当前程序集的GetReferencedAssemblies()方法可能返回空或者不完整的结果,所以推荐通过引用程序集中已知的标识类型来获取对应的程序集:
代码示例(适配IOC注册)
// 第一步:收集所有需要扫描的程序集 // 这里通过引用程序集中的具体类型来定位程序集(比如你知道某个服务类在引用程序集里) var targetAssemblies = new List<Assembly> { // 引用程序集1:通过其中的MyService1类型获取程序集 Assembly.GetAssembly(typeof(MyService1)), // 引用程序集2:通过其中的MyRepository类型获取程序集 Assembly.GetAssembly(typeof(MyRepository)), // 别忘了加上UWP应用自身的程序集 Assembly.GetAssembly(typeof(MainPage)) }; // 第二步:筛选符合约定的类型(比如公开类) var typesToRegister = targetAssemblies .SelectMany(assembly => assembly.DefinedTypes) .Where(type => type.IsClass && type.IsPublic) .ToList(); // 第三步:注册到你的IOC容器(这里以常见的容器API为例) foreach (var type in typesToRegister) { // 比如Autofac:builder.RegisterType(type).AsImplementedInterfaces(); // 或者Unity:container.RegisterType(type); // 替换成你的容器对应的注册逻辑 }
3. 进阶方案:编译时生成程序集清单
如果你的引用程序集很多,不想逐个写标识类型,可以在编译时生成一个包含所有需要扫描的程序集名称的清单文件:
- 可以用MSBuild任务在编译时收集项目引用的程序集名称,写入一个嵌入式资源文件
- 运行时读取这个嵌入式资源,然后通过
Assembly.Load(new AssemblyName(assemblyName))加载对应的程序集(注意UWP中加载程序集的权限限制,确保程序集在部署包内)
关键注意点
- 一定要确保
rd.xml配置正确,这是所有反射操作能生效的前提,不然.Net Native会把你需要的类型直接裁剪掉 - 避免使用
Assembly.LoadFrom这类方法,UWP中对文件系统访问有严格限制,尽量通过已知类型或嵌入式清单来定位程序集
内容的提问来源于stack exchange,提问作者resp78
相关产品推荐
相关产品推荐

