我有一個具有多個托管服務的 Web 服務。
我希望能夠通過 "appSettings.json "來開啟和關閉它們。
在 "StartUp.cs "中,我填充了一個
的實體。 public class HostedServiceSettings
{
public StateOfUse BuildMontageTasks { get; init; }
public StateOfUse BuildTasksFromFileCreations { get; init; }
public StateOfUse BusinessEventPuller { get; init; }
public StateOfUse FieldServiceAppointmentChanges { get; init; }
public StateOfUse MvtBriefingCleanupLoop { get; init; }
public StateOfUse SfCacheFileListener { get; init; }
public StateOfUse TaskWorker { get; init; }
StateOfUse是這個列舉:
public enum stateOfUse
{
不活躍。
活躍
}
而且每個屬性都對應于一個托管服務。
在StartUp類中,我已經添加了以下方法:
private void AddHostedServices(IServiceCollection services)
{
HostedServiceSettings settings = Configure<HostedServiceSettings>(services, "HostedServices"/span>)。
foreach (PropertyInfo property in typeof(HostedServiceSettings) 。 GetProperties())。
{
StateOfUse stateOfUse = (StateOfUse)property.GetValue(settings)。
if (stateOfUse.IsActive())
{
string hostedServiceName = $"PraxedoIntegration.{property.Name}HostedService"/span>。
Type hostedServiceType = Type.GetType(hostedServiceName);
Type = typeof(IServiceCollection);
MethodInfo methodInfo = type.GetMethod("IServiceCollection.AddHostedService"/span>)。
MethodInfo genericMethod = methodInfo.MakeGenericMethod(hostedServiceType)。
genericMethod.Invoke(services, null)。
}
}
這就失敗了,因為MethodInfo methodInfo被決議為null,因此在下一行將拋出一個例外。 方法IServiceCollection.AddHostedService<THostedService>()是一個包含在Microsoft.Extensions.Hosting.Abstractions命名空間的公共靜態類ServiceCollectionHostedServiceExtensions的靜態方法。 (我在代碼中沒有使用nameof,因為擴展方法不支持這樣做。 :-( )
是否可以通過泛型來訪問這個方法? 如果可以,怎么做?
uj5u.com熱心網友回復:
一種選擇是使用 AddHostedService的overload,它需要一個implementationFactory注冊每個服務,但如果不活動則回傳一個空的實作
services.AddHostedService<ServiceA> ( (services => {
HostedServiceSettings settings = Configure<HostedServiceSettings>(services, "HostedServices"/span>)。
if(settings.IsServiceAActive())
return new ServiceA()。
return NullService()。
})
uj5u.com熱心網友回復:
我發現我可以通過將擴展方法包裝在一個本地方法中來解決這個問題,就像:
private void AddHostedServices(IServiceCollection services)
{
HostedServiceSettings settings = Configure<HostedServiceSettings>(services, "HostedServices"/span>)。
foreach (PropertyInfo property in typeof(HostedServiceSettings) 。 GetProperties())。
{
StateOfUse stateOfUse = (StateOfUse)property.GetValue(settings)。
if (stateOfUse.IsActive())
{
string hostedServiceName = $"PraxedoIntegration.{property.Name}HostedService"/span>。
Type hostedServiceType = Type.GetType(hostedServiceName);
Type = typeof(Startup);
MethodInfo methodInfo = type.GetMethod("AddHostedService"/span>)。
MethodInfo genericMethod = methodInfo.MakeGenericMethod(hostedServiceType)。
genericMethod.Invoke(this, new object[ ] { services })。
}
}
}
//需要作為一種作業方法,因為我們不能用反射呼叫擴展方法。
public IServiceCollection AddHostedService<THostedService>(IServiceCollection services)
where THostedService : class, IHostedService =>
services.AddHostedService<THostedService>()。
另外,有人提醒我注意,在這個例子中,AddHostedService()的實作細節是已知的,它只是AddTransient()的一個封裝器(可以說是 "語法糖"),所以我可以通過這樣做避免反射:
private void AddHostedServices(IServiceCollection services)
{
HostedServiceSettings settings = Configure<HostedServiceSettings>(services, "HostedServices"/span>)。
foreach (PropertyInfo property in typeof(HostedServiceSettings) 。 GetProperties())。
{
StateOfUse stateOfUse = (StateOfUse)property.GetValue(settings)。
if (stateOfUse.IsActive())
{
string hostedServiceName = $"PraxedoIntegration.{property.Name}HostedService"/span>。
Type hostedServiceType = Type.GetType(hostedServiceName);
services.AddTransient(typeof(IHostedService), hostedServiceType) 。
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/318604.html
標籤:
上一篇:使用泛型來獲得正確的回傳型別
