samedi 4 février 2017

Asp.Net Core: Reflecting an Asp.Net Assembly throw exception

I'm currently implementing an elementary solution to load the Services in an Asp.Net Core by reflection instead of having to pass every single type. To have some wiggle-room, I created a static helper returning me the assembly-types using the new core-reflection types:

internal static class ReflectionTypeHelper
{
    private static readonly Assembly _currentAssembly = typeof(ServiceContainerInitializer).GetTypeInfo().Assembly;

    internal static IReadOnlyCollection<Type> ScanAssembliesForTypes(Func<Type, bool> predicate)
    {
        var result = new List<Type>();
        var appAssemblies = GetApplicationAssemblies();

        foreach (var ass in appAssemblies)
        {
            var typesFromAssembly = ass.GetTypes().Where(predicate);
            result.AddRange(typesFromAssembly);
        }

        return result;
    }

    private static IEnumerable<Assembly> GetApplicationAssemblies()
    {
        var consideredFileExtensions = new[]
        {
            ".dll",
            ".exe"
        };

        var result = new List<Assembly>();
        var namespaceStartingPart = GetNamespaceStartingPart();

        var assemblyPath = GetPath();
        IEnumerable<string> assemblyFiles = Directory.GetFiles(assemblyPath);

        var fileInfos = assemblyFiles.Select(f => new FileInfo(f));
        fileInfos = fileInfos.Where(f => f.Name.StartsWith(namespaceStartingPart) && consideredFileExtensions.Contains(f.Extension.ToLower()));

        // Net.Core can't load the Services for some reason, so we exclude it at the moment
        //fileInfos = fileInfos.Where(f => f.Name.IndexOf("Services", StringComparison.OrdinalIgnoreCase) == -1);

        foreach (var fi in fileInfos)
        {
            var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(fi.FullName);
            result.Add(assembly);
        }

        return result;
    }

    private static string GetNamespaceStartingPart()
    {
        var fullNamespace = _currentAssembly.FullName;
        var splittedNamespace = fullNamespace.Split('.');

        var result = string.Concat(splittedNamespace[0], ".", splittedNamespace[1]);
        return result;
    }

    private static string GetPath()
    {
        var codeBase = _currentAssembly.CodeBase;
        var uri = new UriBuilder(codeBase);
        var result = Uri.UnescapeDataString(uri.Path);
        result = Path.GetDirectoryName(result);

        return result;
    }
}

As you can probably see in the code-comment, I can't load the "Services"-Assembly, which I creted from the "ASP.NET Core Web Application (.Net Core)" - Project template.

Unfortunately, the exception is quite generic

Could not load file or assembly 'Argusnet.Pis.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

Also, the file is there as expected. I did find some hints on GitHub-Issues regarding this topic, but they're all solved in the Release Candidates.

Interesting enough, all other assemblies work as you'd expect, so there has to be something specific regarding this assembly-types?





Aucun commentaire:

Enregistrer un commentaire