亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何更好地構建架構

如何更好地構建架構

C#
Cats萌萌 2022-07-10 10:13:05
我有一個 ASP.NET Core 應用程序,它從另一個庫調用服務。該服務使用外部 API,這需要sessionId. 我們必須調用 Login API 方法來獲取sessionId. 這sessionId能活多久,什么時候可以改變——我們不知道。規則是:sessionId1個請求有效,10個請求有效,100個請求有效,1分鐘有效,10分鐘有效,1天有效……沒人知道。該服務有許多方法可以調用類似的 API:public class BillRequest{    private readonly HttpClient client;    public BillRequest()    {        client = new HttpClient        {            BaseAddress = new Uri("https://myapi.com/api/v2/")        };    }    public async Task<List<Dto1>> CustomerBankAccountListAsync(int start, int count)    {        List<KeyValuePair<string, string>> nvc = new List<KeyValuePair<string, string>>        {            new KeyValuePair<string, string>("sessionId", CURRENT_SESSION_ID)        };        var customerStream = await client.PostAsync("List/CustomerBankAccount.json", new FormUrlEncodedContent(nvc));        var customerString = await customerStream.Content.ReadAsStringAsync();        //....    }    public async Task<List<Dto2>> Method2(int start, int count)    {        List<KeyValuePair<string, string>> nvc = new List<KeyValuePair<string, string>>        {            new KeyValuePair<string, string>("sessionId", CURRENT_SESSION_ID)        };        var customerStream = await client.PostAsync("List/Method2.json", new FormUrlEncodedContent(nvc));        var customerString = await customerStream.Content.ReadAsStringAsync();        //....    }    // logic to get SessionId here    public async Task LoginAsync()    {    }如何實施以保存此sessionId內部服務?有很多選項可以實現:Login每次調用方法之前調用方法。易于實現,但方法不好,因為那時我們有很多不必要的請求并且sessionId只使用一次保存sessionIdweb 應用程序級別并嘗試捕獲異常,當任何方法返回“無效 sessionId”時,然后調用Login方法,該方法將返回一個新的sessionId. 在這種情況下,我們必須傳遞sessionId給類的構造函數BillRequest。它可以工作,但我不喜歡將服務責任轉移給其他人,因為如何使用 API 是服務的內部責任。保存sessionId在服務本身內部并在服務內部調用Login方法,當舊sessionId的被認為無效時,用新的等重寫它。但是如何將其保存為內存中的“靜態”?我不想將它保存到任何外部位置(文件系統、云等),但我也不能保存到類的變量中,因為可以重新創建類的對象......
查看完整描述

1 回答

?
心有法竹

TA貢獻1866條經驗 獲得超5個贊

我建議在這里對函數式編程進行一定的心理轉變。

sessionID其視為獨立值而不是單個對象。然后可以通過以下(語義等效)方式重新定義您的問題:給定一個類型化的流(string在您的情況下),如何觀察其流程并對傳入的更改做出反應,而您的源代碼無法控制?

嗯,有一個由 Enterprise? 證明的答案:反應式擴展。

從技術上講,這種轉變意味著您正在處理IObservable<string>控制器的內部,它可以通過標準的 .NET Core DI 方法注入,或者簡單地由構造函數定義。這是非常靈活的,因為rX它為您提供了完全可測試、令人難以置信的強大工具集來處理此類任務;rX也與本機兼容,Task因此也與async/await功能兼容。不錯的事實是,從外部世界注入所需的行為并用更合適的行為來裝飾現有的 observable 非常容易:因此,您是安全的:一旦第 3 方的服務邏輯發生更改,您幾乎可以立即輕松地采用您的代碼庫。

里面會是什么IObservable<string>?好吧,我不能說,因為你沒有提供足夠的信息。這可能是一個間隔,詢問遠程服務器當前sessionID是否仍然有效,如果不是 - 運行重新登錄程序并通知它的訂閱者新值;它可能是一個負責編譯時已知過期規則的計時器rX,它可能是您需要的復雜邏輯:足夠靈活,不會限制您使用它可以實現的目標,只要您處理(可能是無限的)流.

因此,這意味著您不需要任何全局值。只需訂閱會話 ID 流并獲取最新的 - 當前有效的,完成工作并處理您的訂閱。它貴,不會影響性能;兩者都不會破壞并發性。如果您想堅持一種常見的 .NET 方式,請rX使用它Task。await

PS 交付實施所需的 99% 已經存在;你只需要結合它。


查看完整回答
反對 回復 2022-07-10
  • 1 回答
  • 0 關注
  • 133 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號