最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

ASP.NET Core 1.0中的管道-中間件模式

2023-03-12 09:14 作者:吳小敏63  | 我要投稿

ASP.NET Core 1.0借鑒了Katana項目的管道設計(Pipeline)。日志記錄、用戶認證、MVC等模塊都以中間件(Middleware)的方式注冊在管道中。顯而易見這樣的設計非常松耦合并且非常靈活,你可以自己定義任意功能的Middleware注冊在管道中。這一設計非常適用于“請求-響應”這樣的場景——消息從管道頭流入最后反向流出。

在本文中暫且為這種模式起名叫做“管道-中間件(Pipeline-Middleware)”模式吧。

本文將描述”管道-中間件模式”的“契約式”設計和“函數(shù)式”設計兩種方案。

一、什么是管道-中間件模式?

在此模式中抽象了一個類似管道的概念,所有的組件均以中間件的方式注冊在此管道中,當請求進入管道后:中間件依次對請求作出處理,然后從最后一個中間件開始處理響應內容,最終反向流出管道。

二、契約式設計

契約式設計是從面向對象的角度來思考問題,根據管道-中間件的理解,中間件(Middleware)有兩個職責:

1
2
3
4
5
public?interface?IMiddleware
{
????Request ProcessRequest(Request request);
????Response ProcessResponse(Response response);
}

管道(Pipeline)抽象應該能夠注冊中間件(Middleware):

1
2
3
4
5
6
7
8
9
public?interface?IApplicationBuilder
{
?
????void?Use(IMiddleware middleware);
?
????void?UseArrange(List<IMiddleware> middlewares);
?
????Context Run(Context context);
}

實現(xiàn)IApplicationBuilder:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public?class?ApplicationBuilder : IApplicationBuilder
{
????public?IWindsorContainer Container { get; private?set; }
????private?readonly?List<IMiddleware> _middlewares;
?
????public?ApplicationBuilder(IWindsorContainer container)
????{
????????Contract.Requires(container!=null,"container!=null");
?
????????_middlewares=new?List<IMiddleware>();
????????Container = container;
????}
?
????public?void?Use(IMiddleware middleware)
????{
????????Contract.Requires(middleware != null, "middleware!=null");
?
????????_middlewares.Add(middleware);
????}
?
????public?void?UseArrange(List<IMiddleware> middlewares)
????{
????????Contract.Requires(middlewares != null, "middlewares!=null");
?
????????_middlewares.AddRange(middlewares);
????}
?
????public?Context Run(Context context)
????{
????????Contract.Requires(context!=null,"context!=null");
?
????????var?request=context.Request;
????????var?response=context.Response;
?
????????foreach?(var?middleware in?_middlewares)
????????{
????????????request = middleware.ProcessRequest(request);
????????}
?
????????_middlewares.Reverse();
?
????????foreach?(var?middleware in?_middlewares)
????????{
????????????response = middleware.ProcessResponse(response);
????????}
?
????????return?new?Context(request,response);
????}
}

Run()方法將依次枚舉Middleware并對消息的請求和響應進行處理,最后返回最終處理過的消息。

接下來需要實現(xiàn)一個Middleware:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public?class?DefaultMiddleware:IMiddleware
?{
?????public?Request ProcessRequest(Request request)
?????{
?????????request.Process("default request", "processed by defaultMiddleware");
?????????return?request;
?????}
?
?????public?Response ProcessResponse(Response response)
?????{
?????????response.Process("default response", "processed by defaultMiddleware");
?????????return?response;
?????}
?}

為了將Middleware注冊進管道,我們還可以寫一個擴展方法增加代碼的可讀性:

1
2
3
4
5
6
7
8
9
10
11
12
public?static?void?UseDefaultMiddleware(this?IApplicationBuilder applicationBuilder)
{
????applicationBuilder.Use<DefaultMiddleware>();
}
?
public?static?void?Use<TMiddleware>(this?IApplicationBuilder applicationBuilder)
????where?TMiddleware:IMiddleware
{
????var?middleware = applicationBuilder.Container.Resolve<TMiddleware>();
?
????applicationBuilder.Use(middleware);
}

寫個測試看看吧:

寫第二個Middleware:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public?class?GreetingMiddleware:IMiddleware
{
????public?Request ProcessRequest(Request request)
????{
????????request.Process("hello, request","processed by greetingMiddleware");
?
????????return?request;
????}
?
????public?Response ProcessResponse(Response response)
????{
????????response.Process("hello, request", "processed by greetingMiddleware");
?
????????return?response;
????}
}

編寫測試:

三、函數(shù)式設計方案

此方案也是Owin和ASP.NET Core采用的方案,如果站在面向對象的角度,第一個方案是非常清晰的,管道最終通過枚舉所有Middleware來依次處理請求。

站在函數(shù)式的角度來看,Middleware可以用Func<Context, Context>來表示,再來看看這張圖:

一個Middleware的邏輯可以用Func<Func<Context, Context>, Func<Context, Context>>來表示,整個Middleware的邏輯可以用下面的代碼描述:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public?Func<Func<Context, Context>, Func<Context, Context>> Process()
{
????Func<Func<Context, Context>, Func<Context, Context>> middleware = next =>
????{
????????Func<Context, Context> process = context =>
????????{
????????????/*process request*/
???????????
????????????next(context);
?
????????????/*process response*/
?
????????????return?context;
????????};
?
????????return?process;
????};
?
????return?middleware;
}

這一過程是理解函數(shù)式方案的關鍵,所有Middleware可以聚合為一個Func<Context,Context>,為了易于閱讀,我們可以定義一個委托:

1
public?delegate?Context RequestDelegate(Context context);

給定初始RequestDelegate,聚合所有Middleware:

1
2
3
4
5
6
7
8
9
10
11
12
13
public?IApplication Build()
{
????RequestDelegate request = context => context;
?
????_middlewares.Reverse();
?
????foreach?(var?middleware in?_middlewares)
????{
????????request = middleware(request);
????}
?
????return?new?Application(request);
}

自定義一個函數(shù)式Middleware:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public?class?DefaultMiddleware:IMiddleware
{
????public?Func<RequestDelegate, RequestDelegate> Request()
????{
????????Func<RequestDelegate, RequestDelegate> request = next =>
????????{
????????????return?context =>
????????????{
????????????????context.Request.Process("default request", "processed by defaultMiddleware");
?
????????????????next(context);
?
????????????????context.Response.Process("default response", "processed by defaultMiddleware");
?
????????????????return?context;
????????????};
?
????????};
?
????????return?request;
????}
}


ASP.NET Core 1.0中的管道-中間件模式的評論 (共 條)

分享到微博請遵守國家法律
清苑县| 金坛市| 南皮县| 海丰县| 时尚| 通辽市| 麦盖提县| 双峰县| 陵川县| 永兴县| 清苑县| 沁水县| 故城县| 彭泽县| 根河市| 河曲县| 灵宝市| 茂名市| 宣城市| 柳林县| 淮滨县| 东安县| 纳雍县| 双辽市| 五寨县| 泾阳县| 巢湖市| 福贡县| 金门县| 阜城县| 家居| 弋阳县| 卓资县| 博爱县| 白水县| 驻马店市| 龙海市| 兴化市| 个旧市| 泗洪县| 红河县|