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