iT邦幫忙

2022 iThome 鐵人賽

DAY 19
0

進入.Net core後,C#大量使用非同步方法,像是從使用EF core從DB取得資料。我們經常會遇到當API接收到request後,需要針對request的資料做驗證,有時候需要跟DB的資料做比對,對Task物件的使用就非常重要。

實做簽到系統

我們來設計一個簽到系統,當輸入名字後會撈取名單,確認簽到的人在名單後,把出席紀錄寫到資料庫中。

// 先準備好要呼叫database的方法
public Task<Member?> GetMemberByNameAsync(string name) => // todo
public Task<Attendance?> CreateAttendanceAsync(Attendance attendance) => // todo

// API的殼
public Task<IActionResult> CheckIn(string name)
{
		var result = GetMemberByNameAsync(name)
		// todo
}

首先觀察GetMemberByNameAsync方法的回傳值,其實可以視為Task<Option<Member>>,我們希望第一步查詢資料庫中是否有這個名字,先試試使用Map去組合接下來的步驟,為了跟接下來的nullable做區別,這邊就叫它TaskMap

var result = GetMemberByNameAsync(name)
				.TaskMap(member=> // todo

目前的member型別為Member?,我希望映射到另一個Attendance的Entity,並且會被nullable包裹

var result = GetMemberByNameAsync(name)
				.TaskMap(member => member
					.Map(m => new Attendance{ name = m.Name })
					// todo							

回傳的型別是Attendance?,這邊一樣使用Map來套用c

var result = GetMemberByNameAsync(name)
				.TaskMap(member => member
					.Map(m => new Attendance{ name = m.Name })
					.Map(CreateAttendanceAsync))	

這時候result的型別會是Task<Task<….>>,有點奇怪是因為我們使用了TaskMap,而CreateAttendanceAsyn的回傳值是一個Task物件,所以這時候要改成使用Bind

var result = GetMemberByNameAsync(name)
				.TaskBind(member => member
					.Map(m => new Attendance{ name = m.Name })
					.Map(CreateAttendanceAsync))	

接下來await就可以取得值了

var result = await GetMemberByNameAsync(name)
                        .TaskBind(member => member
							.Map(m => new Attendance{ name = m.Name })
							.Map(CreateAttendanceAsync));

最後要做一個處裡,如果是null就回傳失敗,完整的api就會變成

public Task<IActionResult> CheckIn(string name)
{
		return (await GetMemberByNameAsync(name)
						.TaskBind(member => member
							.Map(m => new Attendance{ name = m.Name })
							.Map(CreateAttendanceAsync)))
							switch
							{
								{} => Ok(),
								null => BadRequest()
							}
}

小結

在設計的時候為了避免套嵌經常使用Bind來連接,因為很常遇到連接的方法回傳值具有相同的”盒子”,以非同步設計來說後續的方法也經常是非同步的。碎歲念一下,寫到這裡我真的好想放棄,已經不知道自己在寫什麼了,也不知道接下來要寫什麼嗚嗚嗚。


上一篇
Day18. Task(1)
下一篇
Day20. SelectMany(1)
系列文
Functional Programming with C#30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言