Load external Assembly (RCL) to Blazor WebAssembly app

2k Views Asked by At

It is possible to load a RCL (Razor Component Library) to Blazor WebAssembly dynamically?

I found this Loading an external .NET Standard 2.0 assembly with blazor to load a standard classes

What I want is to develop a pluggable/extensible visual framework, where putting a dll in a ASP.NET Core Server folder where enought to access to that blazor component

Solution config:

  • ASP.NET Core WebAPI project
  • Blazor WebAssembly project
  • RCL project 1 with some components
  • RCL project 2 with another components

Steps:

  • Open a Blazor Page and OnInitializedAsync() retreive some dll from WebAPI as binary
  • Load binary to Assembly
  • Reference the assembly and use it dynamically in the page
2

There are 2 best solutions below

0
On BEST ANSWER

I finally develop a solution I want to share with you. A Module Manager witch allows you to load any outside component dynamically

Check it out here:

https://github.com/elgransan/BlazorPluginComponents

Some example code

        var componentPackage = "RazorClassLibrary2";
        var component = "Component2";
        var stream = await Http.GetStreamAsync($"{MyNavigationManager.BaseUri}/{componentPackage}/{componentPackage}.dll");
        var assembly = AssemblyLoadContext.Default.LoadFromStream(stream);
        componentType = assembly.GetType(componentPackage + "." + component);
        await DOMinterop.IncludeLink(componentPackage, $"/{componentPackage}/{componentPackage}.styles.css");

Where the files are in the server

0
On

Sorry for the late answer, but yes, you can do that.

To use dynamic components, follow these steps:

  1. Load the assemblies using the Assembly.LoadfFrom(assemblyFilename)
  2. In a .razor file, use the blazor render tree builder to render your component dynamically, like this:
RenderFragment EditContent = (__builder) =>
{
    __builder.OpenComponent(0, TypeOfYourComponent);
    __builder.AddAttribute(1, "attr1", attrValue);
    ...
    __builder.AddAttribute(n, "attrn", attrNValue);
    __builder.CloseComponent();
};
@EditContent
  1. Implement a method that returns the type you want from the currently loaded assemblies. The following will provide you a list with all types exported by dynamically loaded assemblies:
var exportedTypes = new List<Type>();
var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();

foreach (var assembly in assemblies)
{
    exportedTypes.AddRange(assembly.GetExportedTypes().ToList());
}

In my case, I created a singleton that loads the assemblies from a folder when it is initialized, and created a method in this singleton to return the type from the list defined on step 3. So, in this way, you can call this service whenever you like by registering it on the Startup.cs and injecting it on your razor components:

public class CustomComponentService : ICustomComponentService
{
    public CustomComponentService(...)
    {
        // load the assemblies here
    }

    public Type GetCustomComponent(...)
    {
        //search in the loaded assemblies by any criteria you like
    }
}

In the Startup.cs ConfigureServices method:

_ = services.AddSingleton<ICustomComponentService, CustomComponentService>();

In the razor file:

@inject ICustomComponentService CustomComponentService

...
__builder.OpenComponent(0, CustomComponentService.GetCustomComponent(...));
...