Skip to content

Commit 65680ef

Browse files
committed
Made INavigationTopicViewModelCore generic
This allows it to have a `Children` element that is a collection of `INavigationTopicViewModelCore` implementations, instead of limiting children exclusively to the `INavigationTopicViewModelCore` interface. This is useful in case implementers need to extend the data model.
1 parent 11b1580 commit 65680ef

3 files changed

Lines changed: 28 additions & 16 deletions

File tree

Ignia.Topics.ViewModels/NavigationTopicViewModel.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,22 @@ namespace Ignia.Topics.ViewModels {
1515
/// Provides a strongly-typed data transfer object for feeding views with information about the navigation.
1616
/// </summary>
1717
/// <remarks>
18-
/// No topics are expected to have a <c>Navigation</c> content type. Instead, this view model is expected to be manually
19-
/// constructed by e.g. a <c>LayoutController</c>.
18+
/// <para>
19+
/// No topics are expected to have a <c>Navigation</c> content type. Instead, this view model is expected to be manually
20+
/// constructed by e.g. a <c>LayoutController</c>.
21+
/// </para>
22+
/// <para>
23+
/// Since C# doesn't support return-type covariance, this class can't be derived in a meaningful way (i.e., if it were to
24+
/// be, the <see cref="NavigationTopicViewModel.Children"/> property would still return a <see cref="Collection{T}"/> of
25+
/// <see cref="NavigationTopicViewModel"/> instances). Instead, the preferred way to extend the functionality is to create
26+
/// a new implementation of <see cref="INavigationTopicViewModelCore{T}"/>. To help communicate this, the <see
27+
/// cref="NavigationTopicViewModel"/> class is marked as <c>sealed</c>.
28+
/// </para>
2029
/// </remarks>
21-
public class NavigationTopicViewModel : PageTopicViewModel, INavigationTopicViewModelCore {
30+
public sealed class NavigationTopicViewModel : PageTopicViewModel, INavigationTopicViewModelCore<NavigationTopicViewModel> {
2231

23-
public Collection<INavigationTopicViewModelCore> Children { get; set; }
24-
public bool IsSelected(string uniqueKey) => uniqueKey?.StartsWith(this.UniqueKey) ?? false;
32+
public Collection<NavigationTopicViewModel> Children { get; set; }
33+
public bool IsSelected(string uniqueKey) => uniqueKey?.StartsWith(UniqueKey) ?? false;
2534

2635
} // Class
2736

Ignia.Topics.Web.Mvc/Controllers/LayoutController.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,17 @@ namespace Ignia.Topics.Web.Mvc.Controllers {
2121
/// Provides access to views for populating specific layout dependencies, such as the <see cref="Menu"/>.
2222
/// </summary>
2323
/// <remarks>
24-
/// As a best practice, global data required by the layout view are requested independently of the current page. This allows
25-
/// each layout element to be provided with its own layout data, in the form of <see cref="NavigationViewModel{T}"/>s,
26-
/// instead of needing to add this data to every view model returned by <see cref="TopicController"/>. The <see
27-
/// cref="LayoutController{T}"/> facilitates this by not only providing a default implementation for <see cref="Menu"/>, but
28-
/// additionally providing protected helper methods that aid in locating and assembling <see cref="Topic"/> and <see
29-
/// cref="INavigationTopicViewModelCore"/> references that are relevant to specific layout elements.
24+
/// <para>
25+
/// As a best practice, global data required by the layout view are requested independently of the current page. This
26+
/// allows each layout element to be provided with its own layout data, in the form of <see
27+
/// cref="NavigationViewModel{T}"/>s, instead of needing to add this data to every view model returned by <see
28+
/// cref="TopicController"/>. The <see cref="LayoutController{T}"/> facilitates this by not only providing a default
29+
/// implementation for <see cref="Menu"/>, but additionally providing protected helper methods that aid in locating and
30+
/// assembling <see cref="Topic"/> and <see cref="INavigationTopicViewModelCore"/> references that are relevant to
31+
/// specific layout elements.
32+
/// </para>
3033
/// </remarks>
31-
public class LayoutController<T> : Controller where T : class, INavigationTopicViewModelCore, new() {
34+
public class LayoutController<T> : Controller where T : class, INavigationTopicViewModelCore<T>, new() {
3235

3336
/*==========================================================================================================================
3437
| PRIVATE VARIABLES

Ignia.Topics/INavigationTopicViewModelCore.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ namespace Ignia.Topics {
1818
/// No topics are expected to have a <c>Navigation</c> content type. Instead, implementers of this view model are expected
1919
/// to manually construct instances.
2020
/// </remarks>
21-
public interface INavigationTopicViewModelCore : IPageTopicViewModelCore {
21+
public interface INavigationTopicViewModelCore<T> : IPageTopicViewModelCore where T: INavigationTopicViewModelCore<T> {
2222

2323
/*==========================================================================================================================
2424
| PROPERTY: CHILDREN
2525
\-------------------------------------------------------------------------------------------------------------------------*/
2626
/// <summary>
27-
/// Represents a collection of child <see cref="INavigationTopicViewModelCore"/> instances.
27+
/// Represents a collection of child <see cref="INavigationTopicViewModelCore{T}"/> instances.
2828
/// </summary>
29-
Collection<INavigationTopicViewModelCore> Children { get; set; }
29+
Collection<T> Children { get; set; }
3030

3131
/*==========================================================================================================================
3232
| METHOD: ISSELECTED
@@ -35,7 +35,7 @@ public interface INavigationTopicViewModelCore : IPageTopicViewModelCore {
3535
/// Determines if the current item is selected based on the provided <paramref name="uniqueKey"/>.
3636
/// </summary>
3737
/// <param name="uniqueKey">
38-
/// The unique key to compare against the current <see cref="INavigationTopicViewModelCore"/>
38+
/// The unique key to compare against the current <see cref="INavigationTopicViewModelCore{T}"/>
3939
/// </param>
4040
bool IsSelected(string uniqueKey);
4141

0 commit comments

Comments
 (0)