-
Notifications
You must be signed in to change notification settings - Fork 863
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement polymorphism support for DynamoDB entries #3643
implement polymorphism support for DynamoDB entries #3643
Conversation
implement DynamoDBDerivedTypeAttribute for polymorphism support update nested items for V4
Can the other PR (that was targeting V3) - #3633 - be closed? |
@dscpinheiro the issue that the PR has in scope to fix was affecting AWSSDK.DynamoDBv2 3.7.104, but as @normj instructed in #3633 the fix is raised for V4 also. |
Ok, my read from Norm's comment in the other PR was that we should only make this change for V4. But I can double-check with him offline. |
@irina-herciu Can you add a change file like you did in your previous PR. https://github.com/aws/aws-sdk-net/pull/3614/files |
@irina-herciu A concern I have is a user saves the item with .NET but another parts reads the item with a different language have a mechanism that only stores the .NET type won't be portable. The AWS Kotlin SDK has similar support for polymorphism in their high level. It supports a mechanism customers can use to control the identifier for the type and they could potentially use a language neutral identifier. Can you rework this to have some sort of system that allows users to register a type conversation mapping. By default it can rely on .NET type but if a user can opt-in their own mechanism that would unblock polyglot customers. Validation should be a customer can save a item using polymorphism in our Kotlin SDK and have a way to read it back out using your changes. My understanding in the Kotlin SDK you use the |
@normj The functionality implemented of this feature is different from the 'HeterogenerousItemConverter', as the Kotlin SDK feature is designed to convert top-level items in a DynamoDB table, meaning it applies polymorphism only when retrieving or saving items at the root level and requires a custom 'AttributeConverter' to handle polymorphic nested items. |
Change file added |
@@ -71,6 +71,38 @@ public DynamoDBTableAttribute(string tableName, bool lowerCamelCaseProperties) | |||
} | |||
} | |||
|
|||
/// <summary> | |||
/// DynamoDB attribute that marks a class for polymorphism support. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add more depth to the docs. Explaining how you add multiple declaration of the attribute for each possible subtype and how the TypeDiscriminator is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added extra code comments for docs
|
||
/// <summary> | ||
/// Derived type of the Property type. | ||
/// Type must be a subclass of the Property type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if the property type is an interface? Instead of a subclass can it be a type that implements the interface?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
both interfaces and and subclasses are supported. Integration tests added cover this scenario.
@@ -243,6 +275,36 @@ public DynamoDBPropertyAttribute(string attributeName, bool storeAsEpoch) | |||
public bool StoreAsEpoch { get; set; } | |||
} | |||
|
|||
/// <summary> | |||
/// DynamoDB Polymorphic Property Attribute that marks up current member for polymorphism support. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused on the purpose of separating the attribute that goes on the type vs the property. Seems like they solve same purpose. You are giving them the option of defining the polymorphism on either the type or the property. What happens if the declaration is on both the type and the property that uses the type. Should that be allowed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reworked the implementation in order to have one single attribute for this scope. If the attribute is used on both the type and property, the property one allows more granular control, overriding or supplementing the class-level behavior.
@@ -140,6 +140,11 @@ public DynamoDBContextConfig() | |||
/// Service calls made via <see cref="AmazonDynamoDBClient"/> will always return | |||
/// <see cref="DateTime"/> attributes in UTC.</remarks> | |||
public bool? RetrieveDateTimeInUtc { get; set; } | |||
|
|||
/// <summary> | |||
/// Property indicating the name of the attribute used for derived types conversion. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expand on this documentation. I assume this is the attribute that stores the metadata used by this library to figure out the type to instantiate.
This attribute is missing listing the default attribute.
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2072", | ||
Justification = "The user's type has been annotated with DynamicallyAccessedMemberTypes.All with the public API into the library. At this point the type will not be trimmed.")] | ||
internal SimplePropertyStorage(MemberInfo member) | ||
public SimplePropertyStorage(MemberInfo member) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this being changed to public
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted to internal
@@ -341,10 +373,17 @@ internal StorageConfig([DynamicallyAccessedMembers(InternalConstants.DataModelMo | |||
/// <summary> | |||
/// Storage information for a specific class that is associated with a table | |||
/// </summary> | |||
internal class ItemStorageConfig : StorageConfig | |||
internal class ItemStorageConfig |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain why the removal of the base class? When you propose this implementation changes please give background in the PR description to help speed up PR reviews.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
StorageConfig
was removed as the base class of ItemStorageConfig
and composition used for Storage configuration in order to support multiple Storage configurations for supported derived types.
Running the branch through the internal build system for validation. |
Internal Dry run DRY_RUN-2b085cb8-c005-4606-9a0f-aafb76c2ad6e was successful |
Description
New DynamoDB Attribute added as DynamoDBPolymorphicTypeAttribute in order to add support for polymorphic types serialization and deserialization
[DynamoDBPolymorphicType("A2", typeof(ModelA2))]
Type Attribute name can be configurable from DerivedTypeAttributeName on DynamoDBContextConfig and by default uses "$type".
Motivation and Context
#2985
Testing
Integration tests added
Screenshots (if appropriate)
Types of changes
Checklist
License