Skip to content

Commit e4d5545

Browse files
committed
Merge branch 'maintenance/AttributeDictionary-documentation' into develop
Introduced a description, example, and list of considerations for using the `AttributeDictionary` constructor in view models for use with the `ITopicMappingService`, thus documenting #99.
2 parents 6cdc39f + 285ec1f commit e4d5545

1 file changed

Lines changed: 37 additions & 0 deletions

File tree

OnTopic/Mapping/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ The [`ITopicMappingService`](ITopicMappingService.cs) defines a service for mapp
1313
- [Attributes](#attributes)
1414
- [ReverseTopicMappingService](#reversetopicmappingservice)
1515
- [Example](#example-1)
16+
- [`AttributeDictionary` Constuctor](#attributedictionary-constructor)
17+
- [Example](#example-2)
18+
- [Considerations](#considerations)
1619
- [Polymorphism](#polymorphism)
1720
- [Filtering](#filtering)
1821
- [Topics](#topics)
@@ -152,6 +155,40 @@ In this example, the properties would map to:
152155

153156
> *Note*: Often times, models won't require any attributes. These are only needed if the properties don't follow the built-in conventions and require additional hints. For instance, the `[Collection(…)]` attribute is useful if the collection key is ambiguous between outgoing relationships and incoming relationships.
154157
158+
## `AttributeDictionary` Constructor
159+
160+
By default, all properties are mapped via reflection. As an optimization, view models may _optionally_ include a constructor that accepts an `AttributeDictionary`, using this to assign scalar values directly to properties. Any attributes in the `AttributeDictionary` won't be mapped via reflection, thus improving performance.
161+
162+
### Example
163+
The following is an example of a constructor that accepts an `AttributeDictionary`:
164+
```csharp
165+
public class PageTopicViewModel: TopicViewModel {
166+
167+
public PageTopicViewModel(AttributeDictionary attributes): base(attributes) {
168+
Contract.Requires(attributes, nameof(attributes));
169+
ShortTitle = attributes.GetValue(nameof(ShortTitle));
170+
Subtitle = attributes.GetValue(nameof(Subtitle));
171+
MetaTitle = attributes.GetValue(nameof(MetaTitle));
172+
MetaDescription = attributes.GetValue(nameof(MetaDescription));
173+
MetaKeywords = attributes.GetValue(nameof(MetaKeywords));
174+
NoIndex = attributes.GetBoolean(nameof(NoIndex))?? NoIndex;
175+
Body = attributes.GetValue(nameof(Body));
176+
}
177+
178+
pubic PageTopicViewModel(): base() {}
179+
180+
// View model properties…
181+
182+
}
183+
```
184+
185+
### Considerations
186+
- **Mapping Properties:** If attributes in the `AttributeDictionary` are not properly mapped via the constructor, the corresponding properties will _not_ be mapped.
187+
- **Derived View Models:** If a view model is derived from another view model, it must either implement all inherited attributes, or it must pass the `AttributeDictionary` to the base class's constructor.
188+
- **Empty Constructor:** It's more efficient to use reflection if there are a small number of attributes; therefore, a view model must still include an empty constructor, as well as any annotations necessary to allow mapping via reflection.
189+
- **Strongly Typed Methods:** The `AttributeDictionary` includes strongly typed methods for retrieving supported scalar data types with conversion; these include `GetValue()` (for strings), `GetBoolean()`, `GetInteger()`, `GetDouble()`, `GetDateTime()`, `GetUri()`.
190+
- **Default Values:** If properties include default values, they should be included via a null-coalescing operator to ensure that a null value in the `AttributeDictionary` doesn't override the local defaut.
191+
155192
## Polymorphism
156193
If a reference type (e.g., `TopicViewModel Parent`) or a strongly-typed collection property (e.g., `List<TopicViewModel>`) is defined, then any target instances must be assignable by the base type (in these cases, `TopicViewModel`). If they cannot be, then they will not be included; no error will occur.
157194

0 commit comments

Comments
 (0)