Skip to content

Commit c61a3b0

Browse files
committed
Introduced [DisableMapping] functionality to TopicMappingService
The `[DisableMapping]` capability was originally introduced as part of the `ReverseTopicMappingService`, to instruct it not to map particular properties back the target `Topic` entity. There's no reason the opposite shouldn't also be supported on the `TopicMappingService`—nor is it all that difficult to add this feature. That said, while this feature was a necessity on the `ReverseTopicMappingService` (since it will throw an exception if a corresponding `AttributeDescriptor` can't be found) it provides less necessity on the `TopicMappingService` (since a missing attribute will simply skip over the property). Still, this may be useful for cases where a property should be provided which maps to a valid attribute, but the value should be set separately—perhaps as part of a hard-coded default. While a rare edge case, it's just a few lines of code to support this, and it eliminates the attributes supported on the `ReverseTopicMappingService` but not also the `TopicMappingService`, thus simplifying the documentation.
1 parent 58949b1 commit c61a3b0

5 files changed

Lines changed: 51 additions & 4 deletions

File tree

OnTopic.Tests/TestDoubles/FakeViewModelLookupService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public FakeViewModelLookupService() : base(null, typeof(object)) {
3939
Add(typeof(DefaultValueTopicViewModel));
4040
Add(typeof(DescendentSpecializedTopicViewModel));
4141
Add(typeof(DescendentTopicViewModel));
42+
Add(typeof(DisableMappingTopicViewModel));
4243
Add(typeof(FilteredTopicViewModel));
4344
Add(typeof(FlattenChildrenTopicViewModel));
4445
Add(typeof(InheritedPropertyTopicViewModel));

OnTopic.Tests/TopicMappingServiceTest.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,25 @@ public async Task Map_Dynamic_ReturnsNewModel() {
103103

104104
}
105105

106+
/*==========================================================================================================================
107+
| TEST: MAP: DISABLED PROPERTY: RETURNS NULL
108+
\-------------------------------------------------------------------------------------------------------------------------*/
109+
/// <summary>
110+
/// Establishes a <see cref="TopicMappingService"/> and tests whether it maps a property decorated with the <see
111+
/// cref="DisableMappingAttribute"/>.
112+
/// </summary>
113+
[TestMethod]
114+
public async Task Map_DisabledProperty_ReturnsNull() {
115+
116+
var topic = TopicFactory.Create("Test", "DisableMapping");
117+
118+
var viewModel = await _mappingService.MapAsync<DisableMappingTopicViewModel>(topic).ConfigureAwait(false);
119+
120+
Assert.IsNotNull(viewModel);
121+
Assert.IsNull(viewModel.Key);
122+
123+
}
124+
106125
/*==========================================================================================================================
107126
| TEST: MAP: PARENTS: RETURNS ASCENDENTS
108127
\-------------------------------------------------------------------------------------------------------------------------*/
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*==============================================================================================================================
2+
| Author Ignia, LLC
3+
| Client Ignia, LLC
4+
| Project Topics Library
5+
\=============================================================================================================================*/
6+
using OnTopic.Mapping.Annotations;
7+
8+
namespace OnTopic.Tests.ViewModels {
9+
10+
/*============================================================================================================================
11+
| VIEW MODEL: DISABLE MAPPING
12+
\---------------------------------------------------------------------------------------------------------------------------*/
13+
/// <summary>
14+
/// Provides a simple view model with a single property (<see cref="Key") which is annotated with the <see
15+
/// cref="DisableMappingAttribute"/>.
16+
/// </summary>
17+
/// <remarks>
18+
/// This is a sample class intended for test purposes only; it is not designed for use in a production environment.
19+
/// </remarks>
20+
public class DisableMappingTopicViewModel {
21+
22+
[DisableMapping]
23+
public string? Key { get; set; }
24+
25+
} //Class
26+
} //Namespace

OnTopic/Mapping/README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,7 @@ To support the mapping, a variety of `Attribute` classes are provided for decora
104104
- **`[Follow(relationships)]`**: Instructs the code to populate the specified relationships on any view models within a collection.
105105
- **`[Flatten]`**: Includes all descendants for every item in the collection. If the collection enforces uniqueness, duplicates will be removed.
106106
- **`[MapToParent]`**: Allows the attributes of a topic to be applied to a child complex object, optionally including a prefix.
107-
108-
### `ReverseTopicMappingService`
109-
- **`[DisableMapping]`**: Prevents the `ReverseTopicMappingService` from attempting to map the property back to the target `Topic`.
107+
- **`[DisableMapping]`**: Prevents the mapping service from attempting to map the property to an attribute.
110108

111109
### Example
112110
The following is an example of a data transfer object that implements the above attributes:

OnTopic/Mapping/TopicMappingService.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,10 @@ protected async Task SetPropertyAsync(
264264
/*------------------------------------------------------------------------------------------------------------------------
265265
| Handle by type, attribute
266266
\-----------------------------------------------------------------------------------------------------------------------*/
267-
if (SetCompatibleProperty(source, target, configuration)) {
267+
if (configuration.DisableMapping) {
268+
return;
269+
}
270+
else if (SetCompatibleProperty(source, target, configuration)) {
268271
//Performed 1:1 mapping between source and target
269272
}
270273
else if (_typeCache.HasSettableProperty(target.GetType(), property.Name)) {

0 commit comments

Comments
 (0)