使用 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.mzph.cn/news/285167.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

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 肯汤普森 & 丹尼斯里奇二人合作用…

[转]Android 常见安全漏洞修复理论与实践

前言 前段时间公司对应用在爱加密上进行了安全扫描&#xff0c;本文将基于爱加密的漏洞分析报告&#xff0c;针对部分内容&#xff0c;介绍理论修复实践 最小化特权准则概念介绍 最小化特权准则&#xff0c;即指组件只能供自身应用调用&#xff0c;尽可能禁止其他应用访问及…

C语言试题158之从键盘输入一些字符,逐个把它们送到磁盘上去,直到输入一个#为止。

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:从键盘输入一些字符,逐个把…

我是怎么自学 Git / GitHub 的?

大家好我是鱼皮&#xff0c;Git 和 GitHub 是如今团队协作开发必不可少的技能&#xff0c;且不说程序员&#xff0c;就连很多产品也在学习它们。今天分享一下我自学 Git 和 GitHub 的经验&#xff0c;希望起到一个 导学 的作用&#xff0c;帮助大家抓住重点&#xff0c;节省时间…

【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 原因是,…

[转]Android-Proguard(代码混淆)

一&#xff1a;混淆是什么&#xff0c;该怎么做&#xff1f; 如果我们的app正常发布就必须要经历混淆这一步&#xff0c;混淆可以使我们的app不那么容易被别人用反编译工具破解&#xff0c;就算被破解&#xff0c;想要读懂我们的源码也是非常费劲的&#xff0c;因为混淆过的源码…

学妹,你要的C语言版AOE网络数据结构来了,就这么简单!

文章目录AOE关键路径编程AOE完整求解程序AOE关键路径编程 不难发现AOE图最大特点是没有回路&#xff0c;并且有向图方向始终是从源点走向汇点&#xff0c;且源点汇点都是一个。 把图1写成邻接矩阵文件&#xff0c;见文件P200G736.TXT&#xff0c;并在此复制G0.C到AOE.C&#x…

C语言试题160之某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下: 每位数字都加上 5,然后用和除以 10 的余数代替该数字,再将第一位和第四位交换,第二位和第三位

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:某个公司采用公用电话传递数…

C# 关于状态机的实现(案例版)

大部分的状态机都是有限状态机&#xff0c;某些业务环境&#xff0c;或者其他环境中&#xff0c;如果有状态机其实还是很方便的。比如&#xff0c;我是用在了单个客户的Socket通信上&#xff0c;未连接状态&#xff0c;我就等连接。已连接状态&#xff0c;就等待下一步指令状态…

[转]Android 项目的代码混淆,Android proguard 使用说明

简介 Java代码是非常容易反编译的。为了很好的保护Java源代码&#xff0c;我们往往会对编译好的class文件进行混淆处理。 ProGuard是一个混淆代码的开源项目。它的主要作用就是混淆&#xff0c;当然它还能对字节码进行缩减体积、优化等&#xff0c;但那些对于我们来说都算是次要…

数据结构与算法:终于可以用三种语言(C,C#,JavaScript)把图的广度优先遍历讲清楚了(推荐收藏)

文章目录邻接矩阵存储图的广度优先遍历过程分析C语言实现队列编程程序中加入图的处理函数结果的再次分析C#语言实现图的广度优先遍历、并显示广度优先遍历生成树JavaScript语言实现图的广度优先遍历、并显示广度优先遍历生成树邻接矩阵存储图的广度优先遍历过程分析 对图1这样…

C语言试题161之求100000以内的自守数

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:自守数是…

改造.NET遗留应用

浅议.NET遗留应用改造TLDR&#xff1a;本文介绍了遗留应用改造中的一些常见问题&#xff0c;并对改造所能开展的目标、原则、策略进行了概述。一、背景概述1、概述或许仅“遗留应用”这个标题就比较吸睛&#xff0c;因为我听过太多人吐槽了。Robert Martin在《修改代码的艺术》…