Skip to content

Commit

Permalink
Renamed [Relationship()] attribute to [Collection()]
Browse files Browse the repository at this point in the history
Originally, the `[Relationship()]` attribute was intended to disambiguate references to `Topic.Relationships` and `Topic.IncomingRelationships`. Almost as soon as it was conceived of, however, it was expanded to include e.g. `Topic.Children`, as well as mapped collections (i.e., strongly typed collections with compatible types), and nested topics (a specialized type of `Topic.Children`).

Technically, we can argue that all of these are types of relationships. But the name remains ambiguous and unintuitive, since it sounds specific to `Topic.Relationships`. To mitigate that, it's being renamed to `[Collection()]`, which better articulates that it's clarifying the mapping between the source collection and the target collection, independent of whether or not it's a relationship attribute.
  • Loading branch information
JeremyCaney committed Feb 3, 2021
1 parent 8b9ae46 commit f84ae66
Show file tree
Hide file tree
Showing 7 changed files with 20 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class InvalidRelationshipTypeTopicBindingModel : BasicTopicBindingModel {

public InvalidRelationshipTypeTopicBindingModel(string? key = null) : base(key, "ContentTypeDescriptor") { }

[Relationship(RelationshipType.NestedTopics)]
[Collection(RelationshipType.NestedTopics)]
public Collection<RelatedTopicBindingModel> ContentTypes { get; } = new();

} //Class
Expand Down
4 changes: 2 additions & 2 deletions OnTopic.Tests/TopicMappingServiceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -384,11 +384,11 @@ public async Task Map_Relationships_SkipsDisabled() {
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Establishes a <see cref="TopicMappingService"/> and tests whether it successfully derives values from the key and
/// type specified by <see cref="Mapping.Annotations.RelationshipAttribute"/>.
/// type specified by <see cref="Mapping.Annotations.CollectionAttribute"/>.
/// </summary>
/// <remarks>
/// The <see cref="AmbiguousRelationTopicViewModel.RelationshipAlias"/> uses <see
/// cref="Mapping.Annotations.RelationshipAttribute"/> to set the relationship key to <c>AmbiguousRelationship</c> and the
/// cref="Mapping.Annotations.CollectionAttribute"/> to set the relationship key to <c>AmbiguousRelationship</c> and the
/// <see cref="RelationshipType"/> to <see cref="RelationshipType.IncomingRelationship"/>. <c>AmbiguousRelationship</c>
/// refers to a relationship that is both outgoing and incoming. It should be smart enough to a) look for the
/// <c>AmbigousRelationship</c> instead of the <c>RelationshipAlias</c>, and b) source from the <see
Expand Down
4 changes: 2 additions & 2 deletions OnTopic.Tests/ViewModels/AmbiguousRelationTopicViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace OnTopic.Tests.ViewModels {
/// </summary>
/// <remarks>
/// <para>
/// The <see cref="RelationshipAlias"/> uses <see cref="RelationshipAttribute"/> to set the relationship key to
/// The <see cref="RelationshipAlias"/> uses <see cref="CollectionAttribute"/> to set the relationship key to
/// <c>AmbiguousRelationship</c> and the <see cref="RelationshipType"/> to <see
/// cref="RelationshipType.IncomingRelationship"/>. <c>AmbiguousRelationship</c> refers to a relationship that is both
/// outgoing and incoming.
Expand All @@ -27,7 +27,7 @@ namespace OnTopic.Tests.ViewModels {
/// </remarks>
public class AmbiguousRelationTopicViewModel: KeyOnlyTopicViewModel {

[Relationship("AmbiguousRelationship", Type=RelationshipType.IncomingRelationship)]
[Collection("AmbiguousRelationship", Type=RelationshipType.IncomingRelationship)]
public Collection<KeyOnlyTopicViewModel> RelationshipAlias { get; } = new();

} //Class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class ContentTypeDescriptorTopicViewModel {

public Collection<AttributeDescriptorTopicViewModel> AttributeDescriptors { get; } = new();

[Relationship(RelationshipType.MappedCollection)]
[Collection(RelationshipType.MappedCollection)]
[Follow(Relationships.None)]
public Collection<ContentTypeDescriptorTopicViewModel> PermittedContentTypes { get; } = new();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace OnTopic.Mapping.Annotations {

/*============================================================================================================================
| ATTRIBUTE: RELATIONSHIP
| ATTRIBUTE: COLLECTION
\---------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Provides the <see cref="ITopicMappingService"/> with instructions as to which key to follow for the relationship.
Expand All @@ -21,32 +21,32 @@ namespace OnTopic.Mapping.Annotations {
/// </para>
/// <para>
/// This attribute instructs the <see cref="ITopicMappingService"/> to instead look for a specified key. This allows the
/// target property name to be decoupled from the source's relationship key. In addition, this attribute can be used to
/// specify the type of relationship expected, which is useful if there might be ambiguity between relationship names (for
/// example, if there is a <see cref="Topic.Relationships"/> with the same key as an <see
/// cref="Topic.IncomingRelationships"/>).
/// target property name to be decoupled from the source's collection key. In addition, this attribute can be used to
/// specify the type of collection expected, which is useful if there might be ambiguity between collection names (for
/// example, if there is a <see cref="Topic.Relationships"/> with the same key as an <see cref="Topic.
/// IncomingRelationships"/>), which is not an uncommon scenario.
/// </para>
/// </remarks>
[System.AttributeUsage(System.AttributeTargets.Property)]
public sealed class RelationshipAttribute : System.Attribute {
public sealed class CollectionAttribute : System.Attribute {

/*==========================================================================================================================
| CONSTRUCTOR
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Annotates a property with the <see cref="RelationshipAttribute"/> by providing an <paramref name="key"/>.
/// Annotates a property with the <see cref="CollectionAttribute"/> by providing an <paramref name="key"/>.
/// </summary>
/// <param name="key">The key value of the relationships associated with the current property.</param>
public RelationshipAttribute(string key) {
public CollectionAttribute(string key) {
TopicFactory.ValidateKey(key, false);
Key = key;
}

/// <summary>
/// Annotates a property with the <see cref="RelationshipAttribute"/> by providing the <see cref="RelationshipType"/>.
/// Annotates a property with the <see cref="CollectionAttribute"/> by providing the <see cref="RelationshipType"/>.
/// </summary>
/// <param name="type">Optional. The type of collection the relationship is associated with.</param>
public RelationshipAttribute(RelationshipType type = RelationshipType.Any) {
public CollectionAttribute(RelationshipType type = RelationshipType.Any) {
Type = type;
}

Expand Down
6 changes: 3 additions & 3 deletions OnTopic/Mapping/Internal/PropertyConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public PropertyConfiguration(PropertyInfo property, string? attributePrefix = ""
/*------------------------------------------------------------------------------------------------------------------------
| Attributes: Determine relationship key and type
\-----------------------------------------------------------------------------------------------------------------------*/
GetAttributeValue<RelationshipAttribute>(
GetAttributeValue<CollectionAttribute>(
property,
a => {
RelationshipKey = a.Key ?? RelationshipKey;
Expand Down Expand Up @@ -248,7 +248,7 @@ public PropertyConfiguration(PropertyInfo property, string? attributePrefix = ""
/// the DTO to be aliased to a different collection name on the source <see cref="Topic"/>.
/// </para>
/// <para>
/// The <see cref="RelationshipKey"/> property corresponds to the <see cref="RelationshipAttribute.Key"/> property. It
/// The <see cref="RelationshipKey"/> property corresponds to the <see cref="CollectionAttribute.Key"/> property. It
/// can be assigned by decorating a DTO property with e.g. <c>[Relationship("AlternateRelationshipKey")]</c>.
/// </para>
/// </remarks>
Expand All @@ -269,7 +269,7 @@ public PropertyConfiguration(PropertyInfo property, string? attributePrefix = ""
/// be ambiguous between multiple collections.
/// </para>
/// <para>
/// The <see cref="RelationshipType"/> property corresponds to the <see cref="RelationshipAttribute.Type"/> property. It
/// The <see cref="RelationshipType"/> property corresponds to the <see cref="CollectionAttribute.Type"/> property. It
/// can be assigned by decorating a DTO property with e.g. <c>[Relationship("AlternateRelationshipKey",
/// RelationshipType.Children)]</c>.
/// </para>
Expand Down
2 changes: 1 addition & 1 deletion OnTopic/Mapping/Reverse/IReverseTopicMappingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace OnTopic.Mapping.Reverse {
/// Despite the differences between the <see cref="ITopicMappingService"/> and <see cref="IReverseTopicMappingService"/>s,
/// many attributes are able to be reused between them. For instance, the <see cref="AttributeKeyAttribute"/> can still
/// map a property on a binding model to an attribute of a different name on a <see cref="Topic"/>, just as the <see
/// cref="RelationshipAttribute"/> can with relationships. Other attributes, however, provde no benefit in the reverse
/// cref="CollectionAttribute"/> can with relationships. Other attributes, however, provde no benefit in the reverse
/// scenario, such as <see cref="FlattenAttribute"/> or <see cref="FilterByAttributeAttribute"/>, which really only make
/// sense in creating a "produced view" that is a subset of the original model. That is valuable when creating a view
/// model, but isn't a useful use case when working with binding models.
Expand Down

0 comments on commit f84ae66

Please # to comment.