diff --git a/Dan.Common/Extensions/HostBuilderExtensions.cs b/Dan.Common/Extensions/HostBuilderExtensions.cs
index f472a1d..3bac46b 100644
--- a/Dan.Common/Extensions/HostBuilderExtensions.cs
+++ b/Dan.Common/Extensions/HostBuilderExtensions.cs
@@ -1,6 +1,4 @@
using System.Reflection;
-using System.Text.Json;
-using System.Text.Json.Serialization;
using Azure.Core.Serialization;
using Dan.Common.Interfaces;
using Microsoft.Azure.Functions.Worker;
@@ -15,9 +13,12 @@ namespace Dan.Common.Extensions;
public static class HostBuilderExtensions
{
///
- /// Sets up the isolated worker function with default configuration and wiring with ConfigureFunctionsWorkerDefaults(), handling application insights
- /// logging and correct JSON serialization settings. Also adds defaults services; HttpClientFactory with a circuit-breaker enabled named client (use Constants.SafeHttpClient)
- /// which should be used for outbound requests to the data source. Also expects to find a service implementing IEvidenceSourceMetadata.
+ /// Sets up the isolated worker function with default configuration and wiring with ConfigureFunctionsWorkerDefaults(),
+ /// handling application insights
+ /// logging and correct JSON serialization settings. Also adds defaults services; HttpClientFactory with a
+ /// circuit-breaker enabled named client (use Constants.SafeHttpClient)
+ /// which should be used for outbound requests to the data source. Also expects to find a service implementing
+ /// IEvidenceSourceMetadata.
///
/// The host builder
/// The host builder for additional chaining
@@ -25,66 +26,75 @@ public static class HostBuilderExtensions
public static IHostBuilder ConfigureDanPluginDefaults(this IHostBuilder builder)
{
builder.ConfigureFunctionsWorkerDefaults(workerBuilder =>
- {
- workerBuilder
- // Using preview package Microsoft.Azure.Functions.Worker.ApplicationInsights, see https://github.com/Azure/azure-functions-dotnet-worker/pull/944
- // Requires APPLICATIONINSIGHTS_CONNECTION_STRING being set. Note that host.json logging settings will have to be replicated to worker.json
- .AddApplicationInsights()
- .AddApplicationInsightsLogger();
- }, options => { options.Serializer = new NewtonsoftJsonObjectSerializer(); })
+ {
+ workerBuilder
+ // Using preview package Microsoft.Azure.Functions.Worker.ApplicationInsights, see https://github.com/Azure/azure-functions-dotnet-worker/pull/944
+ // Requires APPLICATIONINSIGHTS_CONNECTION_STRING being set. Note that host.json logging settings will have to be replicated to worker.json
+ .AddApplicationInsights()
+ .AddApplicationInsightsLogger();
+ }, options =>
+ {
+ options.Serializer = new NewtonsoftJsonObjectSerializer(
+ // Use Newtonsoft.Json for serializing in order to support TypeNameHandling and other annotations on. This should be ported to System.Text.Json at some point.
+ new JsonSerializerSettings
+ {
+ TypeNameHandling = TypeNameHandling.Auto,
+ NullValueHandling = NullValueHandling.Ignore
+ });
+ })
.ConfigureServices((context, services) =>
{
services.AddLogging();
services.AddHttpClient();
- var openCircuitTimeSeconds = int.TryParse(context.Configuration["DefaultCircuitBreakerOpenCircuitTimeSeconds"], out var result) ? result : 10;
- var failuresBeforeTripping = int.TryParse(context.Configuration["DefaultCircuitBreakerFailureBeforeTripping"], out result) ? result : 4;
+ var openCircuitTimeSeconds =
+ int.TryParse(context.Configuration["DefaultCircuitBreakerOpenCircuitTimeSeconds"], out var result)
+ ? result
+ : 10;
+ var failuresBeforeTripping =
+ int.TryParse(context.Configuration["DefaultCircuitBreakerFailureBeforeTripping"], out result)
+ ? result
+ : 4;
- var registry = new PolicyRegistry()
+ var registry = new PolicyRegistry
{
{
Constants.SafeHttpClientPolicy,
HttpPolicyExtensions.HandleTransientHttpError()
.CircuitBreakerAsync(
- handledEventsAllowedBeforeBreaking: failuresBeforeTripping,
- durationOfBreak: TimeSpan.FromSeconds(openCircuitTimeSeconds))
+ failuresBeforeTripping,
+ TimeSpan.FromSeconds(openCircuitTimeSeconds))
}
};
services.AddPolicyRegistry(registry);
- var httpClientTimeoutSeconds = int.TryParse(context.Configuration["SafeHttpClientTimeout"], out result) ? result : 30;
+ var httpClientTimeoutSeconds = int.TryParse(context.Configuration["SafeHttpClientTimeout"], out result)
+ ? result
+ : 30;
// Client configured with circuit breaker policies
services.AddHttpClient(Constants.SafeHttpClient,
client => { client.Timeout = TimeSpan.FromSeconds(httpClientTimeoutSeconds); })
.AddPolicyHandlerFromRegistry(Constants.SafeHttpClientPolicy);
- services.Configure(options =>
- {
- options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
- options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
- options.Converters.Add(new JsonStringEnumConverter());
- });
-
- // Try to add the first IEvidenceSourceMetadata implementation we can find
+ // Try to add the first IEvidenceSourceMetadata implementation we can find in the entry assembly
var evidenceSourceMetadataServiceType = typeof(IEvidenceSourceMetadata);
- var assembly = Assembly.GetExecutingAssembly();
+ var assembly = Assembly.GetEntryAssembly();
- var implementationType = assembly.GetTypes()
- .FirstOrDefault(t => t.GetInterfaces().Any(i => i == evidenceSourceMetadataServiceType));
+ var implementationType = assembly?.GetTypes()
+ .FirstOrDefault(t => t.GetInterfaces().Any(i => i == evidenceSourceMetadataServiceType));
if (implementationType == null)
- {
throw new NotImplementedException(
- $"Missing implementation of {nameof(IEvidenceSourceMetadata)}");
- }
+ $"Missing implementation of {nameof(IEvidenceSourceMetadata)} in entry assembly {assembly?.FullName ?? "(unmanaged assembly)"}");
- if (!services.Any(s => s.ServiceType == evidenceSourceMetadataServiceType && s.ImplementationType == implementationType))
- {
- services.Add(new ServiceDescriptor(evidenceSourceMetadataServiceType, implementationType, ServiceLifetime.Singleton));
- }
+ if (!services.Any(s =>
+ s.ServiceType == evidenceSourceMetadataServiceType &&
+ s.ImplementationType == implementationType))
+ services.Add(new ServiceDescriptor(evidenceSourceMetadataServiceType, implementationType,
+ ServiceLifetime.Singleton));
});
return builder;
}
-}
+}
\ No newline at end of file