mkens
mkens

Reputation: 65

Render component dynamically in Blazor using List<string>

I am trying to render component dynamically based on string List.

Let's List values which contains Component Name.

For example:

List<string> componentName = new List<string>() { "SurveyPrompt", "FetchData","Counter" };

Based on above list my component should render.

In Blazor, we have DynamicComponent in which it will generate Dynamic component based on component Type List. Below code is for reference.

Blazor page

<div class="container-fluid">
      <div class="row" >
            <div class="col-md-12">
                <div class="d-flex flex-wrap" style="height: 200px;">

                 @foreach (var component in components)
                {
                    <DynamicComponent [email protected] [email protected] />
                }
            </div>
        </div>
    </div>
</div>

Based on components list it going to render components

@code {
                
                 public List<(Type type, Dictionary<string, object> parameters)> components = new List<(Type type, Dictionary<string, object> parameters)>()
    { (typeof(SurveyPrompt), new Dictionary<string, object>() { }) };
                }

Here, how can I pass component name as string and convert it into Blazor Component?

Upvotes: 1

Views: 1825

Answers (2)

MrC aka Shaun Curtis
MrC aka Shaun Curtis

Reputation: 30350

You can wrap this functionality into a collection class with error checking:

public record ComponentData(Type ComponentType, Dictionary<string, object> Parameters) { }

public class ComponentList : IEnumerable<ComponentData>
{
    private readonly List<ComponentData> _components = new List<ComponentData>();
    private readonly Assembly _assembly;

    public ComponentList(Assembly assembly)
        => _assembly = assembly;

    public bool TryAdd(string componentName, Dictionary<string, object> parameters)
    {
        var comp = _assembly.GetTypes()
            .SingleOrDefault(item => item.Name.Equals(componentName) && item.IsAssignableTo(typeof(Microsoft.AspNetCore.Components.IComponent)));

        if (comp is not null)
            _components.Add(new ComponentData(comp, parameters));

        return comp is not null;
    }

    public IEnumerator<ComponentData> GetEnumerator()
        => _components.GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator()
        => this.GetEnumerator();
}

Upvotes: 1

mkens
mkens

Reputation: 65

I have accomplish this by getting all assembly by default and check based on my string List data

 public List<(Type type, Dictionary<string, object> parameters)> components = new List<(Type type, Dictionary<string, object> parameters)>();



 Assembly assembly = Assembly.GetEntryAssembly();
                    Type[] assemblyType = assembly.GetTypes();
    
                    for (int i = 0; i < assignedFeatureList.Count; i++)
                    {
                        Type typeComponent = assemblyType.Where(x => x.Name.Contains(assignedFeatureList[i])).FirstOrDefault();
                        if (typeComponent != null)
                        {
                            (Type type, Dictionary<string, object> parameters) item;
    
                            item.type = typeComponent;
                            item.parameters = new Dictionary<string, object>();
    
                            components.Add(item);
    
                        }
                    }

Upvotes: 1

Related Questions