
What’s New and What Changed in the 4.0 Version of Our Firely .NET SDK?
Subscribe to our newsletter
SubscribeMore than a year ago we released the last major release of our Firely .NET SDK (version 3.0). Since then, we have been working on several improvements. So it was about time to publish a new major release: version 4.0. In a major release, we allow ourselves to add some breaking changes, clean up our code, and make code improvements. Since we don’t want to make the transition from version 3.x to 4 too difficult, we have kept the breaking changes to a minimum.
The next sections will give you an overview of the biggest changes. For more detail you can read the release notes for version 4.0 and the information about breaking changes.
Reduction of target frameworks
In version 4 we have reduced the target frameworks to:
- net452
- netstandard2.0
- net6.0
This means netstandard1.6 is not targeted anymore. Please bear in mind that we will most likely remove support for net452 in the next major release (version 5).
Serialize/Deserialize with System.Text.Json
A major new feature in this version 4 is a faster serializer/deserializer which is based on the new System.Text.Json
namespace. Using this new serializer we are achieving higher throughput than the existing serializers with a much smaller memory footprint.
Here’s a comparison of the old and new serializer in terms of timing and memory allocation:
Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
JsonDictionarySerializer | 49.40us | 0.693us | 0.579us | 4.5776 | 0.1831 | – | 28KB |
XmlDictionarySerializer | 88.04us | 0.635us | 0.563us | 14.2822 | 1.9531 | – | 88KB |
TypedElementSerializerJson | 457.10us | 4.328us | 4.048us | 69.3359 | 16.1133 | – | 425KB |
TypedElementSerializerXml | 328.80us | 3.369us | 3.152us | 45.8984 | 8.3008 | – | 283KB |
We don’t use the ITypedElement
as intermediate representation of resource anymore, but we use a IReadOnlyDictionary
for this. Meaning that all resources in the SDK are implementing the interface IReadOnlyDictionary
. Here’s an example of how you can use it (the variable value in this example is a FhirBoolean
containing the value true):
IReadOnlyDictionary<string, object> patient = new Patient() { Active = true };
patient.TryGetValue("active", out var value);
Let’s look at some examples how to use the new serializer:
Serializing to Json
var patient = new Patient() { Active = true };
var options = new JsonSerializerOptions().ForFhir(typeof(Patient).Assembly);
var json = JsonSerializer.Serialize<Patient>(patient, options);
Deserializing from Json (Parsing)
var json = @"{ ""resourceType"": ""Patient"" } ";
var options = new JsonSerializerOptions().ForFhir(typeof(Patient).Assembly);
var patient = JsonSerializer.Deserialize<Patient>(json, options);
Our documentation provides more information about the new serializer.
FHIR package resolver
We have been offering a specification.zip
for many years with which you can resolve standard profiles, for example the StructureDefinition
of a Patient
resource. These profiles, or StructureDefinitions, are needed for example for validating resources. Or to generate snapshots of profiles.
For resolving such artifacts, you need a ZipSource
. See here a snippet:
var resolver = new ZipSource("specification.zip");
// or
// var resolver = ZipSource.CreateValidationSource();
var settings = new ValidationSettings() { ResourceResolver = resolver };
var validator = new Validator(settings);
var patient = new Patient();
var outcome = validator.Validate(patient);
Nowadays there are FHIR packages that contain these artifacts. For these packages, we’ve created a FHIR Package resolver. Here’s a snippet of how to use this:
var resolver = new FhirPackageSource(
"https://packages.simplifier.net",
new[] { "hl7.fhir.r4.core" }
);
The above example uses a package server (in this case https://packages.simplifier.net) and automatically downloads the package hl7.fhir.r4.core
to your system, unpacks it, and use this as a source for the artifacts.
When your application cannot reach the internet, you can download the package yourself, place it in your solution and use the following statement:
var resolver = new FhirPackageSource(new[] { @"C:\Users\Marco\Downloads\hl7.fhir.r4.core.tgz" });
This will unpack the package and use this as a source for the artifacts. It will not perform a request on a package server.
In the next major release (5.0) we will not provide the specification.zip
anymore. Therefore, we advise you to use this FhirPackageSource
instead.
Clean-up of the SDK
We’ve used the opportunity of a new release to clean-up a bit. You will find many smaller smaller changes in this new release:
- We’ve removed methods that have been marked as
[Obsolete]
for a while - We’ve moved some classes and interfaces to the common (FHIR agnostic) libraries
- We documented almost all public methods in our SDK.
Check the release notes for a complete overview.
Where to get version 4.0 of the Firely .NET SDK?
The new 4.0 release is available on NuGet (look for Hl7.Fhir.Core
and Hl7.Fhir.Specification
). If you want to compile it yourself, make sure you checkout either the develop-stu3 or develop-r4 branch and the develop branch of the submodule repository.
Plans for the next release
The new release has only just come out, and we are already thinking about a new major release. This release will focus on bringing more classes to the FHIR agnostic libraries. Think of all normative conformance resources, like StructureDefinition
and ElementDefinition
. This allows us to bring the Validator, Snapshot Generator or FhirClient
also to the common libraries, which saves us a lot of maintenance time.
Since these conformance classes have only become normative since FHIR version 4, this may mean that we have a separate package for STU3 and one for R4 (and later). These ideas are still very early and will be further developed over the next few months. If you want to contribute ideas, let us know on our discussion page.