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 assembly loading might fail with FileNotFoundException #64

Closed
mauroservienti opened this issue May 9, 2017 · 8 comments
Closed

Comments

@mauroservienti
Copy link
Member

When dynamically loading assemblies in .NET Core the full framework approach of using Assembly.Load might fail with FileNotFoundException even if the file is available and in the expected location.

Various reasons might lead to that error depending on the packaging configuration and/or if the assembly is already referenced.

The following snippet solves the issue by testing if the assembly is already referenced at compile time or run time (deployment package) and choosing the right approach to load the assembly.

static class AssemblyLoader
{
    public static Assembly Load(string assemblyFullPath)
    {
        var fileNameWithOutExtension = Path.GetFileNameWithoutExtension(assemblyFullPath);

        var inCompileLibraries= DependencyContext.Default.CompileLibraries.Any(l => l.Name.Equals(fileNameWithOutExtension, StringComparison.OrdinalIgnoreCase));
        var inRuntimeLibraries = DependencyContext.Default.RuntimeLibraries.Any(l => l.Name.Equals(fileNameWithOutExtension, StringComparison.OrdinalIgnoreCase));

        var assembly = (inCompileLibraries || inRuntimeLibraries)
            ? Assembly.Load(new AssemblyName(fileNameWithOutExtension))
            : AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyFullPath);

        return assembly;
    }
}
@mauroservienti mauroservienti self-assigned this May 9, 2017
@mauroservienti mauroservienti mentioned this issue May 9, 2017
11 tasks
@adamralph
Copy link
Contributor

@mauroservienti is this a bug in both samples?

@mauroservienti
Copy link
Member Author

The bug might affect all the .NET Core demos, so both ASP.Net Core API Gateway and ASP.Net MVC.

The problem is the following: to keep the demo as simple as possible frontend projects directly reference ViewModel and UI Composition assemblies for the sole purpose of:

  • Having them in bin directory
  • Benefiting of the fact that having VS understanding dependencies via references automatically create the expected projects build order

At sample startup time we scan the bin looking for ViewModel and UI Composition assemblies, in order to scan types we need to load the assembly, in .NET Core assemblies can load in 2 ways 😕

Assemblies can be referenced as compile time assemblies or as runtime assemblies, and to complicate things the way probing works depends on the deployment type

  1. If the assembly is referenced via Assembly.Load
  2. If the assembly is not referenced via AssemblyLoadContext.Default.LoadFromAssemblyPath

As it stands now samples work using the first approach. The problem I see is that users want to play at home and one of the thing they try is to remove the reference and create a sample deployment via some scripting...and kaboom, the assembly is not referenced anymore and we fall now in the second way of loading assemblies. The above sample code utilizes the Microsoft.Extensions.DependencyModel to understand in which way assemblies should be loaded.
I'm still playing with the sample to understand if it covers all the scenarios, and so far it seems so.

To complicate things, Visual Studio 2017 post build events are broken when it comes to .NET Core projects. We could workaround it but I'd prefer to stay with references as of now.

References:

@mauroservienti
Copy link
Member Author

Removing myself from this since the fix is pending in #59, once that's merged this is done.

@mauroservienti mauroservienti removed their assignment Aug 3, 2017
mauroservienti added a commit that referenced this issue Aug 3, 2017
@adamralph adamralph added the bug label Aug 3, 2017
@adamralph
Copy link
Contributor

@mauroservienti to clarify, does this bug currently exist in the asp-net-mvc sample, but does not exist in the new asp-net-core sample in #59?

@mauroservienti
Copy link
Member Author

It doesn't exist in the asp-net-mvc and it's fixed in the asp-net-core via 3b5833d

@adamralph
Copy link
Contributor

OK, so given that the fix also exists in the branch for #59, and therefore the new demo doesn't have the bug, the bug doesn't actually "exist" at all, so can we withdraw this?

@mauroservienti
Copy link
Member Author

this will be automatically closed as we merge #59, is there any advantage in closing this before the PR is merged? Just wondering, it's not a problem at all to close this right now linking to the commit with the fix.

@adamralph
Copy link
Contributor

Discussed with @mauroservienti and agreed to close, since the bug no longer exists in #59.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants