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

Assembly Load Context throws errors in Blazor App 0.8 #7917

Closed
fred-perkins opened this issue Feb 25, 2019 · 8 comments
Closed

Assembly Load Context throws errors in Blazor App 0.8 #7917

fred-perkins opened this issue Feb 25, 2019 · 8 comments
Labels
area-blazor Includes: Blazor, Razor Components

Comments

@fred-perkins
Copy link

Describe the bug

When trying to load an assembly using the AssemblyLoadContext.Default a NotImplementedException is thrown. The Static property Default and it's other static methods don't seem to have any implementations.

To Reproduce

Steps to reproduce the behavior:

  1. Download Sample code from: fred-perkins/BlazorLoading
  2. Run application
  3. Select Fetch Assembly in the left panel
  4. Click "Fetch Assembly using AssemblyLoadContext" Button
  5. Observe error in console: WASM: [System.NotImplementedException] The method or operation is not implemented.

Expected behavior

AssemblyLoadContext should attempt to load the DLL in the default context.

Additional context

We need to be able to dynamically load libraries one at a time within Blazor. Using Assembly.Load to read from bytes presents a problem where assemblies can be loaded several times, which causes a InvalidCastException to be thrown when resolving a type from one of those libraries.
Using AssemblyLoadContext it is possible to avoid this, however it seems unsupported when running in Webassembly on Blazor - But functions within a console application.

This is likely a mono issue:
Looking at mono it seems there are two implementations of the class: AssemblyLoadContext Facade
& AssemblyLoadContext.

@fred-perkins
Copy link
Author

@danroth27 - We spoke about this a week ago (Part of a derivco call). This is blocking us from migrating our framework to Blazor for our POC, as we need to be able to dynamically load libraries in the background. Is there a known alternative we could use other than Assembly.Load - Which doesn't solve our problem

@muratg muratg added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Feb 25, 2019
@danroth27 danroth27 added the area-blazor Includes: Blazor, Razor Components label Feb 27, 2019
@danroth27
Copy link
Member

@fred-perkins Thanks for sharing this feedback with us!

@SteveSandersonMS @lewing Thoughts on this one? Do we have any support currently for dynamically loading .NET assemblies in a Blazor app? Is this really all part of supporting lazy loading of application areas?

@SteveSandersonMS
Copy link
Member

Could you clarify what the problem with Assembly.Load is? If your code caches the results of loading the assembly, is that not sufficient to ensure you only load each one once?

@fred-perkins
Copy link
Author

@SteveSandersonMS / @danroth27 So after a bit of testing I got Assembly.Load(byte[]) to work for me as i wanted. I think there was a misunderstanding about how Assembly.Load varies compared to the API on DotNet core - Where a byte array loaded assembly is anonymous and causes issues where assemblies would be loaded twice. This occurred when one was manually loaded, and the second where an assembly used a type for a dependent assembly - Which results in a InvalidCastException with duplicate types.
This means that for me to work around the issue I've had to use AssemblyLoadContext in .Net Core & Assembly.Load for the web assembly portion.

Ideally i'd prefer to use the AssemblyLoadContext Api across the board so i don't have to do fallback code in my .NetStandard libraries like the following:

public Assembly LoadFromStream(byte[] assemblySource)
{
    if (AssemblyLoadContext.Default != null)
    {
        return AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(assemblySource))
    }
    return Assembly.Load(assemblySource);
}

I did have a dig through the mono source code in the end. It looks like they don't fully support the AssemblyLoadContext Api, and where they have partial support it only works for when you specify the assemblyName or filePath - The LoadFromStream throws a not supported exception as mentioned above.

@SteveSandersonMS
Copy link
Member

Thanks for the update, @fred-perkins! I'm glad you have a workable solution for now.

Longer term, any inconsistencies between .NET Core and Mono are definitely worth reporting. In this specific case it sounds like Mono ideally would support more of AssemblyLoadContext, and might even want tweaks to ensure that Assembly.Load behaves the same as it does on .NET Core (even if that behavior isn't what you wanted in your scenario, it should still be consistent). If you were able to report any such API gaps or inconsistencies to http://github.com/mono/mono that would be really helpful.

@SteveSandersonMS
Copy link
Member

I'll close this as external since it's really about the underlying runtime, not about Blazor.

@fred-perkins
Copy link
Author

@SteveSandersonMS Awesome, thanks for the reply. I'll get a ticket raised with the Mono guys :)

@tylerhartwig
Copy link

tylerhartwig commented Apr 24, 2019

@fred-perkins
Can you link to the related mono issue?

I'm struggling to properly resolve a type existing in Assembly A, that depends on Assembly B.

Both are loaded into the default context already, but I'm looking to ensure A uses the type from B (newly loaded at runtime, separate from the default context), rather than what's already loaded.

@mkArtakMSFT mkArtakMSFT removed area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels May 9, 2019
@ghost ghost locked as resolved and limited conversation to collaborators Dec 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components
Projects
None yet
Development

No branches or pull requests

6 participants