Root / Assembly / ARCCore / AREnumType / DocumentationOnlyEnum / ARConcepts / _Member / PropertyAccess
|Description||The general mechanism for accessing properties of objects in AgoRapide.|
Implemented through the IP (IProperty) interface mechanism.
In applications with lot of different data fields it might be difficult to 1) Specify from the beginning exactly which fields you need, 2) To decide if they are actually available at the stage of processing, 3) To explain them in logs and debug-messages and 4) To implement storage for them.
This can lead to a messy bug-prone implementation because you have to make assumptions about the data available, or you just leave out desired functionality because of a constant need for generating boilerplate code just to accomplish what is really a trivial task that should be inbuilt / automated somehow from the beginning.TODO: CLARIFY SENTENCE ABOVE.
AgoRapide uses a standardized generic mechanism for accessing properties of objects. It is implemented through the IP (IProperty) interface mechanism
This means that for every field / property you have concepts like the following ready for use:
1) Both Get and TryGet are always available. Get will throw a detailed exception if not successful (see default interface methods in IP like TryGetV)
2) Get has the choice of a default value to return if not successful (instead of throwing an exception) (see default interface methods in IP like -GetV-).
3) Meta-information for a property, like who created it or how old it is (see PP like Cid and Created).
4) Defining cardinality like single, multiple and so on (with corresponding validation and parsing) (see Cardinality).
5) Whether the field is obligatory or not (see IsObligatory).
6) Default value (see DefaultValue).
7) Guard against multiple setting of same property (see -SetP- versus AddP, the latter throws a -KeyAlreadyExistsException- for multiple attempts to set a property)
TODO: Regarding 7), introduce in PKTypeAttribute a setting for this (SetOnlyOnceAllowed or similar)
TODO: but remember that must then be honoured by all implementations of AddP and
TODO: you must also think through implications when updating object from the property stream
At the entity level (IP-level), you get the following:
1) Automatic assertion of integrity (assertion that IsObligatory values are set for instance, see AssertIntegrity).
2) An automatic ToString() method for your objects (not even with boilerplate auto-generated code but all automatically from within the framework itself).
TODO: Actually not implemented as of May 2020, but 'easily done'.
3) A truly 'deep' copy is always possible (see DeepCopy).
4) Changes are automatically logged (see log and ExposingApplicationState).
See also ITypeDescriber which extends the idea of a standardized parsing and validation mechanism to single property-values also
|LongDescription||FAQ: How does the PropertyAccess mechanism work with inheritance?|
Classes can of course have inheritance but accessing the properties may be a little non-intuitive.
For instance, for ClassAttribute, the property Description from the base type BaseAttribute is also present. Unfortunately you get little help from tools like Intellisense in Visual Studio to remember this (unless you implement BoilerplateCodeProperties).
However, all the information is contained within TaggingOfPropertyKeys so ARCAPI for instance (with help from ARCQuery) can communicate the relationships clearly to the outside, for instance expressed in Graph QL SDL.
In general this way of storing properties incidentally also helps with issues like
1) Enabling the AgoRapide concept of PropertyStream like serialization (see ToPropertyStream and
deserialization (see TryParse),
Some drawbacks of this mechanism are of course:
1) The risk of increased memory usage. See - MemoryConsumption - for more details about this.
2) Convoluted syntax when accessing properties. This can be alleviated by implementing traditional setters / getters, using the standardized property access mechanism 'behind the scene'.
3) Less static strong typing than what is default in C# (see for instance -AssertTypeIntegrity-).
NOTE: All these drawbacks, 1), 2) and 3) can be alleviated by using traditional setters / getters, and also traditional storage. See respectively BoilerplateCodeProperties and BoilerplateCodePropertiesAndStorage for a more detailed explanation.
Generated 2020-10-13 11:11:01.172 UTC