使用 Scrutor 快速實現“裝飾者模式”

裝飾者模式介紹

裝飾器模式(Decorator Pattern)是在不改變原類和使用繼承的情況下,動態地給一個對象添加一些額外的職責。它是通過創建一個包裝對象,也就是裝飾來包裹真實的對象。

可以在如下使用場景中使用裝飾器模式:

  • 在不影響其他對象的情況下,以動態、透明的方式給單個對象添加職責。

  • 需要動態地給一個對象增加功能,這些功能也可以動態地被撤銷。

  • 當不能采用繼承的方式對系統進行擴充或者采用繼承不利于系統擴展和維護時。

Demo

假設,我們使用IRepository接口的實現類Repository進行數據庫訪問:

public?interface?IUserRepository
{User?Get(int?Id);
}public?class?UserRepository?:?IUserRepository
{public?User?Get(int?Id){Console.WriteLine("訪問數據庫");//模擬數據庫訪問return?new?User(Id,?"My?IO");}
}

現在有一個新的需求:要求增加緩存功能,即先從緩存獲取數據,緩存不存在再訪問數據庫。

有幾種方法可以做到這一點:

  1. 修改業務邏輯,在訪問Get前讀取緩存;

  2. 使用面向切面(AOP)模式,在調用Get方法時注入讀取緩存邏輯;

  3. 修改UserRepository實現緩存功能;

  4. 繼承UserRepository類,在派生類中實現緩存功能;

  5. 使用裝飾器模式封裝UserRepository類,在新的UserRepositoryDecorator類中嵌入實現緩存功能;

在這里,我們使用裝飾器模式:

internal?class?UserRepositoryCacheDecorator?:?IUserRepository
{private?readonly?IUserRepository?_userRepository;public?UserRepositoryCacheDecorator(IUserRepository?userRepository){_userRepository?=?userRepository;}public?User?Get(int?Id){Console.WriteLine("訪問緩存");return?_userRepository.Get(Id);}
}
  • 首先,我們還是實現與UserRepository類相同的IUserRepository接口;

  • 其次,我們將IUserRepository接口注入到構造函數中;

  • 最后,在Get方法中,我們再次調用注入的接口的Get方法,它應該調用UserRepository類的實現。

顯然,如果還是按普通方式進行依賴注入,將不可能成功:

builder.Services.AddTransient<IUserRepository,?UserRepository>();builder.Services.AddTransient<IUserRepository,?UserRepositoryCacheDecorator>();

d85cd4879d85791e3d69299ea4272846.png

這時,我們可以引用 Nuget 包Scrutor,然后使用它提供的Decorate方法:

builder.Services.AddTransient<IUserRepository,?UserRepository>();builder.Services.Decorate<IUserRepository,?UserRepositoryCacheDecorator>();

現在再運行,你將看到裝飾器模式已經實現了:

3d66247eeba99001cdaf4b765e8b67dd.png

結論

可以添加多個裝飾,為原來的功能增加不同的職責,而僅需的操作,就是調用Decorate方法進行注冊:

builder.Services.Decorate<IUserRepository,?UserRepositoryCacheDecorator>();builder.Services.Decorate<IUserRepository,?UserRepositoryLogDecorator>();

添加微信號【MyIO666】,邀你加入技術交流群

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

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

相關文章

各個 Android Gradle 插件版本所需的 Gradle 版本

下表列出了各個 Android Gradle 插件版本所需的 Gradle 版本。 要獲得最佳性能&#xff0c;您應該使用 Gradle 和插件這兩者的最新版本。 插件版本所需的 Gradle 版本1.0.0 - 1.1.32.2.1 - 2.31.2.0 - 1.3.12.2.1 - 2.91.5.02.2.1 - 2.132.0.0 - 2.1.22.10 - 2.132.1.3 - 2.2…

JS時間戳和時間互轉

https://www.cnblogs.com/nield-bky/p/6040853.html http://blog.csdn.net/csdn565973850/article/details/73838583 時間轉時間戳&#xff1a; javascript獲得時間戳的方法有四種&#xff0c;都是通過實例化時間對象 new Date() 來進一步獲取當前的時間戳1.var timestamp1 Da…

C語言試題157之從鍵盤輸入一個字符串,將小寫字母全部轉換成大寫字母,然后輸出到一個磁盤文件“test”中保存。 輸入的字符串以!結束

??個人主頁:個人主頁 ??系列專欄:C語言試題200例 ??推薦一款模擬面試、刷題神器?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 題目:從鍵盤輸入一個字符串,將小…

【ArcGIS微課1000例】0001:添加XY數據(Add XY data)生成shp

用過CASS的人都知道&#xff0c;野外數字測圖得到的點數據&#xff08;平面坐標&#xff09;可以直接在CASS中展點&#xff0c;進一步繪制地形圖。那么&#xff0c;帶有坐標的數據能不能在ArcGIS中實現點圖層的生成呢&#xff1f;答案是必須的&#xff01; 本文以氣象臺站Excel…

算法導論--廣度優先搜索和深度優先搜索

廣度優先搜索 在給定圖G(V,E)和一個特定的源頂點s的情況下&#xff0c;廣度優先搜索系統地探索G中的邊&#xff0c;以期“發現”可從s 到達的所有頂點&#xff0c;并計算s 到所有這些可達頂點之間的距離&#xff08;即最少的邊數&#xff09;。該搜索算法同時還能生成一棵根為s…

動手學 docker

背景動手學 docker最近&#xff0c;終于完成了 動手學 docker 系列的編寫。動手學 docker 是 動手學系列 的首個系列。如果反饋的效果不錯&#xff0c;后續還將推出 動手學 devops動手學 kubernetes動手學 istio 等系列。動手學系列 的構思來源于 李沐 老師的 動手學深度學習 。…

Linux零基礎入學之1-1課程介紹了解RHEL7安裝RHEL7

【本節內容】* 課程介紹* RHEL7了解* RHEL7.2的安裝* 實戰&#xff1a;組裝服務器【Linux介紹】服務器種類&#xff1a;刀片式、塔式&#xff08;機架式&#xff09;1U&#xff1a;4.45cm 三指寬 指服務器的高度貝爾實驗室 Unix 肯湯普森 & 丹尼斯里奇二人合作用…

【ArcGIS微課1000例】0003:按屬性選擇(Select by Attributes)

在使用ArcGIS時,可以使用 SQL 表達式基于要素屬性來選擇要素。 通過按屬性選擇 對話框可為 SQL 表達式定義一個或多個由屬性、運算符和計算構成的條件。給定圖層上生成的要素選擇內容滿足這些條件。 文章目錄 按屬性選擇工具1. 工具箱→按屬性選擇圖層2. 菜單欄→按屬性選擇3.…

[轉]Android 常見安全漏洞修復理論與實踐

前言 前段時間公司對應用在愛加密上進行了安全掃描&#xff0c;本文將基于愛加密的漏洞分析報告&#xff0c;針對部分內容&#xff0c;介紹理論修復實踐 最小化特權準則概念介紹 最小化特權準則&#xff0c;即指組件只能供自身應用調用&#xff0c;盡可能禁止其他應用訪問及…

C語言試題158之從鍵盤輸入一些字符,逐個把它們送到磁盤上去,直到輸入一個#為止。

??個人主頁:個人主頁 ??系列專欄:C語言試題200例 ??推薦一款模擬面試、刷題神器?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 題目:從鍵盤輸入一些字符,逐個把…

html5--3.2 input元素(1)

html5--3.2 input元素(1) 學習要點 input元素及其屬性input元素 用來設置表單中的內容項&#xff0c;比如輸入內容的文本框&#xff0c;按鈕等不僅可以布置在表單中&#xff0c;也可以在表單之外的元素使用input元素的屬性 type屬性&#xff1a;指定輸入內容的類型&#xff0c;…

css3 3D

● css3 3D旋轉 ○ rotateX() 方法&#xff0c;元素圍繞其 X 軸以給定的度數進行旋轉 ○ rotateY() 方法&#xff0c;元素圍繞其 Y 軸以給定的度數進行旋轉 ○ rotateZ(angle)&#xff0c;定義沿 Z 軸的 3D 旋轉。 ● 3D景深 ○ perspective(n)&#xff0c;景深&#xff0c;離屏…

我是怎么自學 Git / GitHub 的?

大家好我是魚皮&#xff0c;Git 和 GitHub 是如今團隊協作開發必不可少的技能&#xff0c;且不說程序員&#xff0c;就連很多產品也在學習它們。今天分享一下我自學 Git 和 GitHub 的經驗&#xff0c;希望起到一個 導學 的作用&#xff0c;幫助大家抓住重點&#xff0c;節省時間…

[轉]Android 代碼混淆和加固 so庫 簡單教你一行代碼實現

混淆 因為開啟混淆會使編譯時間變長&#xff0c;所以debug模式下不開啟。我們需要做的是&#xff1a; 1.將release下minifyEnabled的值改為true&#xff0c;打開混淆&#xff1b; 2.buildConfigField 不顯示log日志 為什么要混淆&#xff1a; 優化java的字節碼減小apk文件的大…

【ArcGIS微課1000例】0004:值提取至點(Extract value to point)

文章目錄 問題描述值提取至點工具介紹案例實現過程注意事項問題描述 研究區分布有成千上萬個離散的矢量點(根據范圍創建隨機點),但是點上沒有高程值,研究區DEM是有的,那么怎樣在ArcGIS中提取每個點對應的高程值? 離散點分布情況: DEM數據(ArcGlobe中三維顯示):

C語言試題159之計算字符串中子串出現的次數

??個人主頁:個人主頁 ??系列專欄:C語言試題200例 ??推薦一款模擬面試、刷題神器?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 題目:兩個字符串連接程序 2 、溫馨…

關于Android studio找不到sqlite數據庫的解決方法

打開Android Device Monitor,剩下的與Eclipse相同。轉載于:https://blog.51cto.com/10237758/1761397

linux ubuntu deepin apache2 rewrite

2019獨角獸企業重金招聘Python工程師標準>>> apache php 環境裝好了&#xff0c;下載了TP5的項目&#xff0c;然后部署上去之后&#xff0c;端口81&#xff0c;&#xff0c;但是 訪問 127.0.0.1:81 正常 127.0.0.1:81/admin&#xff0c;報錯 404 Not Found 原因是,…

論DATASNAP遠程方法支持自定義對象作參數

論DATASNAP遠程方法支持自定義對象作參數 DATASNAP遠程方法已經可以支持自定義對象作參數&#xff0c;這是非常方便的功能。 1&#xff09;自定義對象 type TMyInfo class(TObject) public AccountNo: string; SQL: string; Params: string; end; 2&#xff09;遠程方法定義 f…

[轉]Android-Proguard(代碼混淆)

一&#xff1a;混淆是什么&#xff0c;該怎么做&#xff1f; 如果我們的app正常發布就必須要經歷混淆這一步&#xff0c;混淆可以使我們的app不那么容易被別人用反編譯工具破解&#xff0c;就算被破解&#xff0c;想要讀懂我們的源碼也是非常費勁的&#xff0c;因為混淆過的源碼…