Skip to content

Commit

Permalink
Merge pull request #58 from FirelyTeam/feature/improve-multi-version-doc
Browse files Browse the repository at this point in the history
Update page on multi version use of SDK
  • Loading branch information
mmsmits committed Jan 24, 2024
2 parents 53b471b + e4af646 commit 6034833
Showing 1 changed file with 70 additions and 34 deletions.
104 changes: 70 additions & 34 deletions model/multiple-fhir-versions.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
.. _multiple-versions:

===========================================
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``?

Expand All @@ -14,31 +15,22 @@ project file here:
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Hl7.Fhir.STU3" Version="3.0.0" />
<PackageReference Include="Hl7.Fhir.R4" Version="3.0.0" />
<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>
<Target Name="AddPackageAliases" BeforeTargets="ResolveReferences" Outputs="%(PackageReference.Identity)">
<ItemGroup>
<ReferencePath Condition="'%(FileName)'=='Hl7.Fhir.STU3.Core'">
<Aliases>stu3</Aliases>
</ReferencePath>
<ReferencePath Condition="'%(FileName)'=='Hl7.Fhir.R4.Core'">
<Aliases>r4</Aliases>
</ReferencePath>
</ItemGroup>
</Target>
</Project>
I created here an alias for the STU3 (named ``stu3``) and for the R4 (named ``r4``).

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:
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``:


.. code-block:: csharp
Expand All @@ -47,25 +39,19 @@ we previously defined:
namespace MultipleVersions
{
// code here
// Somewhere inside a method:
var patientR4 = new r4::Hl7.Fhir.Model.Patient();
var patientSTU3 = new stu3::Hl7.Fhir.Model.Patient();
}
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``:

.. code-block:: csharp
var patient = new r4::Hl7.Fhir.Model.Patient();
When you don't want to fully express the namespace everytime, you can use an alias
in the using part:
To avoid having to repeat the namespace, you can use an alias in the ``using``:

.. code-block:: csharp
using R4 = r4::Hl7.Fhir.Model;
/* Inside class: */
// and then later...
var patient = new R4.Patient():
So all together it looks like this:
Expand All @@ -75,10 +61,10 @@ So all together it looks like this:
extern alias r4;
extern alias stu3;
using Hl7.Fhir.Model;
using System;
using Hl7.Fhir.Model;
using R4 = r4::Hl7.Fhir.Model;
using Stu3 = stu3::Hl7.Fhir.Model;
using STU3 = stu3::Hl7.Fhir.Model;
namespace MultipleVersions
{
Expand All @@ -90,10 +76,60 @@ So all together it looks like this:
var code = new Code();
var patient1 = new Stu3.Patient();
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 :ref:`FhirPackageSource <package-source>`, 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:

.. code-block:: csharp
<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:
.. code-block:: csharp
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 <https://brianpos.com/2023/09/22/firely-sdk-and-multiple-fhir-versions>`_.

0 comments on commit 6034833

Please sign in to comment.