-
Notifications
You must be signed in to change notification settings - Fork 345
Overview of the POCO classes and interfaces
classDiagram
direction LR
class IDeepCopyable{
DeepCopy() IDeepCopyable
CopyTo(IDeepCopyable) IDeepCopyable
}
Base --|> IDeepCopyable
class IDeepComparable{
IsExactly(IDeepComparable) bool
Matches(IDeepComparable) bool
}
Base --|> IDeepComparable
class IAnnotated{
Annotations(Type) IEnumerable<object>
}
Base --|> IAnnotated
class IAnnotatable{
AddAnnotation(object) void
RemoveAnnotations(Type) void
}
Base --|> IAnnotatable
namespace System-ComponentModel{
class INotifyPropertyChanged{
PropertyChangedEventHandler PropertyChanged
}
class IValidatableObject{
Validate(ValidationContext) IEnumerable~ValidationResult~
}
}
Base --|> INotifyPropertyChanged
Base --|> IValidatableObject
namespace System-Collections{
class IReadOnlyDictionary~string,object~{
Count
Keys
Values
TryGetValue()
}
}
Base --|> IReadOnlyDictionary
class Base{
<<abstract>>
string TypeName
IEnumerable~Base~ Children()
IEnumerable~ElementValue~ NamedChildren()
IROD AsReadOnlyDictionary()
bool TryGetValue(string, out object)
IEnumerable~KVP~ GetElementPairs()
}
class DataType{
<<abstract>>
}
DataType --|> Element
class PrimitiveType{
<<abstract>>
object ObjectValue
bool HasElements
OnObjectValueChanged() void
ToString() string
}
PrimitiveType --|> DataType
class IExtendable{
List<Extension> Extension
}
class IModifierExtendable{
List<Extension> ModifierExtension
}
IModifierExtendable --|> IExtendable
class Element{
<<abstract>>
string ElementId
}
Element --|> IExtendable
Element --|> Base
class BackboneElement{
<<abstract>>
}
BackboneElement --|> Element
class BackboneType{
<<abstract>>
}
class DomainResource{
<<abstract>>
FindContainedResource() Resource
}
BackboneElement --|> IModifierExtendable
BackboneType --|> IModifierExtendable
DomainResource --|> IModifierExtendable
class Resource{
<<abstract>>
Uri ResourceBase
object SyncLock
}
Resource --|> Base
DomainResource --|> Resource
class ISystemAndCode{
string System
string Code
}
class Code~T~{
ToSystemCode() System.Code
}
class IValue~T~{
T Value
}
class INullableValue~T~
INullableValue --|> IValue
Code --|> ISystemAndCode
Code --|> PrimitiveType
Code --|> INullableValue
-
Maybe getting the TypeName prop should throw on abstract types.
-
PrimitiveType
makes sure the IROD returns theObjectValue
when we access thevalue
element. -
Some datatypes have a static
IsValidValue(string)
that validates the verbatim string representation:- Base64Binary
- Code
- Date
- FhirBoolean
- FhirDateTime
- FhirDecimal
- FhirString
- FhirUri
- FhirUrl
- Id
- Instant
- Integer
- Integer64
- Markdown
- Oid
- Time
- UnsignedInt
- Uuid
- XHtml (multiple)
-
Some datatypes have conversion methods to convert to CQL types:
- Code
- CodeableConcept
- Code<T>
- Coding
- Date
- FhirDateTime
- Time
-
Why has
Instant
no conversion to a CQL type? -
Date
,FhirDateTime
,Time
andInstant
have lots of comparators and conversions functions. -
Bundle
has all kinds of helper methods to find, resolve and filter child resources. Note that we should have these onParameter
too probably. Convert these methods to an interface on both + extension methods? -
DomainResource
hasFindContainedResource()
. -
Canonical
has helpers to split versions and fragments. -
We have a
Bindable
attribute on classes that are bindable according to the FHIR spec. -
IValue<T>
is used by primitives where the Value is a reference type (Code, Data, Canonical, etc),INullableValue<T>
is used by non-reference types (FhirInteger, FhirBoolean etc.) -
ISystemAndCode
is only used byCode<T>
, but is useful to check whether we are dealing with "aCode<T>
" (would require something likeGetGenericDefinition()
etc to check against it otherwise). Why doesn't theCoding
POCO implement this interface as well? Are we dependent on this being one-on-one withCode<T>
? -
There are additional interfaces
IConformanceResource
,IVersionableConformanceResource
,IIdentifiable
,ICoded<T>
,IPatient
implemented by the appropriate resources. -
Remember,
BackboneElement
is used as the base class for nested classes (likePatient.Contact
), whileBackboneType
is used by data types that may have modifier extensions. -
Confusingly,
Code<T>
represents a FHIRCoding
: its enum value has both a system+code encoded in the attributes. This is probably why this is a subclass of PrimitiveType (since it has aValue
of type enum), but it is not a FHIR Primitive datatype.
- Make
IAnnotatable
a subclass ofIAnnotated
. - We should implement most of the interfaces explicitly, so we don't clutter the surface of the POCO's too much.
- We should remove
IDeepComparable
in favor of anSystem.Collections.Generic.EqualityComparer<Base>
(e.g. aExactlyEqualityComparer
and aPatternEqualityComparer
) There are several different kinds of equality defined, so this matches the usescases better. It also can be based on any of the functions to traverse the tree, it does not have to be on the class itself. -
ElementValue
should be a record, and the fields should become properties. -
Resource
has a pretty uselessVersionId
property that gets/sets theMeta.Versiond
and alsoHasVersionId
. I think we should remove it. - We should unify FhirTypeConstants and FhirTypeNames, they do the same.
- There are lots of places where we deal with Canonicals, HL7 base urls, analyzing references. We could unify these unto one or two classes.
- Find out why we have
INullableValue<T>
andIValue<T>
, since it does not seem to be used by us. It does provide typed access to theValue
property of a primitive, unlikePrimitiveType
.INullableValue
does not seem to have a use, beyond being a shorthand for doingIValue<T?>
? - We could move all the comparison logic to the Cql types that correspond to the primitives, so we only have one set. The POCO datatypes could then just invoke the Cql-based comparators etc.