How to load assemblies in ASP.NET Core 1.0 RC2
Asked Answered
L

2

5

I am migrating my web app from ASP.NET Core RC1 to RC2. I'm trying to load my referenced class libraries.

This code snippet doesn't work with RC2 any more:

public class Startup
{  
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        // libraryManager is null .... 
        ILibraryManager libraryManager = app.GetService<ILibraryManager>();

        List<Assembly> result = new List<Assembly>();

        IEnumerable<Library> libraries = libraryManager.GetLibraries();

        IEnumerable<AssemblyName> assemblyNames = libraries.SelectMany(e => e.Assemblies).Distinct();
        assemblyNames = Enumerable.Where(assemblyNames, e => e.Name.StartsWith("projectNamespace"));

        foreach (AssemblyName assemblyName in assemblyNames)
        {
            Assembly assembly = Assembly.Load(assemblyName);
            .
            .
            .
        }
    }
}
Liscomb answered 19/5, 2016 at 6:28 Comment(2)
What kind of error are you getting?Husted
no error.... but app.GetService<ILibraryManager>() returns nullLiscomb
L
12

I found a solution. I'm using now DependencyContext instead of ILibraryManager

var loadableAssemblies = new List<Assembly>();

var deps = DependencyContext.Default;            
foreach (var compilationLibrary in deps.CompileLibraries)
{
    if (compilationLibrary.Name.Contains(projectNamespace))
    {
        var assembly = Assembly.Load(new AssemblyName(compilationLibrary.Name));
        loadableAssemblies.Add(assembly);
    }
}
Liscomb answered 19/5, 2016 at 19:12 Comment(1)
In my program DependencyContext.Default resolves to null. Any suggestions why this could happen?Holy
Q
3

I think stevo has made 2 wrong assumptions:

1) that project namespace should be part of compilation library name.
2) that compilation library name is the same as binary name.

First one is wrong when you change it in project settings. Second one is wrong when you specify it in buildOptions in project.json.

So your idea is correct but implementation is wrong. To fix that we need to forget about resolving by namespace until assembly is loaded.
I guess since all assemblies will be loaded in any case we will not get big performance lag.

But it is not panacea... assembly can have multiple root namespaces inside! So maybe better way will be to define some attribute on assembly level and check it instead of namespace.

In any case if you want to limit your search by assembly name it should be made like this:

IEnumerable<AssemblyName> names = DependencyContext.Default.GetDefaultAssemblyNames();

foreach (AssemblyName name in names)
{
    if (name.Name.StartsWith("MyRoot") == true)
    {
        Assembly assembly = Assembly.Load(name);

        // Process assembly here...
        // I will check attribute for each loaded assembly found in MyRoot.
    }
}
Qoph answered 26/7, 2016 at 12:30 Comment(1)
A slight variation on this approach worked for me, cheers. :)Nilgai

© 2022 - 2024 — McMap. All rights reserved.