C# Attribute 方法擴展

場景
剛寫完一個干凈利落的方法,比如保存數據到數據庫,邏輯清晰、結構優雅,
第二天,“嘿,保存完數據,記得給客戶發個郵件哦~”
第三天,“能不能再發個消息通知其他系統?”
第四天,“能不能記錄一下操作日志?”
第五天,“再加個短信提醒吧。”
……
就這樣,原本清清爽爽的 SaveData 方法,變成了一個臃腫不堪的函數:
我們管這種代碼叫 “腳本代碼”或“面條代碼” —— 邏輯纏在一起,改一處,處處提心吊膽。

C# 提供了更靈活的方式來處理這種場景,那就是利用 Attribute 來對業務進行解耦,從而避免這種腳本式的代碼,提高代碼的可擴展性

1. 定義特性

namespace WebApplication2.Attributes
{/// <summary>/// https://mp.weixin.qq.com/s/Sd9q7FOTlk29wBknNQh87w/// 后置操作特性基類/// 所有繼承它的特性都可以用在方法上,允許多個,不繼承到子類/// </summary>[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)]public abstract class PostOperationAttribute : Attribute{// 每個后置操作都必須實現 Execute 方法public abstract void Execute(object returnValue);}/// <summary>/// 發送郵件特性/// </summary>public class SendEmailAttribute : PostOperationAttribute{private readonly string _emailTemplate; // 郵件模板名稱// 構造函數接收模板名public SendEmailAttribute(string emailTemplate){_emailTemplate = emailTemplate;}// 實現具體的發送郵件邏輯public override void Execute(object returnValue){// 實際項目中這里應該調用郵件服務Console.WriteLine($"發送郵件 - 使用模板:?{_emailTemplate}");Console.WriteLine($"郵件內容包含數據:?{returnValue}");}}/// <summary>/// 發送消息特性/// </summary>public class SendMessageAttribute : PostOperationAttribute{private readonly string _messageType; // 消息類型public SendMessageAttribute(string messageType){_messageType = messageType;}public override void Execute(object returnValue){Console.WriteLine($"發送?{_messageType}?消息");Console.WriteLine($"消息內容包含數據:?{returnValue}");}}
}

2. 編寫業務方法

using System.Reflection;namespace WebApplication2.Attributes
{public class DataService{/// <summary>/// 核心邏輯只負責保存數據/// 使用特性標記需要后置處理的方法/// </summary>/// <param name="data"></param>/// <returns></returns>[SendEmail("DataSavedTemplate")][SendMessage("Notification")]public virtual int SaveData(string data){// 這里只關注保存數據的核心業務邏輯Console.WriteLine($"保存數據:?{data}");// 模擬返回保存后的IDreturn new Random().Next(1000);}}
}

3. 創建攔截類(代理)

using System.Reflection;namespace WebApplication2.Attributes
{/// <summary>/// 自動處理 Attribute 的代理類/// </summary>public class DataServiceProxy : DataService{public override int SaveData(string data){// 調用基類方法var result = base.SaveData(data);// 獲取方法信息MethodInfo methodInfo = typeof(DataService).GetMethod("SaveData");// 獲取該方法上所有的 PostOperationAttribute 特性實例var postOps = methodInfo.GetCustomAttributes<PostOperationAttribute>(true);// 遍歷并執行每一個后置操作foreach (var op in postOps){op.Execute(result);}return result;}}
}

4. 使用

using Microsoft.AspNetCore.Mvc;
using WebApplication2.Attributes;namespace WebApplication2.Controllers
{[Route("api/Attributes/[action]")][ApiController]public class AttributesController : ControllerBase{[HttpGet]public string Test(){// 使用代理類而不是直接使用DataServicevar dataService = new DataServiceProxy();// 直接調用方法,后置操作會自動執行int savedId = dataService.SaveData("測試數據");Console.WriteLine($"保存成功,ID:?{savedId}");return "";}}
}

5. 運行和測試

6.總結
● 核心業務方法不再被新增加的業務需求污染
● 擴展功能就像搭積木一樣快捷方便
● 新增功能無需修改原有代碼,維護成本大大降低
● 一眼就能看出某個方法執行后會觸發哪些操作,代碼可讀性更強

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/93925.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/93925.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/93925.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【URP】[法線貼圖]為什么主要是藍色的?

【從UnityURP開始探索游戲渲染】專欄-直達 法線貼圖呈現藍紫色調&#xff08;尤其以藍色為主&#xff09;是由其?存儲原理、切線空間坐標系設計及顏色編碼規則共同決定的?。 核心原因&#xff1a;法線向量的存儲規則? ?法線向量的物理范圍? 法線是單位向量&#xff0c;…

驅動開發系列63 - NVIDIA 開源GPU驅動open-gpu-kernel-modules編譯調試

目錄 一:通過apt方式安裝nvidia 驅動 二:通過 .run 方式安裝nvidia驅動 三:編譯安裝nvidia開源內核驅動 四:驗證和調試 五:卸載驅動 1. 以apt方式安裝nvidia 驅動的卸載方法 2. 以.run方式安裝nvidia驅動的卸載方法 六:安裝CUDA環境 一:通過apt方式安裝nvidia 驅動…

對KingbaseES架構的解析:從讀寫分離到異地災備的技術實現與保障機制

聲明&#xff1a;文章為本人真實測評博客&#xff0c;非廣告&#xff0c;并沒有推廣該平臺 &#xff0c;為用戶體驗文章 本人旨在分享最真實的用戶體驗&#xff0c;為關注此類產品的朋友們提供一個客觀的參考。 文章目錄一、架構全景&#xff1a;四級高可用構建數字基礎1.1 物…

Visual Studio中的常用調試功能(上)

1、利用斷點進行調試添加斷點的方式有以下幾種1.鍵盤快捷鍵F92.通過菜單【Debug&#xff08;調試&#xff09;】-》【Toggle BreakPoint&#xff08;切換斷點&#xff09;】3.點擊代碼行左邊的空白處&#xff08;推薦&#xff09;設置斷點后&#xff0c;按F5運行程序&#xff0…

Linux -- 線程同步

1.1條件變量 (1)當?個線程互斥地訪問某個變量時&#xff0c;它可能發現在其它線程改變狀態之前&#xff0c;它什么也做不了。 (2)例如?個線程訪問隊列時&#xff0c;發現隊列為空&#xff0c;它只能等待&#xff0c;只到其它線程將?個節點添加到隊列 中。這種情況就需要?到…

前端進階指南:JavaScript性能優化實戰全解析

深入剖析 JavaScript 性能瓶頸&#xff0c;分享優化技巧與最佳實踐&#xff0c;讓你的前端應用更快、更穩、更流暢。 &#x1f4d1; 目錄 一、前言 二、性能瓶頸的常見來源 三、JavaScript代碼優化技巧 1. 避免重復計算 2. 合理使用防抖與節流 3. 使用事件委托 四、渲染…

RabbitMQ:SpringAMQP Direct Exchange(直連型交換機)

目錄一、案例需求二、基礎配置三、代碼實現直連型交換機也叫做定向交換機&#xff0c;通過RoutingKey綁定交換機與隊列直接的關系。 生產者源碼 消費者源碼 一、案例需求 在RabbitMQ控制臺中&#xff0c;聲明隊列direct.queue1和direct.queue2。在RabbitMQ控制臺中&#xff…

implement libtime on Windows

因為Windows的time命令和Linux的time命令不一樣&#xff0c;嘗試實現libtime libtime.h /** libtime.h - 跨平臺時間測量庫* 功能&#xff1a;執行外部命令并測量其運行時間和資源使用*/#ifndef LIBTIME_H #define LIBTIME_H#include <stdio.h> #include <stdlib.h>…

Unity進階--C#補充知識點--【C#各版本的新功能新語法】C#1~4與C#5

來源于唐老獅的視頻教學&#xff0c;僅作記錄和感悟記錄&#xff0c;方便日后復習或者查找 一.C#版本與Unity的關系 1.各Unity版本支持的C#版本 更多信息可以在Untiy官網說明查看 https://docs.unity3d.com/2020.3/Documentation/Manual/CSharpCompiler.html&#xff08;這個好…

水閘安全綜合監測系統解決方案

一、方案概述 水閘作為重要的水利工程設施&#xff0c;承擔著防洪、排澇、供水和灌溉等關鍵功能。其安全性直接關系到下游人民群眾的生命財產安全以及區域經濟的穩定發展。近年來&#xff0c;隨著極端天氣頻發和工程老化問題日益突出&#xff0c;水閘安全監測工作顯得尤為重要。…

基于單片機智能點滴輸液系統

傳送門 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目速選一覽表 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目功能速覽 概述 該系統基于單片機控制技術&#xff0c;結合傳感器和無線通信模塊&#xff0c;實現對輸液過程的實…

AI數據倉庫管理提升效率

內容概要在數字化轉型浪潮中&#xff0c;AI數據倉庫管理正重塑企業數據處理格局。本部分簡要介紹其核心機制&#xff0c;即通過智能API接入外部數據源實現多平臺數據無縫整合&#xff0c;隨后應用數據清洗技術去除冗余信息&#xff0c;確保數據質量。同時&#xff0c;加密存儲機…

使用 Docker 安裝長安鏈管理平臺 + 部署區塊鏈與示例合約

文章目錄簡介登錄官網GithubPodman 配置&#xff08;Docker 配置 registry 地址&#xff09;安裝長安鏈管理平臺下載源碼docker-compose.yml登錄管理平臺部署區塊鏈Dockerfile構建鏡像部署長安鏈訂閱區塊鏈部署合約下載示例合約部署示例合約投票管理文件哈希存證查找存證信息區…

Python訓練營打卡 DAY 41 簡單CNN

知識回顧 數據增強卷積神經網絡定義的寫法batch歸一化&#xff1a;調整一個批次的分布&#xff0c;常用與圖像數據特征圖&#xff1a;只有卷積操作輸出的才叫特征圖調度器&#xff1a;直接修改基礎學習率 卷積操作常見流程如下&#xff1a; 1. 輸入 → 卷積層 → Batch歸一化層…

云端賦能,智慧運維:分布式光伏電站一體化監控平臺研究

摘要 本文針對分布式光伏電站存在的監管困難、火災隱患、系統繁雜及運維不規范等行業痛點&#xff0c;提出AcrelCloud-1200光伏運維云平臺解決方案。平臺通過ANet-1E2S-4G網關集成多品牌逆變器數據&#xff0c;結合視頻監控與氣象站&#xff0c;實現電站全域監測&#xff1b;開…

CVPR 2025 | 具身智能 | HOLODECK:一句話召喚3D世界,智能體的“元宇宙練功房”來了

關注gongzhonghao【CVPR頂會精選】1.導讀1.1 論文基本信息論文標題&#xff1a;《HOLODECK: Language Guided Generation of 3D Embodied AI Environments》作者&#xff1a;Yue Yang*1, Fan-Yun Sun*2, Luca Weihs*4, Eli Vanderbilt4, Alvaro Herrasti4,Winson Han4, Jiajun …

迅為RK3568開發板搭建Ubuntu環境

本小節介紹開發所需 Ubuntu 環境的搭建方法。系統要求:Ubuntu 系統要求&#xff1a;Ubuntu18.04~21.10 版本。推薦使用 20.04 版本&#xff0c;內存 16GB 及以上&#xff0c;硬盤 100GB 及以上。Ubuntu 系統的用戶名不能包含中文字符。建議 Ubuntu 和 Windows 系統上安裝的 Dev…

【數據結構】用堆解決TOPK問題

設計一個算法&#xff0c;找出數組中最小的k個數。以任意順序返回這k個數均可。示例&#xff1a;輸入&#xff1a; arr [1,3,5,7,2,4,6,8], k 4 輸出&#xff1a; [1,2,3,4]比較替換堆頂的數時&#xff0c;不需要讓堆頂與數組的每一個數再進行比較&#xff0c;比較數組減去k個…

【深度長文】Anthropic發布Prompt Engineering全新指南

目錄 1.什么時候適合用提示工程? 2.如何進行提示工程 2.1 使用提示模板 2.1.1 使用提示模板和變量 2.1.2 何時使用提示模板和變量 2.1.3 提示模板示例 2.2 保持清晰和直接 2.2.1 如何保持清晰、具有上下文和具體 2.2.2 示例 ?2.3 使用示例&#xff08;多示例提示…

【基礎-判斷】HarmonyOS提供了基礎的應用加固安全能力,包括混淆、加密和代碼簽名能力

正確 解釋如下: 應用加固: 這是指對應用程序進行保護,使其更難被逆向工程、篡改或盜版。HarmonyOS 作為現代操作系統,確實提供了這樣的基礎安全能力。 混淆: HarmonyOS 的 SDK 提供了代碼混淆工具(通常基于 ProGuard 或類似技術)。開發者在構建應用時啟用混淆,可以將類…