-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathTopicController.cs
126 lines (110 loc) · 7.04 KB
/
TopicController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*==============================================================================================================================
| Author Ignia, LLC
| Client Ignia, LLC
| Project Topics Library
\=============================================================================================================================*/
using OnTopic.Mapping;
namespace OnTopic.AspNetCore.Mvc.Controllers {
/*============================================================================================================================
| CLASS: TOPIC CONTROLLER
\---------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Provides a default ASP.NET MVC Controller for any paths associated with the Ignia Topic Library. Responsible for
/// identifying the topic associated with the given path, determining its content type, and returning a view associated with
/// that content type (with potential overrides for multiple views).
/// </summary>
[TopicResponseCache]
public class TopicController : Controller {
/*==========================================================================================================================
| PRIVATE VARIABLES
\-------------------------------------------------------------------------------------------------------------------------*/
private readonly ITopicMappingService _topicMappingService;
private Topic? _currentTopic;
/*==========================================================================================================================
| CONSTRUCTOR
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Initializes a new instance of a Topic Controller with necessary dependencies.
/// </summary>
/// <returns>A topic controller for loading OnTopic views.</returns>
public TopicController(
ITopicRepository topicRepository,
ITopicMappingService topicMappingService
) {
/*------------------------------------------------------------------------------------------------------------------------
| Validate input
\-----------------------------------------------------------------------------------------------------------------------*/
Contract.Requires(topicRepository, "A concrete implementation of an ITopicRepository is required.");
Contract.Requires(topicMappingService, "A concrete implementation of an ITopicMappingService is required.");
/*------------------------------------------------------------------------------------------------------------------------
| Set values locally
\-----------------------------------------------------------------------------------------------------------------------*/
TopicRepository = topicRepository;
_topicMappingService = topicMappingService;
}
/*==========================================================================================================================
| TOPIC REPOSITORY
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Provides a reference to the Topic Repository in order to gain arbitrary access to the entire topic graph.
/// </summary>
/// <returns>The TopicRepository associated with the controller.</returns>
protected internal ITopicRepository TopicRepository { get; }
/*==========================================================================================================================
| CURRENT TOPIC
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Provides a reference to the current topic associated with the request.
/// </summary>
/// <returns>The Topic associated with the current request.</returns>
public Topic? CurrentTopic {
get {
if (_currentTopic is null) {
_currentTopic = TopicRepository.Load(RouteData);
}
return _currentTopic;
}
set => _currentTopic = value;
}
/*==========================================================================================================================
| GET: INDEX (VIEW TOPIC)
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Provides access to a view associated with the current topic's Content Type, if appropriate, view (as defined by the
/// query string or topic's view.
/// </summary>
/// <returns>A view associated with the requested topic's Content Type and view.</returns>
[ValidateTopic]
public async virtual Task<IActionResult> IndexAsync(string path) {
/*------------------------------------------------------------------------------------------------------------------------
| Establish default view model
\-----------------------------------------------------------------------------------------------------------------------*/
var topicViewModel = await _topicMappingService.MapAsync(CurrentTopic).ConfigureAwait(false);
/*------------------------------------------------------------------------------------------------------------------------
| Validate dependencies
\-----------------------------------------------------------------------------------------------------------------------*/
Contract.Assume(
topicViewModel,
$"A topic view model could not be created for the '{CurrentTopic?.GetUniqueKey()}' topic."
);
/*------------------------------------------------------------------------------------------------------------------------
| Return topic view
\-----------------------------------------------------------------------------------------------------------------------*/
return TopicView(topicViewModel, CurrentTopic?.View);
}
/*==========================================================================================================================
| METHOD: TOPIC VIEW
\-------------------------------------------------------------------------------------------------------------------------*/
/// <summary>
/// Creates a <see cref="TopicViewResult"/> object by specifying a <paramref name="viewName"/> and the <paramref
/// name="model"/> to be rendered by the view.
/// </summary>
/// <param name="model">The model that is rendered by the view.</param>
/// <param name="viewName">The optional name of the view that is rendered to the response.</param>
/// <returns>The created <see cref="TopicViewResult"/> object for the response.</returns>
[NonAction]
[ExcludeFromCodeCoverage]
public TopicViewResult TopicView(object model, string? viewName = null) =>
new(ViewData, TempData, model, CurrentTopic?.ContentType, viewName);
} //Class
} //Namespace