Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions Libraries/Spark.Engine/Extensions/IServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,25 @@ internal static IEnumerable<IFhirServiceExtension> GetFhirExtensions(this IServi
private static DeserializerSettings GetDeserializerSettings(SparkSettings settings) =>
settings.DeserializerSettings ?? DeserializerSettingsFactory.GetStrictDeserializerSettings();

public static IServiceCollection AddFhirFacadeServices(this IServiceCollection services, Action<SparkOptions> options)
{
services.AddFhirFacadeServicesInternal(options);
return services;
}

public static IMvcBuilder AddFhirFacadeMvc(this IServiceCollection services, Action<SparkOptions> options)
{
var opts = services.AddFhirFacadeServicesInternal(options);
return services.AddFhirFormatters(opts.Settings, opts.MvcOption);
}

[Obsolete("Use AddFhirFacadeMvc to retain the existing MVC formatter behavior.")]
public static IMvcBuilder AddFhirFacade(this IServiceCollection services, Action<SparkOptions> options)
{
return services.AddFhirFacadeMvc(options);
}
Comment thread
losolio marked this conversation as resolved.

private static SparkOptions AddFhirFacadeServicesInternal(this IServiceCollection services, Action<SparkOptions> options)
{
services.Configure(options);

Expand Down Expand Up @@ -105,10 +123,6 @@ public static IMvcBuilder AddFhirFacade(this IServiceCollection services, Action
services.TryAddTransient<IFhirResponseInterceptorRunner, FhirResponseInterceptorRunner>();
services.TryAddTransient<IFhirResponseFactory, FhirResponseFactory.FhirResponseFactory>();
services.TryAddTransient<ICompositeServiceListener, ServiceListener>();
services.TryAddTransient<ResourceJsonInputFormatter>();
services.TryAddTransient<ResourceJsonOutputFormatter>();
services.TryAddTransient<ResourceXmlInputFormatter>();
services.TryAddTransient<ResourceXmlOutputFormatter>();

if (services.IndexOf(new ServiceDescriptor(typeof(IResourceStorageService), typeof(ResourceStorageService), ServiceLifetime.Transient)) == -1)
{
Expand All @@ -124,7 +138,7 @@ public static IMvcBuilder AddFhirFacade(this IServiceCollection services, Action
services.TryAddSingleton(provider => new BaseFhirJsonSerializer(provider.GetRequiredService<IFhirModel>().GetModelInspector()));
services.TryAddSingleton(provider => new BaseFhirXmlSerializer(provider.GetRequiredService<IFhirModel>().GetModelInspector()));

return services.AddFhirFormatters(settings, opts.MvcOption);
return opts;
}

internal static IMvcBuilder AddFhirInternal(this IServiceCollection services, SparkSettings settings, Action<MvcOptions> setupAction = null)
Expand Down Expand Up @@ -171,10 +185,6 @@ internal static IMvcBuilder AddFhirInternal(this IServiceCollection services, Sp
services.TryAddTransient<ResourceStorageService>(); // storage
services.TryAddTransient<PatchService>(); // patch
services.TryAddTransient<ICompositeServiceListener, ServiceListener>();
services.TryAddTransient<ResourceJsonInputFormatter>();
services.TryAddTransient<ResourceJsonOutputFormatter>();
services.TryAddTransient<ResourceXmlInputFormatter>();
services.TryAddTransient<ResourceXmlOutputFormatter>();

services.TryAddSingleton(provider => new BaseFhirJsonDeserializer(provider.GetRequiredService<IFhirModel>().GetModelInspector(), GetDeserializerSettings(settings)));
services.TryAddSingleton(provider => new BaseFhirXmlDeserializer(provider.GetRequiredService<IFhirModel>().GetModelInspector(), GetDeserializerSettings(settings)));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2026, Incendi <info@incendi.no>
*
* SPDX-License-Identifier: BSD-3-Clause
*/

using Hl7.Fhir.Serialization;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Spark.Engine.Core;
using Spark.Engine.Extensions;
using Spark.Engine.FhirResponseFactory;
using Spark.Engine.Interfaces;
using System;
using Xunit;

namespace Spark.Engine.Tests.Extensions;

public class FhirFacadeServiceCollectionExtensionsTests
{
[Fact]
public void AddFhirFacadeServices_RegistersFacadeServices_WithoutControllerServices()
{
var services = new ServiceCollection();
services.AddSingleton<IFhirModel, FhirModel>();

services.AddFhirFacadeServices(options =>
{
options.Settings.Endpoint = new Uri("http://localhost/fhir");
});

Assert.DoesNotContain(services, descriptor => descriptor.ServiceType == typeof(ApplicationPartManager));
Assert.DoesNotContain(services, descriptor => descriptor.ServiceType == typeof(IActionInvokerFactory));

using var provider = services.BuildServiceProvider();

Assert.NotNull(provider.GetRequiredService<SparkSettings>());
Assert.NotNull(provider.GetRequiredService<StoreSettings>());
Assert.NotNull(provider.GetRequiredService<ILocalhost>());
Assert.NotNull(provider.GetRequiredService<IFhirResponseFactory>());
Assert.NotNull(provider.GetRequiredService<BaseFhirJsonDeserializer>());
Assert.NotNull(provider.GetRequiredService<BaseFhirXmlDeserializer>());
Assert.NotNull(provider.GetRequiredService<BaseFhirJsonSerializer>());
Assert.NotNull(provider.GetRequiredService<BaseFhirXmlSerializer>());
}
}
Loading