Using multiple FHIR versions in one project
It could happen that in your .NET project you need FHIR version STU3 and R4 simultaneously. But how can you distinguish a STU3 Patient
from a R4 Patient
?
The solution lies in creating aliases for the different projects. See the inclusion of the different Firely .NET SDK packages in the project file here:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Hl7.Fhir.STU3" Version="5.5.0" Aliases="stu3" />ItemGroup>
<PackageReference Include="Hl7.Fhir.R4" Version="5.5.0" Aliases="r4" />
<PackageReference Include="Hl7.Fhir.R4B" Version="5.5.0" Aliases="r4b" />
<PackageReference Include="Hl7.Fhir.R5" Version="5.5.0" Aliases="r5" />
</ItemGroup>
</Project>
To use the Patient
for STU3 and the Patient
for R4 in the same C# unit file, you must use the aliases
we previously defined. Declaring the extern alias introduces an additional root-level namespace to the global namespace.
So in your code you can this to expend the namespace, for example like this for a R4 Patient
:
extern alias r4;
extern alias stu3;
namespace MultipleVersions
{
// Somewhere inside a method:
var patientR4 = new r4::Hl7.Fhir.Model.Patient();
var patientSTU3 = new stu3::Hl7.Fhir.Model.Patient();
}
To avoid having to repeat the namespace, you can use an alias in the using
:
using R4 = r4::Hl7.Fhir.Model;
// and then later...
var patient = new R4.Patient():
So all together it looks like this:
extern alias r4;
extern alias stu3;
using System;
using Hl7.Fhir.Model;
using R4 = r4::Hl7.Fhir.Model;
using STU3 = stu3::Hl7.Fhir.Model;
namespace MultipleVersions
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var code = new Code();
var patient1 = new STU3.Patient();
var patient2 = new R4.Patient();
}
}
}
Dealing with Specification.zip
Although the recommended way of working with FHIR metadata is using the FhirPackageSource, the SDK originally depended on the specification.zip
file. Since the different SDK versions all use the same physical file, it is not possible to use different versions of the SDK in one project when using the specification.zip
file, unless we tweak our projects files:
<ItemGroup>
<PackageReference Include="Hl7.Fhir.Specification.Data.STU3" Version="5.5.0" GeneratePathProperty="true" ExcludeAssets="contentFiles" />
<PackageReference Include="Hl7.Fhir.Specification.Data.R4" Version="5.5.0" GeneratePathProperty="true" ExcludeAssets="contentFiles" />
</ItemGroup>
<ItemGroup>
<Content Include="$(PkgHl7_Fhir_Specification_Data_STU3)\contentFiles\any\any\specification.zip">
<Link>specification_STU3.zip</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Pack>false</Pack>
</Content>
<Content Include="$(PkgHl7_Fhir_Specification_Data_R4)\contentFiles\any\any\specification.zip">
<Link>specification_R4_0.zip</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Pack>false</Pack>
</Content>
</ItemGroup>
You will notice that the package reference uses the GeneratePathProperty
to be able to “link” the different specification.zip
to a unique name that includes the FHIR specification version. When building the project, the specification.zip
files will be copied to the output directory with the new name, and should then also be referenced differently in code creating a resolver using the zip:
IResourceResolver zipSource = fhirVersion switch
{
FHIRVersion.N3_0 =>
stu3::Hl7.Fhir.Specification.Source.ZipSource.CreateValidationSource(Path.Combine(CommonDirectorySource.SpecificationDirectory, "specification_STU3.zip")),
FHIRVersion.N4_0 =>
r4::Hl7.Fhir.Specification.Source.ZipSource.CreateValidationSource(Path.Combine(CommonDirectorySource.SpecificationDirectory, "specification_R4_0.zip")),
_ => throw new NotSupportedException()
}
More background and details can be found in Brian’s blog on multi-version FHIR.