.Net Programming

Explore the .Net with the latest in C# from basic to advanced, including .Net versions 9, 8, 6, 5, Core 3.1, .Net Framework, ASP.NET Core, MVC, design patterns, OOPS, and SOLID principles. Get top tutorials, best practices, and hands-on code examples on GitHub.

Follow publication

Overriding components in Blazor

--

Photo by James Harrison on Unsplash

If you use a component library in your project, you might want to override a component somewhere deep down in the component hierarchy without having to override the whole hierarchy.

I spent some hours searching the web for a solution for this, without finding any up to date answers. With this article I hope to help others searching for the same.

By reading the Blazor source code on GitHub, I discovered that components are created through a DefaultComponentActivator, implementing the IComponentActivator interface. This means that we can create our own implementation of IComponentActivator that will replace the default one when we register it.

public class OverridableComponentActivator : IComponentActivator
{
private static Dictionary<Type, Type> _replaceTypes { get; set; }
= new Dictionary<Type, Type>();
public void RegisterOverride<TOriginal, TOverride>()
{
_replaceTypes.Add(typeof(TOriginal), typeof(TOverride));
}
public IComponent CreateInstance(Type componentType)
{
if (!typeof(IComponent).IsAssignableFrom(componentType))
{
throw new ArgumentException($"The type {componentType.FullName} does not implement {nameof(IComponent)}.", nameof(componentType));
}
if (_replaceTypes.ContainsKey(componentType))
{
componentType = _replaceTypes[componentType];
}
return (IComponent)Activator.CreateInstance(componentType)!;
}
}

By registering this in your Program.cs, you can now override any component:

var componentActivator = new OverridableComponentActivator();componentActivator.RegisterOverride<NavLink, MyNavLink>();builder.Services.AddSingleton<IComponentActivator>(componentActivator);

Be aware that the component signature should match the component that is overridden. If not, runtime errors can occur. This can be enforced by requiring inheritance:

public void RegisterOverride<TOriginal, TOverride>()
{
if (!typeof(TOriginal).IsAssignableFrom(typeof(TOverride)))
{
throw new ArgumentException($"{nameof(OverridableComponentActivator)}.{nameof(RegisterOverride)}: The override '{typeof(TOverride).FullName}' must implement '{typeof(TOriginal).FullName}'.");
}
_replaceTypes.Add(typeof(TOriginal), typeof(TOverride));
}

This is based on, and tested with, .NET5 Blazor webassembly.

Enjoy!

Sign up to discover human stories that deepen your understanding of the world.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

.Net Programming
.Net Programming

Published in .Net Programming

Explore the .Net with the latest in C# from basic to advanced, including .Net versions 9, 8, 6, 5, Core 3.1, .Net Framework, ASP.NET Core, MVC, design patterns, OOPS, and SOLID principles. Get top tutorials, best practices, and hands-on code examples on GitHub.

No responses yet

Write a response