You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Blazor中用工厂模式消除调用Razor组件的If/else语句

在Blazor中实现组件工厂模式的方案

1. 定义基础模型与枚举

先统一共用的问题模型和样式枚举:

public enum QuestionStyle
{
    TextInput,
    Dropdown,
    CheckboxGroup
}

public class Question
{
    public int Id { get; set; }
    public string Title { get; set; }
    public QuestionStyle Style { get; set; }
    // 其他通用属性根据需求添加
}

2. 创建组件统一接口

定义接口确保所有问题组件遵循相同的参数规范:

public interface IQuestionComponent
{
    Question Question { get; set; }
}

3. 实现自定义组件

每个组件继承ComponentBase并实现上述接口,以文本输入组件为例:

@inherits ComponentBase
@implements IQuestionComponent

<div class="text-input-question">
    <label>@Question.Title</label>
    <input type="text" />
</div>

@code {
    [Parameter]
    public Question Question { get; set; }
}

Dropdown、CheckboxGroup等组件按相同结构实现,保证[Parameter]属性与接口一致。

4. 实现组件工厂类

工厂负责维护样式与组件类型的映射,支持动态扩展:

public class QuestionComponentFactory
{
    private readonly Dictionary<QuestionStyle, Type> _componentMap = new();

    public QuestionComponentFactory()
    {
        // 初始化注册现有组件
        _componentMap.Add(QuestionStyle.TextInput, typeof(TextInputComponent));
        _componentMap.Add(QuestionStyle.Dropdown, typeof(DropdownComponent));
        _componentMap.Add(QuestionStyle.CheckboxGroup, typeof(CheckboxGroupComponent));
    }

    // 提供扩展方法,新增组件时直接注册
    public void RegisterComponent(QuestionStyle style, Type componentType)
    {
        if (_componentMap.ContainsKey(style))
            _componentMap[style] = componentType;
        else
            _componentMap.Add(style, componentType);
    }

    // 根据问题获取对应组件类型
    public Type GetComponentType(Question question)
    {
        if (_componentMap.TryGetValue(question.Style, out var type))
            return type;
        
        // 找不到对应样式时返回默认组件(可根据需求调整)
        return typeof(TextInputComponent);
    }
}

在Program.cs中将工厂注册为单例:

builder.Services.AddSingleton<QuestionComponentFactory>();

5. 页面动态渲染组件

在主页面注入工厂,通过DynamicComponent(.NET 6+支持)动态渲染组件:

@inject QuestionComponentFactory ComponentFactory
@foreach (var question in Questions)
{
    <DynamicComponent 
        Type="ComponentFactory.GetComponentType(question)" 
        Parameters="new Dictionary<string, object> { { nameof(IQuestionComponent.Question), question } }" />
}

@code {
    [Parameter]
    public List<Question> Questions { get; set; } = new();
}

扩展新组件的方式

当需要新增一种问题样式(比如日期选择器):

  1. 创建DatePickerComponent,实现IQuestionComponent接口
  2. 在Program.cs中注册映射:
var factory = app.Services.GetRequiredService<QuestionComponentFactory>();
factory.RegisterComponent(QuestionStyle.DatePicker, typeof(DatePickerComponent));

全程无需修改主页面或工厂核心代码,完全符合开闭原则。

内容的提问来源于stack exchange,提问作者maikson mendes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 10:48:22