ASP.NET Core模仿中間件方式實現(xiàn)列表過濾功能
我們的很多功能當中都會遇到對版本進行過濾的場合,例如你可能需要對列表中的數(shù)據(jù)的時間進行過濾、版本過濾、渠道以及地區(qū)信息進行過濾。
原本的做法:設計很多個過濾方法,通過枚舉的方式組合,選擇需要過濾哪些方法,然后一個方法一個方法的調(diào)用。 這樣的做法本身沒什么問題。但是感覺很面向過程,不夠面向對象。

通過學習.Net Core的源碼,我們可以了解到它采用了一種委托鏈表的方式,將所有的中間件都串了起來。所以我想要仿造它這個去實現(xiàn)一下這個功能。
這樣做的好處:抽象出一些過濾的方法,對于不同的系統(tǒng),只要通過Use方法,就可以增加我們的過濾規(guī)則,考慮到不同的系統(tǒng)過濾的規(guī)則不同,這樣做也比較靈活(例如 應用管理系統(tǒng) 需要過濾版本、渠道、地區(qū) ,而黑白名單需要過濾版本、渠道、時間等等,那么對于前者我只需要在過濾的時候 UseVersion UserChannel UseArea, 對于后者把UserArea緩存UseTime即可。)
廢話不多說:上碼
1.定義一個委托類型,承載我們過濾方法
namespace FilterDelegate
{
public delegate IEnumerable<TcySysApplication> TcySysFilterDelegate(IEnumerable<TcySysApplication> applist, TcySysFilterConditionInfo conditionInfo );
}委托的輸入是我們待處理的數(shù)據(jù)列表appList, 以及我們執(zhí)行過濾的條件數(shù)據(jù)。
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.執(zhí)行使用
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中有過濾的邏輯,根據(jù)這個邏輯我們應該只會返回一個Channeld = 88215的數(shù)據(jù)

我們可以將 UseChannelFilter 那句代碼注釋掉,再運行,由于沒有過濾渠道,此時顯示了兩條數(shù)據(jù)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。如果你想了解更多相關內(nèi)容請查看下面相關鏈接
相關文章
看到本質(zhì)而不是現(xiàn)象--解決ASP.NET CS0016的問題
看到本質(zhì)而不是現(xiàn)象--解決ASP.NET CS0016的問題...2007-01-01
ASP.NET MVC中Controller控制器向View視圖傳值的幾種方式
這篇文章介紹了ASP.NET MVC中Controller控制器向View視圖傳值的幾種方式,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-03-03
解決在Web.config或App.config中添加自定義配置的方法詳解
本篇文章是對在Web.config或App.config中添加自定義配置的方法進行了詳細的分析介紹,需要的朋友參考下2013-05-05
WPF實現(xiàn)ScrollViewer滾動到指定控件處
這篇文章主要為大家詳細介紹了WPF實現(xiàn)ScrollViewer滾動到指定控件處,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06
基于localStorge開發(fā)登錄模塊的記住密碼與自動登錄實例
下面小編就為大家?guī)硪黄趌ocalStorge開發(fā)登錄模塊的記住密碼與自動登錄實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08

