Skip to content

Structure of the solution starting from SDK 5.0

Marco Visser edited this page Jan 11, 2023 · 4 revisions

Introduction

With the introduction of SDK 5.0, we have deeply restructured the source code repositories. In SDK 4.0, the source for the SDK was spread out over multiple repo's and branches:

  • In the main repo (this one): a branch for every release of FHIR (develop-stu3, develop-r4, develop-r5, etcetera).
  • A "common" repo (https://github.com/FirelyTeam/firely-net-common) that contained the code shared amongst those branches.

Submitting a PR most of the time meant submitting a PR for common and one for each of the release branches. On our side, merging, unit testing, building these branches became more and more time-consuming. With the advent of R4B and R6 on the horizon, this situation became unmaintainable.

Why did these branches exist in the first place? Obviously, the generated POCO's for each FHIR release were different, and so all code depending on these POCO's (for the SDK, these are mostly the datatypes and conformance resources) had to have their own copies in their own branches. This was clearly necessary for DSTU1, DSTU2 and STU3, but as time progressed, the differences between the POCOs (and especially the more mature ones like the datatypes and conformance resources) became minimal, leading to the introduction of the "common" repo, which made it possible to have some of the common code separated off.

The introduction of the "common" repo also helped us shape our thinking around how far we could go to share resource POCOs across versions, even when there were minimal differences between them (e.g. Meta.profile changed from uri to canonical between STU3 and R4). For SDK 5.0 we have used this experience to introduce many more classes to the "common" parts of the SDK. In fact so many, that we were able to remove large swathes of code duplicated over R3/R4/R5 and we were able to completely restrucure the repository. Shared code has become the norm and it is no longer necessary to have a separate "common" repo on Github, nor is there any longer a need for separate branches. To conclude:

From SDK 5.0 on, there's one repo (this one) and one branch (develop). Things are getting back to normal!

New solution structure

The solution now consists of four logical projects:

  • The base layer (Hl7.Fhir.Base) which contains shared code amongst STU3, R4 and newer (informally called R4+). Examples are the primitive types, Resource, Bundle, OperationOutcome and all code related to them. Of course, code that was already not dependent on POCO's (everything around ITypedElement and reflection/ModelInspector) is also here.
  • The conformance layer (Hl7.Fhir.Conformance). This is code that is used by the SDK itself and that we could not (yet) share between STU3 and R4+. This is principally CapabilityStatement, CodeSystem, RelatedArtifact, StructureDefinition, ElementDefinition, ValueSet and related code (think: Snapshot generator).
  • The satellite layer (Hl7.Fhir.STU3/R4/R4B/R5) - code that is not be shared. These satellites are mostly the POCO's (that do really differ) and ModelInfo.
  • Shared code (Hl7.Fhir.Shims.*): even for the satellite projects, we were able to remove duplication of code by using shared projects. These projects mostly contain shims, wrap version-agnostic code using a shim with hard coded version specific data. An example is the FhirClient, which exists for each release (as it needs to support all resources for that release). This FhirClient class is merely a wrapper around BaseFhirClient, which passes the relevant ModelInspector into it.
  • Specification data (Hl7.Fhir.Specification.Data.STU3/R4/R4B/R5): these projects contain nothing but the specification.zip file, which means developers now have the choice which (if any) of the NuGet packages for these zips to include in their distribution.

Finally, the validator has been given its own repository (https://github.com/FirelyTeam/Hl7.Fhir.Validation.Legacy). As can be guessed from the name, this is the first step in migrating to our (as yet unpublished) new validator. We plan to do publish its replacement in a subsequent SDK 5 release.

To conclude

When you want to contribute code, it is no longer necessary to create a PR for each FHIR release of the SDK, nor do you need to cope with the common submodule anymore. There is just one repo and one branch to commit to. Also, the project structure has been simplified, so it hopefully becomes easier to navigate the SDK's source code.

Clone this wiki locally