Author Component

作者 dotnet0608d8924cd3MIT5.5K 个星标收录于 2026年10月8日更新于 2026年10月8日仓库今天更新

Create or review Blazor components (.razor files) with correct architecture. USE FOR: writing new Blazor components that do NOT involve JavaScript interop, implementing parameters and EventCallback, RenderFragment slots, component lifecycle (OnInitializedAsync, OnParametersSet), async patterns, IAsyncDisposable, CancellationToken, CSS isolation, code-behind. DO NOT USE FOR: creating new projects (use create-blazor-project), JavaScript interop or calling browser APIs from Blazor (use use-js-interop), forms and validation (use collect-user-input), prerendering issues (use support-prerendering), HTTP data fetching patterns (use fetch-and-send-data), coordinating state between unrelated components (use coordinate-components).

AI 生成的概览

指导以正确架构编写和审查 Blazor 组件(.razor 文件),涵盖参数、生命周期、异步与释放模式。

功能
提供编写或审查 Blazor 组件的规则与参考资料。内容涵盖参数与 EventCallback 约定、RenderFragment 插槽与泛型、单文件与代码隐藏的布局、组件生命周期、异步及防抖/轮询模式,以及 IAsyncDisposable 释放。还列出应避免的反模式,例如修改参数或用 Action/Func 处理事件。
适用场景
适用于编写不涉及 JavaScript 互操作的新 Blazor 组件,或审查现有 .razor 组件的架构正确性。不适用于创建项目、JS 互操作、表单与验证、预渲染、HTTP 数据获取或跨组件状态协调。
运行要求
无脚本,仅为说明与参考文档。代理需要随附的参考文件,涉及异步编程、组件拆分与组件释放。

Author Blazor Component

Core Rules

  • Data flows down via [Parameter]. Events flow up via EventCallback<T> (never Action/Func).
  • Never mutate [Parameter] properties. Copy to a private field in OnParametersSet.
  • Use [Parameter] public T Prop { get; set; } — never required or init (causes BL0007).
  • Use [EditorRequired] for required parameters.
  • Handle all states: loading, empty, loaded, error — each with @if/@else.
  • Use @key on repeated elements in loops for efficient diffing.
  • Use IReadOnlyList<T> (not IEnumerable<T>) for collection parameters.

RenderFragment & Generics

csharp
[Parameter] public RenderFragment? ChildContent { get; set; }[Parameter] public RenderFragment<TItem>? RowTemplate { get; set; }  // generic template

Use @typeparam TItem for generic components.

File Patterns

  • Single-file: .razor with @code block when logic < ~50 lines.
  • Code-behind: .razor + .razor.cs with partial class when logic > ~50 lines.

Disposal

Implement IAsyncDisposable (not IDisposable) when the component owns subscriptions, timers, or CTS. In DisposeAsync: unsubscribe (-=), cancel CTS, dispose resources. Never call StateHasChanged.

Async Patterns

  • await every async operation. Never use .Result, .Wait(), Task.Run, ContinueWith, Thread.Start.
  • Debounce: Task.Delay + CancellationTokenSource. Cancel old CTS, create new, await delay, do work. Never use System.Threading.Timer or System.Timers.Timer.
  • Polling: Loop in OnInitializedAsync with await Task.Delay(interval, token) — stays on sync context.
  • External events (Action<T>): Use async void handler + await InvokeAsync(() => { state++; StateHasChanged(); }) + catch → DispatchExceptionAsync. Never _ = InvokeAsync(...).
  • Cancel CTS in DisposeAsync. Don't catch ObjectDisposedException — use CTS cancellation.

Don'ts

  • required/init on [Parameter] — runtime failure
  • Mutate [Parameter] — copy to private field in OnParametersSet
  • Action/Func for events — use EventCallback<T>
  • Task.Run/.Result/.Wait()/Timer for debounce — deadlock or thread-pool escape
  • Inline style attributes — use CSS classes or data-* attributes
  • catch { throw; } — use when guard or let exceptions propagate
  • Gold-plating: ARIA, wrapper divs, accessibility features not requested
  • _ = InvokeAsync(...) — swallows exceptions; use async void + DispatchExceptionAsync

来源与署名

来源:dotnet/skills位于plugins/dotnet-blazor/skills/author-component提交0608d89

许可证: MIT

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架