dotnet/aspnetcore · error · ArgumentException
The type {componentType.FullName} does not implement {nameof
Error message
The type {componentType.FullName} does not implement {nameof(IComponent)}. What it means
Thrown by DefaultComponentActivator.CreateInstance when the requested type does not implement IComponent. Blazor's component instantiation requires the type to be a valid component; passing a plain class, struct, or non-component type is an error. The check is at DefaultComponentActivator.cs:28-31.
Source
Thrown at src/Components/Components/src/DefaultComponentActivator.cs:30
{
private static readonly ConcurrentDictionary<Type, ObjectFactory> _cachedComponentTypeInfo = new();
static DefaultComponentActivator()
{
if (HotReloadManager.IsSupported)
{
HotReloadManager.Default.OnDeltaApplied += ClearCache;
}
}
public static void ClearCache() => _cachedComponentTypeInfo.Clear();
/// <inheritdoc />
public IComponent CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type componentType)
{
if (!typeof(IComponent).IsAssignableFrom(componentType))
{
throw new ArgumentException($"The type {componentType.FullName} does not implement {nameof(IComponent)}.", nameof(componentType));
}
var factory = GetObjectFactory(componentType);
return (IComponent)factory(serviceProvider, []);
}
private static ObjectFactory GetObjectFactory([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type componentType)
{
// Unfortunately we can't use 'GetOrAdd' here because the DynamicallyAccessedMembers annotation doesn't flow through to the
// callback, so it becomes an IL2111 warning. The following is equivalent and thread-safe because it's a ConcurrentDictionary
// and it doesn't matter if we build a cache entry more than once.
if (!_cachedComponentTypeInfo.TryGetValue(componentType, out var factory))
{
factory = ActivatorUtilities.CreateFactory(componentType, Type.EmptyTypes);
_cachedComponentTypeInfo.TryAdd(componentType, factory);
}
View on GitHub (pinned to 294cab2f9b)
Solutions
- Ensure the type derives from ComponentBase (or implements IComponent directly).
- Verify the Type passed to DynamicComponent is actually a Razor component, not a data model.
- If loading types dynamically, filter candidates to those implementing IComponent.
Example fix
// before
public class MyData { public int Id; } // not a component
<DynamicComponent Type="@typeof(MyData)" />
// after
public class MyDataComponent : ComponentBase
{
[Parameter] public int Id { get; set; }
}
<DynamicComponent Type="@typeof(MyDataComponent)" /> Defensive patterns
Strategy: type-guard
Validate before calling
if (!typeof(IComponent).IsAssignableFrom(componentType))
throw new ArgumentException($"{componentType} does not implement IComponent."); Type guard
static bool IsValidComponentType(Type t) => typeof(IComponent).IsAssignableFrom(t);
Prevention
- Validate candidate types with typeof(IComponent).IsAssignableFrom before passing to DynamicComponent.
- Use a typed registry of known component types instead of open-ended reflection.
When it happens
Trigger: Passing a type to DynamicComponent's Type parameter, a custom activator, or a root component registration where the type does not implement IComponent (i.e., does not derive from ComponentBase or implement the interface directly).
Common situations: Passing a POCO or service class to DynamicComponent Type; wiring up a type by name that is a model not a component; reflection-based component loading that picks the wrong type.
Related errors
- The component activator returned a null value for a componen
- Cannot notify about changes because the {GetType()} is confi
- Cannot provide a value for property '{propertyName}' on type
- Cannot provide a value for property '{propertyName}' on type
- Cannot provide a value for property '{propertyName}' on type
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/3c800d0389c070f7.
Report an issue: GitHub.