Search code examples
c#.net.net-corerazorblazor-webassembly

Generic Razor Type Parameter pass as variable


Razor/Blazor component with Generic Type Parameter as a variable

 <QueryRow  Titem="Person"/>

Works

in the above component i can recieve the parameter

 Type typeParameterType = typeof(Titem);

and create an instance

 object? myObject = Activator.CreateInstance(typeParameterType);

That all works great, however

  public Type mytype = typeof(Person);

  <QueryRow  Titem="@mytype"/>

Does not work, I need be able to pass the types down from the parent as list of types or strings I can convert to real types using reflection.

How do I pass the type parameter as a variable such as

mytype = typeof(Person);

I can do all this in code but not in razor!!! what am I doing different/ wrong ?

for example, Person starts as a string below

   Type? typeArgument = Type.GetType("Person");
   Type genericClass = typeof(QueryRow<>);
   Type constructedClass = genericClass.MakeGenericType(typeArgument);
   object? createdType = Activator.CreateInstance(constructedClass);

works great, but then I have to use blazor's Dynamic component as a workaround to do the render, which I'd rather avoid as it seems a bit yuk


Solution

  • You can't use a variable as the type parameter in this way.

    You can create a RenderFragment using a bit of reflection:

    public Type myType = typeof(Person);
    
    @MakeQueryComponent(myType)
    
    @code {
        RenderFragment MakeQueryComponent(Type typeParam)
        {
            var genericType = typeof(QueryRow<>)
                .MakeGenericType(new[] { typeParam });
    
            RenderFragment frag = new RenderFragment(b =>
            {
                b.OpenComponent(1, genericType);
                b.CloseComponent();
            });
    
            return frag;
        }
    }
    

    UPDATE

    Following GitHub issue 26781, the Blazor team have now encapsulated the above method of generating a RenderFragment into a new component called DynamicComponent.

    See source code and guidance.