Rick Strahl
Rick Strahl

Reputation: 17651

Loading Assembly and Type in .NET Core

I'm trying to dynamically load assemblies at runtime in .NET Core by essentially looking in an external folder and loading assemblies from there. Loading seems to work fine, however, i can't seem to instantiate the now loaded types in a .NET Core application.

I'm using the the following loading code (very basic for feasibility testing at this point):

private void LoadPrivateBinAssemblies()
{
    var binPath = Path.Combine(WebRoot, "PrivateBin");
    if (Directory.Exists(binPath))
    {
        var files = Directory.GetFiles(binPath);
        foreach (var file in files)
        {
            if (!file.EndsWith(".dll", StringComparison.CurrentCultureIgnoreCase) &&
               !file.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase))
                continue;

            try
            {
                var asm = AssemblyLoadContext.Default.LoadFromAssemblyPath(file);
                //var asm = Assembly.LoadFrom(file);
                Console.WriteLine("Additional Assembly: " + file);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed to load private assembly: " + file);
                Console.WriteLine("   " + ex.Message);
            }
        }
    }
}    

Note - I am using AssemblyLoadContext.Default to load into the .NET Core default context, from which I would presumably be creating a new type.

Then - for testing I now explicitly try to instantiate a type like this at the bottom of the Configure() startup sequence:

LoadPrivateBinAssemblies();

// this has my loaded assemblies in it
var list = AssemblyLoadContext.Default.Assemblies;

try
{
    // this works
    var t = Type.GetType(typeof(Startup).FullName);

    // fails - Markdig is loaded and has no dependencies
    var t2 = Type.GetType("Markdig.Markdown", true);  // fails

    // fails 
    var md = Type.GetType("Westwind.AspNetCore.Markdown.Markdown", true);  
    // never get here
    md.InvokeMember("Parse", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new object[] { "**asdasd**", false, false, false });
}
catch (Exception ex)
{
    Console.Log($"{ex.message}");
}

I've verified that the types exist in the assemblies and that the names are correct, but it fails on several custom loaded assemblies.

enter image description here

The figure shows the list of loaded assemblies (here from AppDomain.GetAssemblies(), but I get the same list from AssemblyLoadContext.Default.Assemblies). The assemblies are loaded, but I can't get a type reference to the types contained within it.

Any ideas what I'm missing here?

Upvotes: 2

Views: 540

Answers (1)

davidfowl
davidfowl

Reputation: 38764

You need to use the assembly qualified name so, Type.GetType("Namespace.TypeName, AssemblyName").

Upvotes: 3

Related Questions