首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 應用程式框架設計:樣板方法模式與擴充點實作

     編輯:關於C#

前言

應用程式框架定義演算法骨架,將可變步驟延遲到子類別實作。本文示範以樣板方法模式建構可擴充的框架基底,包含初始化、執行、銷毀生命週期,並探討現代框架設計演進 (DI、中介軟體、選項模式)。

核心框架基底類別


using System;

public abstract class ApplicationFramework
{
    // 樣板方法:定義演算法骨架,不可被覆寫 (sealed)
    public sealed void Run()
    {
        try
        {
            OnInitializing();
            OnInitialized();

            OnStarting();
            OnRunning();
            OnStopping();
        }
        finally
        {
            OnDisposing();
            OnDisposed();
        }
    }

    // 擴充點:受保護虛擬方法,子類別可選擇覆寫
    protected virtual void OnInitializing() { }
    protected virtual void OnInitialized() { }
    protected virtual void OnStarting() { }
    protected virtual void OnRunning() { }      // 核心邏輯進入點
    protected virtual void OnStopping() { }
    protected virtual void OnDisposing() { }
    protected virtual void OnDisposed() { }
}

具體應用程式實作


public class MyBusinessApp : ApplicationFramework
{
    private ILogger _logger;
    private IConfiguration _config;
    private IServiceProvider _services;

    protected override void OnInitializing()
    {
        Console.WriteLine("[Framework] 初始化配置與服務容器...");
        _config = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .Build();

        var services = new ServiceCollection();
        ConfigureServices(services);
        _services = services.BuildServiceProvider();
        _logger = _services.GetRequiredService>();
    }

    protected override void OnInitialized()
    {
        _logger.LogInformation("服務容器建立完成");
    }

    protected override void OnStarting()
    {
        _logger.LogInformation("應用程式啟動中...");
        // 啟動背景服務、連接資料庫、開啟網路埠等
    }

    protected override void OnRunning()
    {
        _logger.LogInformation("進入主迴圈...");
        // 這裡可以是:
        // - Console 選單迴圈
        // - Windows Forms Application.Run()
        // - ASP.NET Core WebApplication.Run()
        // - gRPC 服務啟動
        
        // 範例:簡單主迴圈
        bool running = true;
        while (running)
        {
            Console.Write("> ");
            var input = Console.ReadLine();
            if (input?.ToLower() == "exit") running = false;
            else ProcessCommand(input);
        }
    }

    protected override void OnStopping()
    {
        _logger.LogInformation("正在關閉...");
        // 釋放資源、儲存狀態
    }

    protected override void OnDisposing()
    {
        (_services as IDisposable)?.Dispose();
    }

    private void ConfigureServices(IServiceCollection services)
    {
        services.AddLogging(b => b.AddConsole());
        services.AddTransient();
        // 註冊其他服務...
    }

    private void ProcessCommand(string cmd)
    {
        // 委派給服務處理
        var svc = _services.GetRequiredService();
        svc.Handle(cmd);
    }
}

進階框架特性

1. 依賴注入整合

框架基底提供 IServiceProvider 存取,子類別在 OnInitializing 註冊服務,OnDisposing 釋放容器。

2. 選項模式配置


public class AppOptions
{
    public string ConnectionString { get; set; }
    public int MaxRetry { get; set; } = 3;
}

// 在 OnInitializing
services.Configure(_config.GetSection("App"));
// 使用
var options = _services.GetRequiredService>().Value;

3. 中介軟體管線 (類 ASP.NET Core)


public delegate Task MiddlewareDelegate(Context ctx, Func next);

public class PipelineFramework : ApplicationFramework
{
    private readonly List _middlewares = new();

    public void Use(MiddlewareDelegate middleware) => _middlewares.Add(middleware);

    protected override void OnRunning()
    {
        var context = new Context();
        var pipeline = BuildPipeline();
        pipeline(context).Wait();
    }

    private Func BuildPipeline()
    {
        Func end = ctx => Task.CompletedTask;
        for (int i = _middlewares.Count - 1; i >= 0; i--)
        {
            var next = end;
            var mw = _middlewares[i];
            end = ctx => mw(ctx, next);
        }
        return end;
    }
}

// 使用
var app = new PipelineFramework();
app.Use(async (ctx, next) => { Console.WriteLine("Middleware 1 前"); await next(); Console.WriteLine("Middleware 1 後"); });
app.Use(async (ctx, next) => { Console.WriteLine("Middleware 2 前"); await next(); Console.WriteLine("Middleware 2 後"); });
app.Run();

4. 外掛模組載入


protected override void OnInitializing()
{
    base.OnInitializing();
    LoadPlugins();
}

private void LoadPlugins()
{
    var pluginDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
    foreach (var dll in Directory.GetFiles(pluginDir, "*.dll"))
    {
        var asm = Assembly.LoadFrom(dll);
        foreach (var type in asm.GetTypes())
        {
            if (typeof(IModule).IsAssignableFrom(type) && !type.IsAbstract)
            {
                var module = (IModule)Activator.CreateInstance(type);
                module.Initialize(_services);
                _modules.Add(module);
            }
        }
    }
}

現代框架比較:Generic Host (Microsoft.Extensions.Hosting)

實際專案建議直接使用 .NET 內建 IHost,已實作完整生命週期、DI、配置、日誌、優雅關閉:


using Microsoft.Extensions.Hosting;

public class Program
{
    public static async Task Main(string[] args)
    {
        var host = Host.CreateDefaultBuilder(args)
            .ConfigureServices((ctx, services) =>
            {
                services.AddHostedService();
                services.AddTransient();
            })
            .Build();

        await host.RunAsync(); // 封裝了完整生命週期
    }
}

public class WorkerService : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            // 背景工作
            await Task.Delay(1000, stoppingToken);
        }
    }
}

總結

樣板方法模式提供框架的基本骨架:定義流程、延遲實作。關鍵點:

  • 樣板方法標記 sealed 防止破壞流程
  • 擴充點採用 protected virtual,預設空實作
  • 生命週期明確:Initializing → Initialized → Starting → Running → Stopping → Disposing → Disposed
  • 現代框架整合 DI、配置、日誌、中介軟體、外掛系統
  • 生產環境優先使用 Microsoft.Extensions.Hosting (Generic Host)

良好的框架設計能強制統一架構、降低樣板代碼、提升團隊開發效率。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved