Reputation: 7692
We need to iterate over all assemblies in our app, and then get types that have a CustomAttribute of type DataContract. This is the code that currently works in UWP when not compiled for .NET Native:
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();
}
This fails when compiling for .NET Native toolchain. Firstly, we only see one assembly which is an exe, and that has no types in it.
What do we need to change? How do we get the assemblies and their types?
Note: What we really need is a definitive list of reflection APIs that are supported by .NET Native and those that aren't.
Upvotes: 2
Views: 246
Reputation: 7692
So, the main difference between standard UWP, and .NET Native is that all of the assemblies are compiled in to machine code, and probably sit inside the exe rather than .NET Assembly DLLs, so the above code no longer works. However, the method is still the same so long as you actually know which assemblies are being used. In this case I have hard coded the assemblies, but I could potentially use the Assembly.Load method to dynamically load assemblies at runtime. However, I'm not sure if the store validator will allow this code. I may have to ask a separate question if the validator rejects this code.
#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
Upvotes: 1