Skip to content

Commit f137ca1

Browse files
committed
Added AttributeDictionary constructors to each of the view models
The models in `OnTopic.ViewModels` are intended to be the standard reference models used for out-of-the-box implementations of OnTopic, and should be optimized for readability and performance, while also demonstrating best practices. To this end, I've added support for the new `AttributeDictionary` constructor to each of these, thus allowing them to bypass reflection for standard scalar properties. Equally importantly, while not all implementors will choose to create `AttributeDictionary` constructors for their own view models, we want to support those who do, and do so by basing their implementation on the `OnTopic.ViewModels` library. By ensuring there's an `AttributeDictionary` constructor on every model—even models that aren't used very often and might not otherwise benefit from this functionality—we make it possible for any model in `OnTopic.ViewModels` to be subclassed and to have an `AttributeDictionary` constructor defined on that derived type without needing to implement properties of all base types. This should improve both performance of the `OnTopic.ViewModels` when used directly. while offering flexibility for implementors to fully adopt `AttributeDictionary` constructors on their own derived view models, should they choose to do so. This completes the basic implementation of the `AttributeDictionary` support for the `TopicMappingService` as required by Feature #99. That said, we still need to extend our unit tests to cover `AttributeDictionary` and the new `MapAsync()` functionality.
1 parent 8e09fc5 commit f137ca1

14 files changed

Lines changed: 221 additions & 0 deletions

OnTopic.ViewModels/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
\-----------------------------------------------------------------------------------------------------------------------------*/
1010
global using System.ComponentModel.DataAnnotations;
1111
global using System.Diagnostics.CodeAnalysis;
12+
global using OnTopic.Attributes;
13+
global using OnTopic.Internal.Diagnostics;
1214
global using OnTopic.Models;
1315

1416
/*==============================================================================================================================

OnTopic.ViewModels/TopicViewModel.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,24 @@ namespace OnTopic.ViewModels {
2020
/// </remarks>
2121
public record TopicViewModel: ITopicViewModel, ICoreTopicViewModel, IAssociatedTopicBindingModel, ITopicBindingModel {
2222

23+
/*==========================================================================================================================
24+
| CONSTRUCTOR
25+
\-------------------------------------------------------------------------------------------------------------------------*/
26+
/// <summary>
27+
/// Initializes a new <see cref="TopicViewModel"/> with an <paramref name="attributes"/> dictionary.
28+
/// </summary>
29+
/// <param name="attributes">An <see cref="AttributeDictionary"/> of attribute values.</param>
30+
public TopicViewModel(AttributeDictionary attributes) {
31+
Contract.Requires(attributes, nameof(attributes));
32+
IsHidden = attributes.GetBoolean("IsHidden")?? false;
33+
View = attributes.GetValue("View");
34+
}
35+
36+
/// <summary>
37+
/// Initializes a new <see cref="TopicViewModel"/> with no parameters.
38+
/// </summary>
39+
public TopicViewModel() { }
40+
2341
/*==========================================================================================================================
2442
| ID
2543
\-------------------------------------------------------------------------------------------------------------------------*/

OnTopic.ViewModels/_contentTypes/ContentListTopicViewModel.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,24 @@ namespace OnTopic.ViewModels {
1919
/// </remarks>
2020
public record ContentListTopicViewModel: PageTopicViewModel {
2121

22+
/*==========================================================================================================================
23+
| CONSTRUCTOR
24+
\-------------------------------------------------------------------------------------------------------------------------*/
25+
/// <summary>
26+
/// Initializes a new <see cref="ContentListTopicViewModel"/> with an <paramref name="attributes"/> dictionary.
27+
/// </summary>
28+
/// <param name="attributes">An <see cref="AttributeDictionary"/> of attribute values.</param>
29+
public ContentListTopicViewModel(AttributeDictionary attributes): base(attributes) {
30+
Contract.Requires(attributes, nameof(attributes));
31+
IsIndexed = attributes.GetBoolean(nameof(IsIndexed))?? false;
32+
IndexLabel = attributes.GetValue(nameof(IndexLabel))?? "Contents";
33+
}
34+
35+
/// <summary>
36+
/// Initializes a new <see cref="ContentListTopicViewModel"/> with no parameters.
37+
/// </summary>
38+
public ContentListTopicViewModel() { }
39+
2240
/*==========================================================================================================================
2341
| CONTENT ITEMS
2442
\-------------------------------------------------------------------------------------------------------------------------*/

OnTopic.ViewModels/_contentTypes/IndexTopicViewModel.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ namespace OnTopic.ViewModels {
1919
/// </remarks>
2020
public record IndexTopicViewModel: PageTopicViewModel {
2121

22+
/*==========================================================================================================================
23+
| CONSTRUCTOR
24+
\-------------------------------------------------------------------------------------------------------------------------*/
25+
/// <summary>
26+
/// Initializes a new <see cref="IndexTopicViewModel"/> with an <paramref name="attributes"/> dictionary.
27+
/// </summary>
28+
/// <param name="attributes">An <see cref="AttributeDictionary"/> of attribute values.</param>
29+
public IndexTopicViewModel(AttributeDictionary attributes): base(attributes) { }
30+
31+
/// <summary>
32+
/// Initializes a new <see cref="IndexTopicViewModel"/> with no parameters.
33+
/// </summary>
34+
public IndexTopicViewModel() { }
35+
2236

2337
} //Class
2438
} //Namespace

OnTopic.ViewModels/_contentTypes/PageGroupTopicViewModel.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ namespace OnTopic.ViewModels {
1919
/// </remarks>
2020
public record PageGroupTopicViewModel : SectionTopicViewModel {
2121

22+
/*==========================================================================================================================
23+
| CONSTRUCTOR
24+
\-------------------------------------------------------------------------------------------------------------------------*/
25+
/// <summary>
26+
/// Initializes a new <see cref="PageGroupTopicViewModel"/> with an <paramref name="attributes"/> dictionary.
27+
/// </summary>
28+
/// <param name="attributes">An <see cref="AttributeDictionary"/> of attribute values.</param>
29+
public PageGroupTopicViewModel(AttributeDictionary attributes): base(attributes) { }
30+
31+
/// <summary>
32+
/// Initializes a new <see cref="PageGroupTopicViewModel"/> with no parameters.
33+
/// </summary>
34+
public PageGroupTopicViewModel() { }
35+
2236

2337
} //Class
2438
} //Namespace

OnTopic.ViewModels/_contentTypes/PageTopicViewModel.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,29 @@ namespace OnTopic.ViewModels {
1919
/// </remarks>
2020
public record PageTopicViewModel: TopicViewModel, INavigableTopicViewModel {
2121

22+
/*==========================================================================================================================
23+
| CONSTRUCTOR
24+
\-------------------------------------------------------------------------------------------------------------------------*/
25+
/// <summary>
26+
/// Initializes a new <see cref="PageTopicViewModel"/> with an <paramref name="attributes"/> dictionary.
27+
/// </summary>
28+
/// <param name="attributes">An <see cref="AttributeDictionary"/> of attribute values.</param>
29+
public PageTopicViewModel(AttributeDictionary attributes): base(attributes) {
30+
Contract.Requires(attributes, nameof(attributes));
31+
ShortTitle = attributes.GetValue(nameof(ShortTitle));
32+
Subtitle = attributes.GetValue(nameof(Subtitle));
33+
MetaTitle = attributes.GetValue(nameof(MetaTitle));
34+
MetaDescription = attributes.GetValue(nameof(MetaDescription));
35+
MetaKeywords = attributes.GetValue(nameof(MetaKeywords));
36+
NoIndex = attributes.GetBoolean(nameof(NoIndex))?? false;
37+
Body = attributes.GetValue(nameof(Body));
38+
}
39+
40+
/// <summary>
41+
/// Initializes a new <see cref="PageTopicViewModel"/> with no parameters.
42+
/// </summary>
43+
public PageTopicViewModel() { }
44+
2245
/*==========================================================================================================================
2346
| SHORT TITLE
2447
\-------------------------------------------------------------------------------------------------------------------------*/

OnTopic.ViewModels/_contentTypes/SectionTopicViewModel.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,23 @@ namespace OnTopic.ViewModels {
1919
/// </remarks>
2020
public record SectionTopicViewModel : TopicViewModel {
2121

22+
/*==========================================================================================================================
23+
| CONSTRUCTOR
24+
\-------------------------------------------------------------------------------------------------------------------------*/
25+
/// <summary>
26+
/// Initializes a new <see cref="SectionTopicViewModel"/> with an <paramref name="attributes"/> dictionary.
27+
/// </summary>
28+
/// <param name="attributes">An <see cref="AttributeDictionary"/> of attribute values.</param>
29+
public SectionTopicViewModel(AttributeDictionary attributes): base(attributes) {
30+
Contract.Requires(attributes, nameof(attributes));
31+
HeaderImageUrl = attributes.GetUri(nameof(HeaderImageUrl));
32+
}
33+
34+
/// <summary>
35+
/// Initializes a new <see cref="SectionTopicViewModel"/> with no parameters.
36+
/// </summary>
37+
public SectionTopicViewModel() { }
38+
2239
/*==========================================================================================================================
2340
| HEADER IMAGE
2441
\-------------------------------------------------------------------------------------------------------------------------*/

OnTopic.ViewModels/_contentTypes/SlideshowTopicViewModel.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,23 @@ namespace OnTopic.ViewModels {
1919
/// </remarks>
2020
public record SlideshowTopicViewModel: ContentListTopicViewModel {
2121

22+
/*==========================================================================================================================
23+
| CONSTRUCTOR
24+
\-------------------------------------------------------------------------------------------------------------------------*/
25+
/// <summary>
26+
/// Initializes a new <see cref="SlideshowTopicViewModel"/> with an <paramref name="attributes"/> dictionary.
27+
/// </summary>
28+
/// <param name="attributes">An <see cref="AttributeDictionary"/> of attribute values.</param>
29+
public SlideshowTopicViewModel(AttributeDictionary attributes): base(attributes) {
30+
Contract.Requires(attributes, nameof(attributes));
31+
TransitionEffect = attributes.GetValue(nameof(TransitionEffect));
32+
}
33+
34+
/// <summary>
35+
/// Initializes a new <see cref="SlideshowTopicViewModel"/> with no parameters.
36+
/// </summary>
37+
public SlideshowTopicViewModel() { }
38+
2239
/*==========================================================================================================================
2340
| TRANSITION EFFECT
2441
\-------------------------------------------------------------------------------------------------------------------------*/

OnTopic.ViewModels/_contentTypes/VideoTopicViewModel.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,24 @@ namespace OnTopic.ViewModels {
1919
/// </remarks>
2020
public record VideoTopicViewModel: PageTopicViewModel {
2121

22+
/*==========================================================================================================================
23+
| CONSTRUCTOR
24+
\-------------------------------------------------------------------------------------------------------------------------*/
25+
/// <summary>
26+
/// Initializes a new <see cref="VideoTopicViewModel"/> with an <paramref name="attributes"/> dictionary.
27+
/// </summary>
28+
/// <param name="attributes">An <see cref="AttributeDictionary"/> of attribute values.</param>
29+
public VideoTopicViewModel(AttributeDictionary attributes): base(attributes) {
30+
Contract.Requires(attributes, nameof(attributes));
31+
VideoUrl = attributes.GetUri(nameof(VideoUrl))!;
32+
PosterUrl = attributes.GetUri(nameof(PosterUrl));
33+
}
34+
35+
/// <summary>
36+
/// Initializes a new <see cref="VideoTopicViewModel"/> with no parameters.
37+
/// </summary>
38+
public VideoTopicViewModel() { }
39+
2240
/*==========================================================================================================================
2341
| VIDEO URL
2442
\-------------------------------------------------------------------------------------------------------------------------*/

OnTopic.ViewModels/_items/CacheProfileTopicViewModel.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,27 @@ namespace OnTopic.ViewModels {
2020
/// </remarks>
2121
public record CacheProfileTopicViewModel: ItemTopicViewModel {
2222

23+
/*==========================================================================================================================
24+
| CONSTRUCTOR
25+
\-------------------------------------------------------------------------------------------------------------------------*/
26+
/// <summary>
27+
/// Initializes a new <see cref="CacheProfileTopicViewModel"/> with an <paramref name="attributes"/> dictionary.
28+
/// </summary>
29+
/// <param name="attributes">An <see cref="AttributeDictionary"/> of attribute values.</param>
30+
public CacheProfileTopicViewModel(AttributeDictionary attributes): base(attributes) {
31+
Contract.Requires(attributes, nameof(attributes));
32+
Duration = attributes.GetInteger(nameof(Duration));
33+
Location = attributes.GetValue(nameof(Location));
34+
NoStore = attributes.GetBoolean(nameof(NoStore));
35+
VaryByHeader = attributes.GetValue(nameof(VaryByHeader));
36+
VaryByQueryKeys = attributes.GetValue(nameof(VaryByQueryKeys));
37+
}
38+
39+
/// <summary>
40+
/// Initializes a new <see cref="CacheProfileTopicViewModel"/> with no parameters.
41+
/// </summary>
42+
public CacheProfileTopicViewModel() { }
43+
2344
/*==========================================================================================================================
2445
| DURATION
2546
\-------------------------------------------------------------------------------------------------------------------------*/

0 commit comments

Comments
 (0)