UWP .NET Native - 遍历类型和程序集
UWP .NET Native - Iterate Through Types and Assemblies
我们需要遍历应用程序中的所有程序集,然后获取具有 DataContract 类型的 CustomAttribute 的类型。这是未针对 .NET Native 编译时当前可在 UWP 中运行的代码:
public async Task Initialise()
{
var files = await Package.Current.InstalledLocation.GetFilesAsync();
if (files == null)
{
return;
}
_Assemblies = new List<Assembly>();
foreach (var file in files.Where
(
file => (file.FileType.ToLower() == ".dll" || file.FileType == ".exe") &&
!new List<string> { "clrjit", "clrcompression", "sqlite3", "ucrtbased" }.Contains(file.DisplayName)
))
{
try
{
_Assemblies.Add(Assembly.Load(new AssemblyName(file.DisplayName)));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
_Types = _Assemblies.SelectMany
(
a => a.GetTypes().Where
(
t => t.GetTypeInfo().GetCustomAttribute<DataContractAttribute>() != null ||
t.GetTypeInfo().GetCustomAttribute<CollectionDataContractAttribute>() != null
)
).ToList();
}
为 .NET Native 工具链编译时失败。首先,我们只看到一个程序集,它是一个 exe,其中没有任何类型。
我们需要改变什么?我们如何获取程序集及其类型?
注意:我们真正需要的是 .NET Native 支持和不支持的反射 API 的最终列表。
因此,标准 UWP 和 .NET Native 之间的主要区别在于所有程序集都被编译成机器代码,并且可能位于 exe 中而不是 .NET 程序集 DLL 中,因此上面的代码不再作品。但是,只要您真正知道正在使用哪些程序集,该方法仍然是相同的。在这种情况下,我对程序集进行了硬编码,但我可能会使用 Assembly.Load 方法在运行时动态加载程序集。但是,我不确定商店验证器是否会允许此代码。如果验证器拒绝此代码,我可能不得不问一个单独的问题。
#region Public Methods
public async Task Initialise()
{
_Assemblies = new List<Assembly>();
_Assemblies.Add(typeof(ReflectionUtils).GetTypeInfo().Assembly);
_Assemblies.Add(Assembly.Load(new AssemblyName("Adapt.Model.Helpdesk")));
_Assemblies.Add(typeof(SavePage).GetTypeInfo().Assembly);
_Assemblies.Add(typeof(XivicClient.WCF.ServiceCalls.GeneralCalls).GetTypeInfo().Assembly);
_Types = _Assemblies.SelectMany
(
a => a.GetTypes().Where
(
t => t.GetTypeInfo().GetCustomAttribute<DataContractAttribute>() != null ||
t.GetTypeInfo().GetCustomAttribute<CollectionDataContractAttribute>() != null
)
).ToList();
}
#endregion
我们需要遍历应用程序中的所有程序集,然后获取具有 DataContract 类型的 CustomAttribute 的类型。这是未针对 .NET Native 编译时当前可在 UWP 中运行的代码:
public async Task Initialise()
{
var files = await Package.Current.InstalledLocation.GetFilesAsync();
if (files == null)
{
return;
}
_Assemblies = new List<Assembly>();
foreach (var file in files.Where
(
file => (file.FileType.ToLower() == ".dll" || file.FileType == ".exe") &&
!new List<string> { "clrjit", "clrcompression", "sqlite3", "ucrtbased" }.Contains(file.DisplayName)
))
{
try
{
_Assemblies.Add(Assembly.Load(new AssemblyName(file.DisplayName)));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
_Types = _Assemblies.SelectMany
(
a => a.GetTypes().Where
(
t => t.GetTypeInfo().GetCustomAttribute<DataContractAttribute>() != null ||
t.GetTypeInfo().GetCustomAttribute<CollectionDataContractAttribute>() != null
)
).ToList();
}
为 .NET Native 工具链编译时失败。首先,我们只看到一个程序集,它是一个 exe,其中没有任何类型。
我们需要改变什么?我们如何获取程序集及其类型?
注意:我们真正需要的是 .NET Native 支持和不支持的反射 API 的最终列表。
因此,标准 UWP 和 .NET Native 之间的主要区别在于所有程序集都被编译成机器代码,并且可能位于 exe 中而不是 .NET 程序集 DLL 中,因此上面的代码不再作品。但是,只要您真正知道正在使用哪些程序集,该方法仍然是相同的。在这种情况下,我对程序集进行了硬编码,但我可能会使用 Assembly.Load 方法在运行时动态加载程序集。但是,我不确定商店验证器是否会允许此代码。如果验证器拒绝此代码,我可能不得不问一个单独的问题。
#region Public Methods
public async Task Initialise()
{
_Assemblies = new List<Assembly>();
_Assemblies.Add(typeof(ReflectionUtils).GetTypeInfo().Assembly);
_Assemblies.Add(Assembly.Load(new AssemblyName("Adapt.Model.Helpdesk")));
_Assemblies.Add(typeof(SavePage).GetTypeInfo().Assembly);
_Assemblies.Add(typeof(XivicClient.WCF.ServiceCalls.GeneralCalls).GetTypeInfo().Assembly);
_Types = _Assemblies.SelectMany
(
a => a.GetTypes().Where
(
t => t.GetTypeInfo().GetCustomAttribute<DataContractAttribute>() != null ||
t.GetTypeInfo().GetCustomAttribute<CollectionDataContractAttribute>() != null
)
).ToList();
}
#endregion