# Overview of the POCO model The FHIR POCO (Plain Old CLR Object) model in the `Hl7.Fhir.Model` namespace maps FHIR resources and data types to idiomatic .NET classes. The UML diagram below shows the principal classes and interfaces and the relationships described in this chapter. Historically, the class hierarchy has evolved: in FHIR STU3 and R4 most datatypes inherited directly from `Element`. R5 introduced intermediate types such as `Base`, `PrimitiveType`, and `DataType` to better structure shared behavior. The .NET SDK adopts these concepts retroactively, so the SDK POCOs for STU3 and R4 also use these base classes. As a result, the class hierarchy shown here reflects the SDK’s unified view and applies to all supported FHIR versions, even when the original STU3 and R4 definitions did not explicitly include these intermediate types. The diagram explicitly includes `Code` and `Code`: `Code` is a SDK-specific construct (not part of the FHIR specification) that represents enumerable codes. The diagram also shows `PocoNode`; although this class is not part of the FHIR specification, it is important for integrating POCOs with code that uses `ITypedElement` and `ISourceNode`. ```mermaid classDiagram class Base { <> bool HasOverflow CompareChildren(...) TryGetValue(...) SetValue(...) EnumerateElements() } class IAnnotated { Annotations(Type) } class IAnnotatable { <> AddAnnotation(object) RemoveAnnotations(Type) } IAnnotatable --|> IAnnotated Base ..|> IAnnotatable class Element{ <> string ElementId } class PocoNode { PocoNode Parent string Name int Index IEnumerable~PocoNodeOrList~ Children() PocoNodeOrList Child(string name) } PocoNode ..|> ITypedElement PocoNode ..|> ISourceNode PocoNode *-- Base Element --|> Base BackboneElement --|> Element class BackboneElement { <> List~Extension~ ModifierExtension } note for BackboneElement "Nested classes like Patient.Contact derive from BackboneElement" class DomainResource{ <> Narrative Text List~Resource~ Contained } note for DomainResource "Most resources derive from DomainResource" Resource --|> Base DomainResource --|> Resource class DataType { <> } PrimitiveType --|> DataType class PrimitiveType { <> object JsonValue bool HasValidValue() bool TryConvertToSystemType(out Any) } note for PrimitiveType "All FHIR primitive types (e.g., FhirString, FhirBoolean) derive from PrimitiveType" Code --|> PrimitiveType class Code { string Value string Literal string System } CodeOfT --|> Code class CodeOfT { new T Value } note for DataType "Non-primitive datatypes derive from DataType" DataType --|> Element class Resource { <> string ResourceType Uri ResourceBase } note for Resource "Bundle, Parameters, Binary derive directly from Resource" ``` ## Dynamic types in the model The SDK also provides dynamic types for representing instances that do not have a compiled POCO in the SDK. The parsers create these runtime types when they encounter unknown resource types or data that have no corresponding .NET class. ```mermaid classDiagram class IDynamicType{ <> string DynamicTypeName } DynamicResource --|> DomainResource DynamicResource ..|> IDynamicType DynamicPrimitive --|> PrimitiveType DynamicPrimitive ..|> IDynamicType DynamicDataType --|> DataType DynamicDataType ..|> IDynamicType DynamicInfraResource --|> Resource DynamicInfraResource ..|> IDynamicType ``` ## Modifier extensions in the model The FHIR specification treats modifier extensions differently from regular extensions: modifier extensions convey additional information that changes the core meaning of the element they modify, and they therefore require careful handling. The SDK indicates which classes may carry modifier extensions by using the `IModifierExtendable` interface. As shown in the diagram, most typical FHIR resources support both `Extension` and modifier extensions, but some infrastructure resources such as `Bundle` and `Parameters` (which derive directly from `Resource`) do not support extensions at all. Also, primitive types may have regular `Extension` instances but cannot have modifier extensions. ```mermaid classDiagram class IModifierExtendable { <> List~Extension~ ModifierExtension } IModifierExtendable ..|> IExtendable BackboneElement ..|> IModifierExtendable BackboneType ..|> IModifierExtendable DomainResource ..|> IModifierExtendable DomainResource --|> Resource note for BackboneType "Non-primitive datatypes that can have modifier extensions derive from BackboneType" class BackboneType { <> } class IExtendable { <> List~Extension~ Extension } BackboneType --|> DataType Element ..|> IExtendable Element --|> Base Resource --|> Base DataType --|> Element ```