Skip to content

Commit c27e6a2

Browse files
committed
Merge branch 'release/5.0.0' into master
OnTopic 5.0.0 is a major release primarily focused on reliability and tidying up the interface. It includes a significant number of breaking changes—though only a handful of them will affect most implementers. - **Metapackage:** Established `OnTopic.All` metapackage which includes a reference to all of the core packages and implementations (c15bf2e). - **SourceLink:** Configured `SourceLink` with references to GitHub commits so that packages can be properly debugged by implementers (f7fb979). - **IntelliSense:** The NuGet packages now include the XML documentation, thus allowing implementers to benefit from IntelliSense annotations in Visual Studio (219ece4). - **Lookup Fallback Types:** Allow multiple fallback types to be defined when calling `ITypeLookupService.Lookup()` (ab4253d). - **Topic References:** Introduced support for keyed topic references via `Topic.References`, with full support for enforcing business logic (31144cc). - **Full Versioning Support:** Introduced versioning support for `Relationships` and `TopicReferences`, in addition to the previous support for versioning in `Attributes` and `ExtendedAttributes` (0e808ea). - **Repository Caching:** Established a `ITopicRepository.Refresh()` interface (3d51b14), `SqlTopicRepository.Refresh()` implementation (6dbf973), as well as a `GetTopicUpdates` stored procedure (0f36947) to allow occasional cache updates without needing to reload the entire topic graph (164de05). - **Contextual Loading:** When calling `ITopicRepository.Load()`, an optional `referenceTopic` can now be passed; this allows individual topics or topic branches to be loaded, while still being able to connect relationships and topic references to elsewhere in the topic graph (180526e). It can also be used to update topics already in the topic graph. - **Resolve Associations:** `TopicRepository.Save()` will now recurse over `Children` and attempt to resolve unresolved associations, such as relationships and topic references (fdd0025, e703de5); previously, this had to be implemented by each individual implementation. - **Repository Events:** `ITopicRepository` now supports the `TopicLoaded` and `TopicSaved` events, in addition to the previous `TopicRenamed`, `TopicMoved` and `TopicDeleted` events (37b38f5). - **C# 9.0 Records:** Introduced support for mapping C# 9.0 records with `init` setters in the topic mapping services (75dea66, 145c2a4) and updated all view models and binding models from read/write classes to C#'s new read-only, immutable `record` types (10d0652). - **Core Attributes:** `TopicKey`, `ContentType`, and `ParentID` are now first-class columns in the `Topics` table (c50f44d), greatly simplifying querying for the core attributes. - **SQL Unit Tests:** Introduced unit tests for stored procedures and functions for SQL Server database schema (91e3fe4) as well as for the `SqlDataReader` extension methods used by `SqlTopicRepository` (b91c292), thus offering far more assurances over the correctness and regression testing. - **Post-Exception Business Logic Enforcement:** If an exception occurs while enforcing business logic on `Topic.Attributes`, the request will be de-registered, thus ensuring any subsequent attempts to set an item with the same key will have business logic enforced (1b5dd5b). Previously, the exception could prevent that process from being completed, thus introducing a potential loophole during subsequent actions. - **Track Deleted Attributes:** Ensured that `AttributeCollection.Clear()` correctly marked the collection as `IsDirty()`, if appropriate, by accounting any `DeletedAttributes` (ce3cc43). - **Track Attribute Reversions:** Ensured that all modified `AttributeRecord` instances in a `TopicRepositoryBase.Rollback()` operation were correctly marked as `IsDirty`, thus ensuring they would be properly `Save()`d (e77d8eb). - **Allow Duplicate Topic Keys in Relationships:** The `Topic.Relationships` collection now allows relationships to different topics with the same `Topic.Key` (66ccd9d). Previously, this used a `KeyedTopicCollection`, which artificially restricted it to relationships with a unique `Key`. - **Allow Duplication Topic Keys in `FindAll()`:** Fixed a bug in the `Topic.FindAll()` extension methods which prevented it from returning multiple topics which the same `Key`, even if they represented different entities (75f6369). - **Track Version in Reversion:** Fixed bug in the `GetTopicVersion` stored procedure which resulted in the `Version` column not being returned for `Attributes` or `ExtendedAttributes`, and thus the `AttributeRecord.LastModified` not being properly updated during e.g. a `Rollback()` (622d575). In practice, this didn't harm anything, but it prevented removal of legacy schema validation which explicitly looked for the `Version` column. - **Map Overriden Members and Overloaded Methods:** Resolved an issue where the `MemberInfoCollection<T>`—used by the topic mapping services—would throw an exception if an overloaded or overridden member was present on a type (75dea66). Now, it will simply defer to the first or most derived instance of a member, and ignore all others. This enables support for C# 9.0 records, which have an implicit compiler-injected override, and is also a logical default for most scenarios where this might occur. - **Allow Multiple Roots:** Fixed bug where calling the `CreateTopic` or `MoveTopic` stored procedures with a `null` `@ParentID` would result in a corrupted hierarchy (500ca09). This isn't an expected use case, but we obviously want to make sure there's no risk of corrupting the hierarchy if it does occur. - **Stored Procedure Errors:** Fixed the `RAISERROR()` calls in the `MoveTopic` stored procedure; these weren't working correctly due to a formatting bug (bfdec1c). For a quick summary of all renamed and removed types, members, and methods, see #27. - **.NET Framework Support:** Removed support for .NET Standard 2.0 and, thus, .NET Framework; this effectively ends support for **OnTopic-WebForms**, **OnTopic-MVC**, and **OnTopic-Editor-WebForms** (b3ba1a0). - **`Topic.DerivedTopic`:** Renamed `Topic.DerivedTopic` to the more semantically accurate `Topic.BaseTopic` (2486ab2). This breaks not only calls to `Topic.DerivedTopic`, but also database records for e.g. `ReferenceKey`s storing the `DerivedTopic` value. The OnTopic 5.x database migration script addresses the data aspects of the migrations. - **Immutable View Models:** Changed all view models and binding models from read/write classes to C#'s new read-only, immutable `record` types (10d0652). This necessitates that all adopters that rely on these migrate any derived types from classes to records. - **Keyed Topic Collections:** Renamed `TopicCollection` classes (such as `TopicCollection<T>`, `ReadOnlyTopicCollection`) to `KeyedTopicCollection` (e.g., `KeyedTopicCollection<T>`, `ReadOnlyKeyedTopicCollection`) to better communicate that the items are indexed and, thus, must have a unique key, even if they represent different entities (826b93c). - **Attribute Collection:** Renamed `AttributeValueCollection` to `AttributeCollection`, and `AttributeValue` to `AttributeRecord` (f51407a). - **`TopicRelationshipMultiMap`:** The `RelatedTopicCollection` and `NamedTopicCollection` used by `Topic.Relationships` have been replaced with `TopicRelationshipMultiMap` (57ff3f9, 7129289), `ReadOnlyTopicMultiMap` (eb5c1c3), and `TopicMultiMap` (d049ea9). Care was taken to maintain the overall interface. The interface for calls to the underlying collections, however, will have changed (66ccd9d). Most notably, all write operations _must_ now go through `SetValue()`, `Remove()`, or `Clear()`. In addition, for callers iterating over the relationships, the relationship key is now `Key` not `Name`, the topics are now stored under a `Values` property, and the methods now require a full `Topic` reference, instead of just a `Topic.Key` (0d9dcd5). - **`GetValue()` Syntax:** Renamed `(ReadOnly)KeyedTopicCollection<T>.GetTopic()` to `GetValue()` (6674c7d); on `TopicRelationshipMultiMap` (i.e., `Topic.Relationships`), renamed `GetAllTopics()`, `GetTopics()`, `RemoveTopic()`, and `ClearTopics()` to `GetAllValues()`, `GetValues()`, `Remove()`, and `Clear()` for consistency with other collections, and especially the `TrackedRecordCollection` used by `AttributeCollection` and `TopicRelationshipCollection` (34a8c52). - **`OnTopic.Lookup` namespace:** Consolidated all `ITypeLookupService` implementations into a new `OnTopic.Lookup` namespace (f80e084). - **`Load()` by Unique Key:** Modified `Load(topicKey)` to instead expect a fully-qualified `UniqueKey` (e.g., `Root:Web:Products`); as part of that, renamed the `topicKey` parameter to `uniqueKey` to disambiguate usage (4c3d30f). - **Mapping Attributes:** Renamed `[Relationship()]` to `[Collection()]` (f84ae66), `[Follow()]` to `[Include()]` (7c150d8), `RelationshipType` to `CollectionType` (1daf799), and `Relationships` to `AssociationTypes` (78600fd) as part of a broader effort to establish a more consistent and unified nomenclature that distinguishes between topic associations and specific types of associations, such as `Topic.Relationships`, `Topic.References`, or `Topic.BaseTopic` (b01216e). - **Filter by Content Type:** The `[FilterByAttribute()]` attribute continues to operate as it previously did, but can no longer be used to filter by `ContentType` since content type is no longer stored in `Topic.Attributes` (4a9f5b7); instead, use the new `[FilterByContentType()]` attribute (105cfdd). If `ContentType` is used with `[FilterByAttribute()]`, an `ArgumentException` will be thrown (c68040a). - **`IRouteBuilder` Support:** Removed (deprecated) support for `IRouteBuilder` extension methods in ASP.NET Core; implementers should use end point routing via `IEndpointRouteBuilder` instead (6be993b, 19612ac). - **`NavigationViewModel`:** Replaced `CurrentKey` with `CurrentWebPath`; updated the `INavigationTopicViewModel<T>`'s `IsSelected()` method to expect a `webPath` parameter instead of a `uniqueKey` parameter (3e68b16). - **Core Attributes:** Added `@Key` and `@ContentType` to the `CreateTopic` and `UpdateTopic` stored procedures (a74389d); removed `TopicKey`, `ContentType`, and `ParentID` from the `Attributes` table; they are now in the `Topics` table (c50f44d). - **Default Attribute Values:** The `AttributeCollection` extension methods, such as `GetBoolean()` and `GetDateTime()`, no longer require that a `defaultValue` parameter be defined; if it is omitted, the default value for each datatype (e.g., `false` for `GetBoolean`) will be used (a79a0b1). - **`TrackedRecordCollection<>`:** Established new `TrackedRecordCollection<>` and base `TrackedCollection<>` to handle `IsDirty` tracking and enforcement of business logic in keyed collections associated with a particular topic; this is now the base class for both `AttributeCollection` and `TopicReferenceCollection` (8b9ae46). - **`Topic.IsDirty()`:** Introduced `Topic.IsDirty()` method to aid in state tracking; optionally, this can optionally call `AttributeCollection.IsDirty()` and `RelatedTopicCollection.IsDirty()` via the `checkCollections` parameter (a8feb6d, f7d36f0). - **`Topic.MarkClean()`:** Introduced `MarkClean()` method to `Topic` (28ea6ea, 48e8ed4) and `RelatedTopicCollection` (c37934b). - **`ITrackDirtyKeys`:** Introduced a new `ITrackDirtyKeys` interface to standardize the implementation of `IsDirty()` and `MarkClean()` between `Topic` (f7d36f0), `Topic.Attributes`, `Topic.Relationships`, and `Topic.References` (c757dd3). The above is just a high-level summary of the highest impact features, changes, and improvements. For complete release notes, see Pull Request #28.
2 parents 8d921a7 + 83183b2 commit c27e6a2

File tree

323 files changed

+16803
-5167
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

323 files changed

+16803
-5167
lines changed

Directory.Build.props

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<Project>
2+
3+
<PropertyGroup>
4+
<LangVersion>9.0</LangVersion>
5+
<Nullable>enable</Nullable>
6+
<AnalysisLevel>latest</AnalysisLevel>
7+
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
8+
</PropertyGroup>
9+
10+
<PropertyGroup>
11+
<Company>Ignia</Company>
12+
<Product>OnTopic</Product>
13+
<Copyright>©2021 Ignia, LLC</Copyright>
14+
<Authors>Ignia</Authors>
15+
<PackageProjectUrl>https://github.com/Ignia/Topics-Library</PackageProjectUrl>
16+
<UseFullSemVerForNuGet>true</UseFullSemVerForNuGet>
17+
<NeutralLanguage>en</NeutralLanguage>
18+
<IncludeSymbols>true</IncludeSymbols>
19+
<EmbedUntrackedSources>true</EmbedUntrackedSources>
20+
<PublishRepositoryUrl>true</PublishRepositoryUrl>
21+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
22+
<PackageIcon>Icon.png</PackageIcon>
23+
</PropertyGroup>
24+
25+
<ItemGroup>
26+
<None Include="../Icon.png" Pack="true" PackagePath=""/>
27+
</ItemGroup>
28+
29+
<PropertyGroup Condition="'$(TF_BUILD)' == 'true'">
30+
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
31+
</PropertyGroup>
32+
33+
</Project>

Icon.png

5.33 KB
Loading

OnTopic.All/OnTopic.All.csproj

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
</PropertyGroup>
6+
7+
<PropertyGroup>
8+
<AssemblyTitle>OnTopic Library Metapackage</AssemblyTitle>
9+
<Description>Includes all core packages associated with the OnTopic Library, excluding the OnTopic Editor. Reference this package as a shorthand for establishing a reference to each of the individual packages.</Description>
10+
<OutputPath>bin\$(Configuration)\</OutputPath>
11+
</PropertyGroup>
12+
13+
<ItemGroup>
14+
<PackageReference Include="GitVersion.MsBuild" Version="5.6.6">
15+
<PrivateAssets>all</PrivateAssets>
16+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
17+
</PackageReference>
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<ProjectReference Include="..\OnTopic.AspNetCore.Mvc\OnTopic.AspNetCore.Mvc.csproj" />
22+
<ProjectReference Include="..\OnTopic.Data.Caching\OnTopic.Data.Caching.csproj" />
23+
<ProjectReference Include="..\OnTopic.Data.Sql\OnTopic.Data.Sql.csproj" />
24+
<ProjectReference Include="..\OnTopic.ViewModels\OnTopic.ViewModels.csproj" />
25+
<ProjectReference Include="..\OnTopic\OnTopic.csproj" />
26+
</ItemGroup>
27+
28+
</Project>
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*==============================================================================================================================
2+
| Author Ignia, LLC
3+
| Client Ignia, LLC
4+
| Project Topics Library
5+
\=============================================================================================================================*/
6+
using System;
7+
using System.Runtime.InteropServices;
8+
9+
/*==============================================================================================================================
10+
| DEFINE ASSEMBLY ATTRIBUTES
11+
>===============================================================================================================================
12+
| Declare and define attributes used in the compiling of the finished assembly.
13+
\-----------------------------------------------------------------------------------------------------------------------------*/
14+
[assembly: ComVisible(false)]
15+
[assembly: CLSCompliant(false)]

OnTopic.All/README.md

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# OnTopic Metapackage
2+
The `OnTopic.All` metapackage includes a reference to the core OnTopic libraries that most implementations will require. It is recommended that implementers reference this package instead of referencing each of the OnTopic packages individually, unless they have a specific need to customize which packages are referenced.
3+
4+
[![OnTopic.Data.Caching package in Internal feed in Azure Artifacts](https://igniasoftware.feeds.visualstudio.com/_apis/public/Packaging/Feeds/46d5f49c-5e1e-47bb-8b14-43be6c719ba8/Packages/3dfb3a0a-c049-407d-959e-546f714dcd0f/Badge)](https://igniasoftware.visualstudio.com/OnTopic/_packaging?_a=package&feed=46d5f49c-5e1e-47bb-8b14-43be6c719ba8&package=3dfb3a0a-c049-407d-959e-546f714dcd0f&preferRelease=true)
5+
[![Build Status](https://igniasoftware.visualstudio.com/OnTopic/_apis/build/status/OnTopic-CI-V3?branchName=master)](https://igniasoftware.visualstudio.com/OnTopic/_build/latest?definitionId=7&branchName=master)
6+
![NuGet Deployment Status](https://rmsprodscussu1.vsrm.visualstudio.com/A09668467-721c-4517-8d2e-aedbe2a7d67f/_apis/public/Release/badge/bd7f03e0-6fcf-4ec6-939d-4e995668d40f/2/2)
7+
8+
### Contents
9+
- [Scope](#scope)
10+
- [Installation](#installation)
11+
12+
## Scope
13+
The `OnTopic.All` metapackage maintains a reference to the following packages:
14+
- [`OnTopic`](../OnTopic/README.md): The core OnTopic library.
15+
- [`OnTopic.AspNetCore.Mvc`](../OnTopic.AspNetCore.Mvc/README.md): The ASP.NET Core implementation, with support for both ASP.NET Core 3.x and ASP.NET Core 5.x.
16+
- [`OnTopic.Data.Caching`](../OnTopic.Data.Caching/README.md): An `ITopicRepository` decorator for caching the topic graph in memory.
17+
- [`OnTopic.Data.Sql`](../OnTopic.Data.Sql/README.md): An `ITopicRepository` implementation for persisting topic data in a SQL Server database.
18+
- [`OnTopic.ViewModels`](../OnTopic.ViewModels/README.md): A set of reference view models and binding models mapping to the out-of-the-box schema for the standard content types.
19+
20+
## Installation
21+
Installation can be performed by providing a `<PackageReference /`> to the `OnTopic.All` **NuGet** package.
22+
```xml
23+
<Project Sdk="Microsoft.NET.Sdk.Web">
24+
25+
<ItemGroup>
26+
<PackageReference Include="OnTopic.All" Version="5.0.0" />
27+
</ItemGroup>
28+
</Project>
29+
```
30+
31+
> *Note:* This package is currently only available on Ignia's private **NuGet** repository. For access, please contact [Ignia](http://www.ignia.com/).

OnTopic.AspNetCore.Mvc.Host/Components/MenuViewComponent.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
\=============================================================================================================================*/
66
using Microsoft.AspNetCore.Mvc;
77
using OnTopic.AspNetCore.Mvc.Components;
8+
using OnTopic.AspNetCore.Mvc.Controllers;
89
using OnTopic.AspNetCore.Mvc.Models;
910
using OnTopic.Mapping.Hierarchical;
1011
using OnTopic.Repositories;
@@ -16,7 +17,7 @@ namespace OnTopic.AspNetCore.Mvc.Host.Components {
1617
| CLASS: MENU VIEW COMPONENT
1718
\---------------------------------------------------------------------------------------------------------------------------*/
1819
/// <summary>
19-
/// Defines a <see cref="ViewComponent"/> which provides access to a menu of <typeparamref name="NavigationTopicViewModel"/>
20+
/// Defines a <see cref="ViewComponent"/> which provides access to a menu of <see cref="NavigationTopicViewModel"/>
2021
/// instances.
2122
/// </summary>
2223
/// <remarks>

OnTopic.AspNetCore.Mvc.Host/Components/PageLevelNavigationViewComponent.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
\=============================================================================================================================*/
66
using Microsoft.AspNetCore.Mvc;
77
using OnTopic.AspNetCore.Mvc.Components;
8+
using OnTopic.AspNetCore.Mvc.Controllers;
89
using OnTopic.AspNetCore.Mvc.Models;
910
using OnTopic.Mapping.Hierarchical;
1011
using OnTopic.Repositories;
@@ -16,15 +17,14 @@ namespace OnTopic.AspNetCore.Mvc.Host.Components {
1617
| CLASS: PAGE-LEVEL NAVIGATION VIEW COMPONENT
1718
\---------------------------------------------------------------------------------------------------------------------------*/
1819
/// <summary>
19-
/// Defines a <see cref="ViewComponent"/> which provides access to a menu of <typeparamref name="NavigationTopicViewModel"/>
20+
/// Defines a <see cref="ViewComponent"/> which provides access to a menu of <see cref="NavigationTopicViewModel"/>
2021
/// instances representing the nearest page-level navigation.
2122
/// </summary>
2223
/// <remarks>
2324
/// <para>
2425
/// As a best practice, global data required by the layout view are requested independent of the current page. This
25-
/// allows each layout element to be provided with its own layout data, in the form of <see
26-
/// cref="NavigationViewModel{T}"/>s, instead of needing to add this data to every view model returned by <see
27-
/// cref="TopicController"/>.
26+
/// allows each layout element to be provided with its own layout data, in the form of <see cref="NavigationViewModel{T}"
27+
/// />s, instead of needing to add this data to every view model returned by <see cref="TopicController"/>.
2828
/// </para>
2929
/// </remarks>
3030
public class PageLevelNavigationViewComponent : PageLevelNavigationViewComponentBase<NavigationTopicViewModel> {
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>netcoreapp3.1</TargetFramework>
4+
<TargetFrameworks>net5.0</TargetFrameworks>
55
<UserSecretsId>62eb85bf-f802-4afd-8bec-3d344e1cfc79</UserSecretsId>
66
<IsPackable>false</IsPackable>
77
</PropertyGroup>
88

99
<ItemGroup>
10-
<ProjectReference Include="..\OnTopic.AspNetCore.Mvc\OnTopic.AspNetCore.Mvc.csproj" />
11-
<ProjectReference Include="..\OnTopic.Data.Caching\OnTopic.Data.Caching.csproj" />
12-
<ProjectReference Include="..\OnTopic.Data.Sql\OnTopic.Data.Sql.csproj" />
13-
<ProjectReference Include="..\OnTopic.ViewModels\OnTopic.ViewModels.csproj" />
14-
<ProjectReference Include="..\OnTopic\OnTopic.csproj" />
10+
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3">
11+
<PrivateAssets>all</PrivateAssets>
12+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
13+
</PackageReference>
1514
</ItemGroup>
1615

17-
</Project>
16+
<ItemGroup>
17+
<ProjectReference Include="..\OnTopic.All\OnTopic.All.csproj" />
18+
</ItemGroup>
19+
20+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*==============================================================================================================================
2+
| Author Ignia, LLC
3+
| Client Ignia, LLC
4+
| Project Topics Library
5+
\=============================================================================================================================*/
6+
using System;
7+
using System.Runtime.InteropServices;
8+
9+
/*==============================================================================================================================
10+
| DEFINE ASSEMBLY ATTRIBUTES
11+
>===============================================================================================================================
12+
| Declare and define attributes used in the compiling of the finished assembly.
13+
\-----------------------------------------------------------------------------------------------------------------------------*/
14+
[assembly: ComVisible(false)]
15+
[assembly: CLSCompliant(false)]

OnTopic.AspNetCore.Mvc.Host/SampleActivator.cs

+32-11
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111
using OnTopic.AspNetCore.Mvc.Host.Components;
1212
using OnTopic.Data.Caching;
1313
using OnTopic.Data.Sql;
14+
using OnTopic.Internal.Diagnostics;
15+
using OnTopic.Lookup;
1416
using OnTopic.Mapping;
1517
using OnTopic.Mapping.Hierarchical;
16-
using OnTopic.Reflection;
1718
using OnTopic.Repositories;
1819
using OnTopic.ViewModels;
1920

@@ -31,21 +32,22 @@ public class SampleActivator : IControllerActivator, IViewComponentActivator {
3132
/*==========================================================================================================================
3233
| PRIVATE INSTANCES
3334
\-------------------------------------------------------------------------------------------------------------------------*/
34-
private readonly ITypeLookupService _typeLookupService = null;
35-
private readonly ITopicMappingService _topicMappingService = null;
36-
private readonly ITopicRepository _topicRepository = null;
35+
private readonly ITypeLookupService _typeLookupService;
36+
private readonly ITopicMappingService _topicMappingService;
37+
private readonly ITopicRepository _topicRepository;
38+
private DateTime _cacheLastUpdated = DateTime.UtcNow;
3739

3840
/*==========================================================================================================================
3941
| HIERARCHICAL TOPIC MAPPING SERVICE
4042
\-------------------------------------------------------------------------------------------------------------------------*/
41-
private readonly IHierarchicalTopicMappingService<NavigationTopicViewModel> _hierarchicalMappingService = null;
43+
private readonly IHierarchicalTopicMappingService<NavigationTopicViewModel> _hierarchicalMappingService;
4244

4345
/*==========================================================================================================================
4446
| CONSTRUCTOR
4547
\-------------------------------------------------------------------------------------------------------------------------*/
4648
/// <summary>
47-
/// Establishes a new instance of the <see cref="SampleControllerFactory"/>, including any shared dependencies to be used
48-
/// across instances of controllers.
49+
/// Establishes a new instance of the <see cref="SampleActivator"/>, including any shared dependencies to be used across
50+
/// instances of controllers.
4951
/// </summary>
5052
/// <remarks>
5153
/// The constructor is responsible for establishing dependencies with the singleton lifestyle so that they are available
@@ -86,14 +88,28 @@ public SampleActivator(string connectionString) {
8688
/// <summary>
8789
/// Registers dependencies, and injects them into new instances of controllers in response to each request.
8890
/// </summary>
89-
/// <returns>A concrete instance of an <see cref="IController"/>.</returns>
91+
/// <returns>A concrete instance of an <see cref="Controller"/>.</returns>
9092
public object Create(ControllerContext context) {
9193

94+
/*------------------------------------------------------------------------------------------------------------------------
95+
| Validate parameters
96+
\-----------------------------------------------------------------------------------------------------------------------*/
97+
Contract.Requires(context, nameof(context));
98+
9299
/*------------------------------------------------------------------------------------------------------------------------
93100
| Determine controller type
94101
\-----------------------------------------------------------------------------------------------------------------------*/
95102
var type = context.ActionDescriptor.ControllerTypeInfo.AsType();
96103

104+
/*------------------------------------------------------------------------------------------------------------------------
105+
| Periodically update cache
106+
\-----------------------------------------------------------------------------------------------------------------------*/
107+
if (DateTime.UtcNow > _cacheLastUpdated.AddMinutes(1)) {
108+
var currentUpdate = DateTime.UtcNow;
109+
_topicRepository.Refresh(_topicRepository.Load()!, _cacheLastUpdated);
110+
_cacheLastUpdated = currentUpdate;
111+
}
112+
97113
/*------------------------------------------------------------------------------------------------------------------------
98114
| Configure and return appropriate controller
99115
\-----------------------------------------------------------------------------------------------------------------------*/
@@ -104,17 +120,22 @@ public object Create(ControllerContext context) {
104120
new SitemapController(_topicRepository),
105121
nameof(RedirectController) =>
106122
new RedirectController(_topicRepository),
107-
_ => throw new Exception($"Unknown controller {type.Name}")
123+
_ => throw new InvalidOperationException($"Unknown controller {type.Name}")
108124
};
109125

110126
}
111127

112128
/// <summary>
113129
/// Registers dependencies, and injects them into new instances of view components in response to each request.
114130
/// </summary>
115-
/// <returns>A concrete instance of an <see cref="IController"/>.</returns>
131+
/// <returns>A concrete instance of an <see cref="ViewComponent"/>.</returns>
116132
public object Create(ViewComponentContext context) {
117133

134+
/*------------------------------------------------------------------------------------------------------------------------
135+
| Validate parameters
136+
\-----------------------------------------------------------------------------------------------------------------------*/
137+
Contract.Requires(context, nameof(context));
138+
118139
/*------------------------------------------------------------------------------------------------------------------------
119140
| Determine view component type
120141
\-----------------------------------------------------------------------------------------------------------------------*/
@@ -128,7 +149,7 @@ public object Create(ViewComponentContext context) {
128149
new MenuViewComponent(_topicRepository, _hierarchicalMappingService),
129150
nameof(PageLevelNavigationViewComponent) =>
130151
new PageLevelNavigationViewComponent(_topicRepository, _hierarchicalMappingService),
131-
_ => throw new Exception($"Unknown view component {type.Name}")
152+
_ => throw new InvalidOperationException($"Unknown view component {type.Name}")
132153
};
133154

134155
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
@Html.PartialAsync("~/Views/ContentList/ContentList.cshtml")
1+
<partial name="~/Views/ContentList/ContentList.cshtml" />
22

33
<!--
44
Content Type: Content List
55
View Type: Accordion
66
View Location: ~/Views/ContentList/Accordion.cshtml
7-
-->
7+
-->

OnTopic.AspNetCore.Mvc.Host/Views/ContentList/ContentList.cshtml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@
2727
Content Type: Content List
2828
View Type: Accordion
2929
View Location: ~/Views/ContentList/Accordion.cshtml
30-
-->
30+
-->
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
@Html.PartialAsync("~/Views/ContentList/ContentList.cshtml")
1+
<partial name="~/Views/ContentList/ContentList.cshtml" />
22

33
<!--
44
Content Type: Content List
55
View Type: Indexed List
66
View Location: ~/Views/ContentList/IndexedList.cshtml
7-
-->
7+
-->
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
@Html.PartialAsync("~/Views/ContentList/ContentList.cshtml")
1+
<partial name="~/Views/ContentList/ContentList.cshtml" />
22

33
<!--
44
Content Type: Content List
55
View Type: Linked List
66
View Location: ~/Views/ContentList/LinkedList.cshtml
7-
-->
7+
-->

OnTopic.AspNetCore.Mvc.Host/Views/ContentTypes/Page.cshtml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
<!--
66
Content Type: Page
77
View Location: ~/ContentTypes/Page.cshtml
8-
-->
8+
-->

OnTopic.AspNetCore.Mvc.Host/Views/ContentTypes/PageGroup.cshtml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
<!--
44
Content Type: PageGroup
55
View Location: ~/ContentTypes/PageGroup.cshtml
6-
-->
6+
-->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
@model SlideshowTopicViewModel
2+
3+
<partial name="_PageAttributes" />
4+
5+
<h2>Attributes</h2>
6+
<ul>
7+
<li>TransitionEffect: @Model.TransitionEffect</li>
8+
</ul>
9+
10+
<h2>Collections</h2>
11+
12+
<h3>Slides</h3>
13+
@foreach (var contentItem in Model.ContentItems) {
14+
<h4>@contentItem.Key</h4>
15+
<ul>
16+
<li>Title: @contentItem.Title</li>
17+
<li>Category: @contentItem.Category</li>
18+
<li><a href="@contentItem.LearnMoreUrl">Learn More</a></li>
19+
<li><img src="@contentItem.ThumbnailImage" /></li>
20+
<li>Description: @contentItem.Description</li>
21+
</ul>
22+
}
23+
24+
<!--
25+
Content Type: Slideshow
26+
View Location: ~/Views/ContentTypes/Slideshow.cshtml
27+
-->

OnTopic.AspNetCore.Mvc.Host/Views/ContentTypes/Video.cshtml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@
1111
<!--
1212
Content Type: Video
1313
View Location: ~/Views/ContentTypes/Video.cshtml
14-
-->
14+
-->

0 commit comments

Comments
 (0)