[英]What pattern to use for TwilioRestClient with Dependency Injection
我試圖了解如何通過依賴注入正確使用TwilioRestClient
。 我閱讀了這個宣布AddTwilioClient服務的頁面並做了一些實驗。
目標是訪問多個 Twilio 子帳戶。
程序.cs:
///Removed code for clarity
var host = new HostBuilder()
.ConfigureServices(services =>
{
services.AddHttpClient();
services.AddTwilioClient();
services.AddScoped<TwilioVoiceServices>();
}).Build();
這是一個注入的 class,它顯示了創建TwilioClient
的兩個選項
Twilio語音服務.cs :
public class TwilioVoiceServices
{
///Removed code for clarity
private readonly ITwilioRestClient twilioClient
public TwilioVoiceServices(ITwilioRestClient twilioClient)
{
_twilioClient = twilioClient;
}
public async Task<CallResource> GetCallWithNamedHttpClient(string accountSid, string authToken, string callSid)
{
var call = await CallResource.FetchAsync(
pathAccountSid: accountSid,
pathSid: callSid,
client: new TwilioRestClient(username: accountSid, password: authToken, httpClient: _twilioClient.HttpClient);
return call;
}
public async Task<CallResource> GetCallWithImpliedHttpClient(string accountSid, string authToken, string callSid)
{
var call = await CallResource.FetchAsync(
pathAccountSid: accountSid,
pathSid: callSid,
client: new TwilioRestClient(username: accountSid, password: authToken));
return call;
}
}
GetCallWithNamedHttpClient
和GetCallWithImpliedHttpClient
都可以工作,並允許我使用動態命名的 Sid/AuthToken 訪問 Twilio REST API。
我是否需要將 httpClient: 指定為注入的ITwilioRestClient
,如GetCallWithNamedHttpClient
所示? 或者,Twilio 庫是否會自動處理該問題,如GetCallWithImpliedHttpClient
中所示?
由於兩者都有效,我擔心的是GetCallWithImpliedHttpClient
實際上是在幕后創建新的HttpClient
,而不是重用services.AddTwilioClient()
創建的 singleton HttpClient
。
這被部署到 Azure Function 上 .NET 7。
使用Twilio.AspNet.Core
庫中的.AddTwilioClient()
時,Twilio REST 客戶端將使用IHttpClientFactory.CreateClient("Twilio")
獲取HttpClient
。 ( 源代碼)
因此,在GetCallWithNamedHttpClient
中,您將重復使用由 HTTP 客戶端工廠管理的相同HttpClient
,而在GetCallWithImpliedHttpClient
中,它每次都會創建一個新的HttpClient
。 ( 源代碼)
重用 HTTP 客戶端工廠提供的 HTTP 客戶端會更好,所以我將 go 與GetCallWithNamedHttpClient
一起使用,但是,我不是注入ITwilioRestClient
,而是從 HTTP 客戶端工廠請求 HTTP 客戶端並將其傳遞給客戶端工廠 TthatClient 構造函數TwilioRestClient
. 像這樣:
public class TwilioVoiceServices
{
private readonly IHttpClientFactory _clientFactory;
public TwilioVoiceServices(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
public async Task<CallResource> GetCallWithNamedHttpClient(string accountSid, string authToken, string callSid)
{
var httpClient = _clientFactory.CreateClient();
var call = await CallResource.FetchAsync(
pathAccountSid: accountSid,
pathSid: callSid,
client: new TwilioRestClient(
username: accountSid,
password: authToken,
httpClient: new SystemNetHttpClient(httpClient)
)
);
return call;
}
}
現在您真的不需要在啟動期間調用.AddTwilioClient
,因為您不再注入ITwilioRestClient
。
在這種情況下,我認為為 Twilio 客戶端創建工廠 class 更有意義:
public class TwilioClientFactory
{
private readonly IHttpClientFactory _clientFactory;
public TwilioClientFactory(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
public ITwilioRestClient CreateClient(string accountSid, string authToken)
{
var httpClient = _clientFactory.CreateClient();
return new TwilioRestClient(
username: accountSid,
password: authToken,
httpClient: new SystemNetHttpClient(httpClient)
);
}
}
將工廠注冊為 singleton 並將其注入到您需要的任何位置,調用CreateClient
並將其傳遞到資源方法中:
var twilioClient = twilioClientFactory.CreateClient(
accountSid: "",
authToken: ""
);
var call = await CallResource.FetchAsync(
pathSid: "",
client: twilioClient
);
請注意,我沒有指定accountSid
,因為它將使用twilioClient.AccountSid
。
您也可以根據您的用例自行將 Twilio 客戶端注冊到 DI 容器中。 你能詳細說明你有多少個子賬戶,什么時候需要在子賬戶之間切換?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.