[英]DI issue in .NET Core
我有一個 odata 查詢生成器 class 用於構建我的 odata 字符串,該字符串根據調用它的 object 對結果進行消毒。
public class UosOdataQueryBuilder<T>
{
private readonly Dictionary<string, string> _queryOptions;
private readonly IHttpClientFactory _clientFactory;
private readonly ILogger _logger;
public UosOdataQueryBuilder([FromServices] IHttpClientFactory clientFactory, [FromServices] ILogger logger)
{
_queryOptions = new Dictionary<string, string>();
_clientFactory = clientFactory;
_logger = logger;
}
public UosOdataQueryBuilder<T> WithFilter(string filter)
{
_queryOptions.Add("$filter", filter);
return this;
}
public UosOdataQueryBuilder<T> Skip(int skip)
{
_queryOptions.Add("$skip", skip.ToString());
return this;
}
public UosOdataQueryBuilder<T> Top(int top)
{
_queryOptions.Add("$top", top.ToString());
return this;
}
public UosOdataQueryBuilder<T> WithNoInlineCount()
{
_queryOptions.Add("$inlinecount", "none");
return this;
}
public UosOdataQueryBuilder<T> OrderBy(string orderBy)
{
_queryOptions.Add("$orderby", orderBy);
return this;
}
public async Task<UosOdataReponse<T>> ExecuteQueryAsync(string elementName = "")
{
var result = new UosOdataReponse<T>();
try
{
var authToken = AppSettings.PlatformBearerToken;
var queryParameters = new List<string>();
foreach (var option in _queryOptions)
queryParameters.Add($"{option.Key}={option.Value}");
var queryParametersCombined = string.Join("&", queryParameters);
var oDataElementName = (elementName == "") ? typeof(T).Name : elementName;
var baseUrl = AppSettings.PlatformBaseUri;
var client = _clientFactory.CreateClient("UOS");
var request = new HttpRequestMessage(
HttpMethod.Get,
new Uri(baseUrl + $"/uos/v4/odata/{oDataElementName}" + queryParametersCombined));
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
result = JsonConvert.DeserializeObject<UosOdataReponse<T>>(data);
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
}
return result;
}
}
我已經在啟動時設置了客戶端
services.AddHttpClient("UOS", c =>
{
c.BaseAddress = new Uri(Configuration.GetValue<string>("PlatformBaseUri") + "uos/v4/");
c.DefaultRequestHeaders.Add("Accept", "application/json");
c.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Configuration.GetValue<string>("PlatformBearerToken"));
//c.Timeout = new TimeSpan(0, 0, 30);
});
當我從另一個方法創建這個的新實例時,它要求我傳入 clientFactory 和 logger。
protected async Task<int> GetUosOdataCount(string filter)
{
var result = new List<T>();
try
{
var countCheck = await new UosOdataQueryBuilder<T>()
.WithFilter(filter)
.Top(1)
.ExecuteQueryAsync();
return countCheck.Count;
}
catch (Exception ex)
{
//CustomLogger.LogError(GetType().FullName, "GetUosOdata", ex.Message);
}
}
在 .NET 框架中,我將從 UosOdataQueryBuilder 的構造函數中刪除參數並解決其中的依賴關系。 例如:
_uosUserAttributeRepository = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUosUserAttributeRepository)) as IUosUserAttributeRepository;
但我不確定如何在 .NET Core 中實現。 有什么建議么?
您可以為UosOdataQueryBuilder<T>
創建一個接口並將其注冊到DI
中。 像這樣的東西:
public interface IUosOdataQueryBuilder<T>
{
Task<T> SomeMethod();
}
public class UosOdataQueryBuilder<T> : IUosOdataQueryBuilder<T>
{
private readonly Dictionary<string, string> _queryOptions;
private readonly IHttpClientFactory _clientFactory;
private readonly ILogger<UosOdataQueryBuilder<T>> _logger;
public UosOdataQueryBuilder(IHttpClientFactory clientFactory, ILogger<UosOdataQueryBuilder<T>> logger)
{
_queryOptions = new Dictionary<string, string>();
_clientFactory = clientFactory;
_logger = logger;
}
public Task<T> SomeMethod()
{
return default;
}
}
在啟動時的ConfigureServices
中寫下:
services.AddScoped(typeof(IUosOdataQueryBuilder<>), typeof(UosOdataQueryBuilder<>));
並在您的 controller 中注入IUosOdataQueryBuilder
:
private readonly IUosOdataQueryBuilder<YourClass> _uosOdataQueryBuilder;
public YourController( IUosOdataQueryBuilder<YourClass> uosOdataQueryBuilder)
{
_uosOdataQueryBuilder = uosOdataQueryBuilder;
}
您可以將IUosOdataQueryBuilder
注冊為Singleton
但為了防止 memory 泄漏,您應該在具體的 class 中注入IServiceScopeFactory
以在您的方法中而不是在構造函數中獲取注冊服務。
我同意堅持注入的評論,但您可以使用IServiceProvider檢索 class 中的依賴項
例如
MyMethod(IServiceProvider serviceProvider)
{
MyService svc = (MyService)serviceProvider.GetService(typeof(MyService));
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.