0
votes

​I have started to work with Blazor and setup a hosted web-assembly application.

Within the App.Razor, I am using lazy loaded assemblies which are loaded from an API and then use Reflection to inspect each dll for an implementation of a specific interface.

This works perfectly fine when running the solution via Visual Studio (debugging). When I publish the solution, I am getting an error when loading the libraries stating System.Runtime 5.0.0.0 is missing.

This is working whenever it is being started in visual studio but not when running the published code.

I have tried this using Blazor server and this is working perfectly fine.

I have tried to work with adding false to see if the problem is caused by the linking but the issue still exists.

I have tried this on net5, net5.0.1 and net5 RC2.

Any advice would be much appreciated.

Thanks in advance​

The code in my webassembly is:

private static List<Assembly> LoadedAssemblies { get; set; }
    public static async Task<List<Assembly>> GetAssemblies(HttpClient client)
    {
        if (LoadedAssemblies is null)
        {
            LoadedAssemblies = new List<Assembly>();
            Console.WriteLine($"Running Version: {Runtime.FrameworkDescription}");

            var files = System.Text.Json.JsonSerializer.Deserialize<string[]>(await (await client.GetAsync("/api/addons")).Content.ReadAsStringAsync());

            Console.WriteLine(string.Join(',', files));
            
            var allAssemblies = new List<Assembly>();
            foreach (string dll in files)
            {
                var dllData = await client.GetStringAsync("/api/addons/" + dll);
                allAssemblies.Add(Assembly.Load(Convert.FromBase64String(dllData)));
            }

            LoadedAssemblies = allAssemblies
                .Where(w => w.GetTypes().Any(a => a.GetInterfaces().Contains(typeof(IModule)))).ToList();
        }

        return LoadedAssemblies;
    }

    public static async Task<IEnumerable<TypeInfo>> GetTypes<T>(HttpClient client)
    {
        return (await GetAssemblies(client)).SelectMany(a => a.DefinedTypes.Where(x => x.GetInterfaces().Contains(typeof(T))));
    }

    public static async Task<IEnumerable<T>> GetInstances<T>(HttpClient client)
    {
        List<T> instances = new List<T>();

        foreach (Type implementation in await GetTypes<T>(client))
        {
            if (!implementation.GetTypeInfo().IsAbstract)
            {
                T instance = (T)Activator.CreateInstance(implementation);
                instances.Add(instance);
            }
        }

        return instances;
    }

The Chrome error is:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Could not load file or assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.
System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.
IO_FileName_Name, System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
   at System.Reflection.RuntimeModule.GetTypes()
   at System.Reflection.Assembly.GetTypes()
   at AssemblyScanning.<>c.<GetAssemblies>b__4_0(Assembly w)
   at System.Linq.Enumerable.WhereListIterator`1[[System.Reflection.Assembly, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].ToList()
   at System.Linq.Enumerable.ToList[Assembly](IEnumerable`1 source)
   at AssemblyScanning.GetAssemblies(HttpClient client)
   at Dash.WMS.WebClient.Client.App.OnNavigateAsync(NavigationContext args)
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.Routing.Router.RunOnNavigateAsync(String path, Boolean isNavigationIntercepted)
   at Microsoft.AspNetCore.Components.Routing.Router.<>c__DisplayClass61_0.<RunOnNavigateAsync>b__1(RenderTreeBuilder builder)
   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry renderQueueEntry)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()
1
Did you try to clear your cache ? - agua from mars
Hi. Thanks for your response. I did yes. I tried this several times and still no success. - Charlie
Post the full browser error - agua from mars
Hi, apologies. I have added this to the question along with the code i am using. I should add the dlls are served from my API as base64 encoded strings and then i am trying to load them. This is to try and develop a plugin based UI. Does this help? Is it something to do with security as i am now in a "production" environment compared to the "Development" environment Visual Studio uses? Thanks again! - Charlie
Just to add, the dynamic modules / dll are not present at compilation time. I can load any dlls in this manner if they were there at compilation time, but no new ones. - Charlie

1 Answers

0
votes

I have found the root of the issue on the following link: docs.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/… I found lots of articals about the trimming but missed this artical. The trimming function was removing the system.runtime library as it wasnt needed at run time! Thanks so much for your help.