模仿DotnetCore中间件的方式,做一个列表过滤的功能
我们的很多功能当中都会遇到对版本进行过滤的场合,例如你可能需要对列表中的数据的时间进行过滤、版本过滤、渠道以及地区信息进行过滤。
原本的做法:设计很多个过滤方法,通过枚举的方式组合,选择需要过滤哪些方法,然后一个方法一个方法的调用。 这样的做法本身没什么问题。但是感觉很面向过程,不够面向对象。

通过学习.Net Core的源码,我们可以了解到它采用了一种委托链表的方式,将所有的中间件都串了起来。所以我想要仿造它这个去实现一下这个功能。
这样做的好处:抽象出一些过滤的方法,对于不同的系统,只要通过Use方法,就可以增加我们的过滤规则,考虑到不同的系统过滤的规则不同,这样做也比较灵活(例如 应用管理系统 需要过滤版本、渠道、地区 ,而黑白名单需要过滤版本、渠道、时间等等,那么对于前者我只需要在过滤的时候 UseVersion UserChannel UseArea, 对于后者把UserArea缓存UseTime即可。)
废话不多说:上码
1.定义一个委托类型,承载我们过滤方法
namespace FilterDelegate
{
public delegate IEnumerable<TcySysApplication> TcySysFilterDelegate(IEnumerable<TcySysApplication> applist, TcySysFilterConditionInfo conditionInfo );
}
委托的输入是我们待处理的数据列表appList, 以及我们执行过滤的条件数据。
2.定义一个Builder类,主要用于构建我们整个过滤器,里面主要有两个方法Use方法以及Build方法,Use方法主要用于往我们的委托列表里面增加过滤委托,Build方法主要用于生成最后的过滤器
private readonly IList<Func<TcySysFilterDelegate, TcySysFilterDelegate>> _components = new List<Func<TcySysFilterDelegate, TcySysFilterDelegate>>(); public TcySysFilterBuilder()
{ } public TcySysFilterBuilder Use(Func<TcySysFilterDelegate, TcySysFilterDelegate> filterItem)
{
_components.Add(filterItem);
return this;
} public TcySysFilterDelegate Build()
{
TcySysFilterDelegate last = (applist,filterInfo) =>
{
Console.WriteLine("过滤完成");
return applist;
}; foreach (var component in _components.Reverse())
{
last = component(last);
} return last;
}
3.定义一堆过滤方法,这里没有写具体的逻辑,每一个方法都是通过Builder.Use将委托加入到委托链中
public static TcySysFilterBuilder UseTimeFilter(this TcySysFilterBuilder builder)
{
return builder.Use(next =>
{
return (list, filterInfo) =>
{
Console.WriteLine("我是时间过滤");
return next(list, filterInfo);
};
});
} public static TcySysFilterBuilder UseChannelFilter(this TcySysFilterBuilder builder)
{
return builder.Use(next =>
{
return (list, filterInfo) =>
{
Console.WriteLine("我是渠道过滤"); list = list.Where(x => x.ChannelId != filterInfo.ChannelId); return next(list, filterInfo);
};
});
} public static TcySysFilterBuilder UseVersionFilter(this TcySysFilterBuilder builder)
{
return builder.Use(next =>
{
return (list, filterInfo) =>
{
Console.WriteLine("我是版本过滤");
return next(list, filterInfo);
};
});
}
4.其他类型
public class TcySysApplication
{
public long AppId { set; get; }
public string Name { set; get; }
public long ChannelId { set; get; }
public long Version { set; get; }
public string Province { set; get; }
public string City { set; get; }
public string District { set; get; }
} public class TcySysFilterConditionInfo
{
public long ChannelId { set; get; }
public long Version { set; get; }
public string Province { set; get; }
public string City { set; get; }
public string District { set; get; }
}
5.执行使用
class Program
{
static void Main(string[] args)
{
var sourceList = new List<TcySysApplication>(); sourceList.Add(new TcySysApplication {
AppId =1000,
ChannelId = 88215,
District = "",
City = "乌鲁木齐",
Province = "新疆",
Name ="爱玩不玩",
Version = 10001
}); sourceList.Add(new TcySysApplication
{
AppId = 1001,
ChannelId = 310200,
District = "",
City = "乌鲁木齐",
Province = "新疆",
Name = "爱玩不玩2",
Version = 10002
}); var filterInfo = new TcySysFilterConditionInfo
{
ChannelId = 310200,
District = "",
City = "北京",
Province = "北京",
Version = 10002
}; var builder = new TcySysFilterBuilder(); builder.UseTimeFilter()
.UseChannelFilter()
.UseVersionFilter(); var filter = builder.Build(); var result = filter(sourceList, filterInfo); foreach (var item in result)
{
Console.WriteLine($"AppId={item.AppId} AppName={item.Name} ChannelId={item.ChannelId}");
} Console.ReadKey();
}
}
图上我使用了三种过滤,其中因为Channel中有过滤的逻辑,根据这个逻辑我们应该只会返回一个Channeld = 88215的数据

我们可以将 UseChannelFilter 那句代码注释掉,再运行,由于没有过滤渠道,此时显示了两条数据

模仿DotnetCore中间件的方式,做一个列表过滤的功能的更多相关文章
- 用小程序做一个类似于苹果AssistiveTouch功能
一.首先我先介绍一下,我们要做一个什么样的项目功能 项目功能就是一个音频点击播放,当点击为播放的状态时,一个音频的动图出现,而且是可以跟随着手指的滑动而滑动,而且,在滑动动图的时候,当前下的页面是不可 ...
- SpringBoot2.x整合Email并利用AOP做一个项目异常通知功能
因为不知aop能干嘛,因此用aop做个小功能,再结合最近学的springboot-Email做了个系统异常自动邮件通知的功能, 感觉满满的成就感. AOP不懂的可以看上一篇:https://www.c ...
- QT 创建一个具有复选功能的下拉列表控件
最近研究了好多东西,前两天突然想做一个具有复选功能的下拉列表框.然后在网上"学习"了很久之后,终于发现了一个可以用的,特地发出来记录一下. 一.第一步肯定是先创建一个PROJECT ...
- [转]jsPlumb插件做一个模仿viso的可拖拉流程图
原贴:https://www.cnblogs.com/sggx/p/3836432.html 前言 这是我第一次写博客,心情还是有点小小的激动!这次主要分享的是用jsPlumb,做一个可以给用户自定义 ...
- react实例之todo,做一个实时响应的列表操作
react实例之todo, 做一个实时响应的列表操作 在所有的mvc框架中,最常见的例子不是hello world,而是todo,由于reactjs的简单性,在不引用flux和redux的情况下,我们 ...
- jsPlumb插件做一个模仿viso的可拖拉流程图
前言 这是我第一次写博客,心情还是有点小小的激动!这次主要分享的是用jsPlumb,做一个可以给用户自定义拖拉的流程图,并且可以序列化保存在服务器端. 我在这次的实现上面做得比较粗糙,还有分享我在做j ...
- 启动django应用报错 “Error: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试。”
启动django应用时报如下错误 "Error: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试." 网上查了一下,是8000端口被其他程序占 ...
- apache(OS 10013)以一种访问权限不允许的方式做了一个访问套接字的尝试 ...
今天启动Apache时, 报了“(OS 10013)以一种访问权限不允许的方式做了一个访问套接字的尝试. : make_sock: could not bind to address 0.0.0.0: ...
- HeadFirstPython学习笔记——OSError: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试。
1.文件构成如下 2.运行服务器时报错 OSError: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试. 解决方法:更换端口 3.Python的CGI跟踪术 在 ...
随机推荐
- C#多线程编程实例 线程与窗体交互
C#多线程编程实例 线程与窗体交互 代码: public partial class Form1 : Form { //声明线程数组 Thread[] workThreads = ]; public ...
- git使用安装
下载地址 http://msysgit.github.io/ 配置个人的用户名称和电子邮件地址: $ git config --global user.name "runoob" ...
- [一点感触]ADF4350 ADF4111混频记
几经周折,还是和jack顺利的调完了二者的混频,回想起来我发的上一个版本是2016-11-29,时间可能永远停留在这里了... 祝您一路走好,未来的世界不再忙碌.奔波! 发两张界面纪念吧: 也曾想着把 ...
- rdkafka swoole
1.yum install php-devel php-pear 2. wget http://pear.php.net/go-pear.phar 3.PHP go-pear.phar 4.cp /r ...
- htm5 css学习笔记整理
点击链接后退页面: <a href="javascript:history.go(-1)">回到上一个网页</a> ——修改placeholder提示的样式 ...
- idea使用maven+Tomcat
1.创建maven项目,并使用webapp骨架,并修改pom.xml文件 <build> <finalName>myWebApp</finalName> <! ...
- 开始使用 Ubuntu(字体渲染去模糊+软件安装+优化配置+常见错误)(29)
1. 中文字体渲染美化 + 去模糊 步骤: 1. 解压安装 lulinux_fontsConf_181226.tar.gz,按里面的安装说明操作: 2. 开启字体渲染: 打开 unity-tweak- ...
- 剑指offer13:数组[奇数,偶数],奇数偶数相对位置不变。
1. 题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 2. 思路和方 ...
- 1183: 零起点学算法90——海选女主角(C语言)
一.题目 http://acm.wust.edu.cn/problem.php?id=1183&soj=0 二.分析 从描述来看,就是找出一个二维数组中绝对值最大的数: 带符号的32位整数,刚 ...
- The Preliminary Contest for ICPC Asia Xuzhou 2019 E XKC's basketball team [单调栈上二分]
也许更好的阅读体验 \(\mathcal{Description}\) 给n个数,与一个数m,求\(a_i\)右边最后一个至少比\(a_i\)大\(m\)的数与这个数之间有多少个数 \(2\leq n ...