Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.net core 3.0, "ReflectionOnly loading is not supported on this platform." #1732

Closed
jherby2k opened this issue Mar 10, 2019 · 20 comments
Closed

Comments

@jherby2k
Copy link

jherby2k commented Mar 10, 2019

Description

You're probably well aware of this limitation, but I thought i'd log an issue since I can't find one.

I'm unable to dynamically load modules using a DirectoryModuleCatalog under .NET Core 3.0. It throws the exception System.PlatformNotSupportedException: 'ReflectionOnly loading is not supported on this platform.'

Steps to Reproduce

  1. Create a new .NET Core 3.0 WPF application
  2. override the CreateModuleCatalog method in App.xaml.cs
  3. Return a new DirectoryModuleCatalog.

Expected Behavior

  1. Load the modules without issue. .NET Core apps need to use System.Runtime.Loader to resolve assemblies, but all the same stuff should be doable.

Actual Behavior

Said exception

Basic Information

  • Version with issue: 7.2.0.1038-pre
  • Last known good version: N/A
  • IDE: Visual Studio 2019 RC1

Reproduction Link

If you really need a repro i'll supply one, but this is pretty trivial to reproduce.

@jherby2k
Copy link
Author

jherby2k commented Mar 10, 2019

Just saw your post about stepping back from OSS. That's cool! Thanks for all your hard work. Hopefully you'll take a PR for this - i'll try to work on it once I understand what's needed.

@dansiegel
Copy link
Member

@jherby2k I'm sure that it is trivial to reproduce... if you could please provide a repro that would be helpful though. Our time is really quite limited so having something that demonstrates the reported issue helps us to both validate and prioritize issues.

@jherby2k
Copy link
Author

The prism sample actually fails with this exception... just check out and run https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/netcore3/07-Modules%20-%20Directory (netcore3 branch).

@Grompot77
Copy link

Grompot77 commented Apr 10, 2019

I just ran into the exact same issue, when looking at the code on github, it is using the AppDomain. If there is a different branch, it might be different.

issue 1544 discussed it as well

Trying to hack my way around the AppDomain ... eventually did ...

First issue is Assembly.ReflectionOnlyLoadFrom(fileInfo.FullName); ,seems it is not supported.

Found a comment from our old friend David Fowler ... busy tracking this down, but does not seem to be in the preview build yet.
System.Reflection.MetadataLoadContext

PS: Producing it with the latest ci build from myget

@Grompot77
Copy link

Grompot77 commented Apr 10, 2019

sorry, it is a bit ugly, could not spend more time analysing the MetadataLoadContext, but this is a quick hack that works, just watch out for the this.GetType().Assembly. I was doing it in the running context. And there is a bit of hardcoding for the directory, all this are modified excerpts from the existing code base.

`AssemblyLoadContext ctx = AssemblyLoadContext.GetLoadContext(this.GetType().Assembly);
DirectoryInfo directory = new DirectoryInfo(".\Modules");
var alreadyLoadedAssemblies = ctx.Assemblies;
var fileInfos = directory.GetFiles("*.dll")
.Where(file => alreadyLoadedAssemblies
.FirstOrDefault(
assembly =>
String.Compare(Path.GetFileName(assembly.Location), file.Name,
StringComparison.OrdinalIgnoreCase) == 0) == null);
List validAssemblies = new List();
foreach (FileInfo fileInfo in fileInfos)
{
try
{
var assembly = ctx.LoadFromAssemblyPath(fileInfo.FullName);
validAssemblies.Add(assembly);
}
catch (BadImageFormatException)
{
// skip non-.NET Dlls
}
}

var vss = validAssemblies.SelectMany(a => a.GetTypes())
.Where(v => typeof(IModule).IsAssignableFrom(v))
.Where(t => t != typeof(IModule) && !t.IsAbstract)
.Select(type => CreateModuleInfo(type)).ToList();

var moduleCatalog = base.CreateModuleCatalog();
vss.ForEach(c => moduleCatalog.AddModule(c));
return moduleCatalog;`

@Grompot77
Copy link

Grompot77 commented Apr 10, 2019

The DirectoryModuleCatalog just need these changes, for testing I just added it in-line with the override IModuleCatalog CreateModuleCatalog(), bit easier to step through...

EDIT: Forgot, I did not have IModuleType, so just used IModule and did not know if .GetExportedTypes() is an extension method used inside InnerModuleInfoLoader, therefore on the SelectMany a.GetTypes() would get all the types, not just the Exported Types

@LioRei
Copy link

LioRei commented Apr 12, 2019

So, there is a way to do it. Fell free to comment this approach.

@Grompot77
Copy link

Do not think TypeLoading is the way to go now, the AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies is still not supported. Also reviewed the github code, it is always and empty array, so no luck using it.

@Grompot77
Copy link

Grompot77 commented Apr 12, 2019

@brianlagunas I am making a quick fork, to apply the changes, but it is working. I have added comments to the changes (//ajb:) and left some of the code commented out, so that you can see where the changes was effected

@Grompot77
Copy link

pushed it, https://github.com/Grompot77/Prism/blob/master/Source/Wpf/Prism.Wpf/Modularity/DirectoryModuleCatalog.Desktop.cs

@brianlagunas
Copy link
Member

Thanks, I'll check it out.

@Grompot77
Copy link

Cool, I got my old PrioritizedWatchDirectoryModuleCatalog working as well, it has a filewatcher with a priority loading construct 👍

@jherby2k
Copy link
Author

jherby2k commented Apr 19, 2019

I haven't had time to investigate this - thanks for working on it! I definitely get the impression https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0#type-metadataloadcontext is the new way of doing things.

@LioRei
Copy link

LioRei commented Apr 24, 2019

I've reworked my code with the new way in 3.0 (thx @jherby2k). You will "only" need to take care about assembly resolving because I've an error with mscorlib that is resolved with an ugly patch. So, there is the code in the attached zip:

src.zip

PS Remember to activate "include prerelease" in nuget and add the package System.Reflection.MetadataLoadContext

@Grompot77
Copy link

Thanks for all the work, remember that the changes being made has to "fit" both full and core stack, just doing it for core is not good enough IMHO. Might need to incorporate the change to have a conditional build switch and build 2x packages. Another way is to run a PrismCore project that has linked files for common work and only make new files where the core does not support the old full stack work.

@LioRei
Copy link

LioRei commented Apr 24, 2019

I think, and it's only my opinion, it will be a mandatory to update to netstandard2.0 at least to be able to maintain a full framework and a netcore version without to much work.

for the work I've done, it's only to unblock guys on netcore who have the same problem than me with the module directory loader and I totally understand that will not be merge on prism now (or never), I'm fine with that :)

@brianlagunas
Copy link
Member

The approach to take here is to have two different implementations. One for .NET and one for .NET Core.

@brianlagunas
Copy link
Member

I used @Grompot77 code in a .NET Core 3 version of the DirectoryModuleCatalog with PR #1828. Please test it out in the latest nightly build on MyGet in about 30 minutes.

@Grompot77
Copy link

Thanks @brianlagunas , I will test it out as soon as I can. On a personal note, I think we should create a branch for the .net core work. I will try and see how much I can port for the MS DI work through some middleware registration in the ServicesCollection. My feeling is to have it registered, eg services.AddPrism which will wire up Prism modules. Let me know what you think.

@lock
Copy link

lock bot commented Jan 28, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants