Tags: OnTopicCMS/OnTopic-Library
Tags
5.2.0 Release OnTopic 5.2.0 introduces support for response caching (#89), a new `ErrorController` for HTTP error codes (#91), and improvements to `ITopicMappingService` performance via optional `AttributeDictionary` constructors (#99), updates to the internal reflection libraries (#90), and caching of compatible properties (#102). In addition, it also includes a number of internal code improvements, such as adoption of new C# 10 capabilities (#96), including global using directives (#93). For a full roll-up of new features, improvements, and code changes, see Pull Request #108.
5.1.0 Release OnTopic 5.1.0 is a minor release which introduces support for mapping constructor parameters (#35) and defining what model to use when mapping associations via the `[MapAs()]` attribute (#41). Primarily, however, it is focused on bug fixes, and resolves a number of priority issues, such as an exception which occurs when deleting topics with associations (#47), topics with deleted references being treated as _unresolved_ (#46), and the inability to move a first child to another parent (#76). Finally, it also includes a number of improvements, such as checking type compatibility before mapping an association (#83), migrating the unit tests to xUnit.net (#66), and establishing integration tests for ASP.NET Core (#39). For a full rollup of new features, improvements, and bug fixes, see Pull Request #85.
The first release candidate for OnTopic 5.1.0. This is expected to be… … ready for deployment in production scenarios. It is feature and code complete, and well tested, though some minor bugs may remain.
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.
This update includes a few minor features, most notably improvements … …over routing and reporting for the ASP.NET Core `TopicController`. In addition, it upgrades the underlying code to C# 9.0 in order to take advantage of some new features such as improved pattern matching and implicitly typed initializers. Features - Updated `[ValidateTopic]` attribute to redirect to canonical URL to ensure consistency in analytics, indexes (0edab34) - Updated `Topic.Load(RouteData)` extension to return null if an invalid `Key` is submitted (b303f13); this results in the `TopicController` treating incorrect topic paths (e.g., `/Web/!@~/`) as 404s instead of exceptions - Added support for enabling (`IsIndexed`) and configuring (`IndexLabel`) an optional table of contents to the `ContentListTopicViewModel` (e9ccb06) Bug Fixes - Fixed issue with where the delegate is validated in the `HierarchicalTopicMappingService.GetViewModelAsnc()` method (69dff49) Improvements - Updated code to use C# 9.0 pattern matching and implicitly typed initializers (d63f2b5) - Updated to latest versions of internal packages, and implemented (4838da8) - Updated to latest version of Code Analysis and fixed most issues introduced with C# 9.0 (089c96a) Note: There are some Code Analysis false positives that remain with C# 9.0. Those are presumably fixed with the new `Microsoft.CodeAnalysis.NetAnalyzers` 5.0.0. There appears to be a bug in getting that to work with .NET 3.x projects, however, so it's not yet implemented.
This update focuses primarily on minor feature improvements, such as … …new extension methods for `Topic` (7d08ac6) and `AttributeValueCollection` (9795dd1), as well as new utility functions in the SQL schema (1e9b1d5), such as `GetUniqueKey()` (a2ac659) and `GetTopicIDByUniqueKey()` (ea97f91). It also includes a number of bug fixes as well as some cleanup. Most notably, it fixes a bug where existing attributes values cannot be reset to empty under certain circumstances—notably include those involving the OnTopic Editor (1e4812f). Features and Improvements - Added `MarkClean()` methods to `AttributeValueCollection` to improve the semantics for `IsDirty` tracking and to better account for deleted attributes (1e4812f) - Added `FindAll()` (4dbf872), `FindFirstParent()` (aa54ccf), and `GetContentTypeDescriptor()` (026e7a3) extension methods for `Topic` (7d08ac6) - Added `GetDouble()` (148a1b1) and `SetDouble()` (23f9ce2) extension methods to `AttributeValueCollection` (9795dd1) - Added `GetChildTopicIDs()` (8e0eca5) and `FindTopicIDs()` (1dfd333) functions in order to facilitate tree traversal and lookups in SQL - Added `GetUniqueKey()` (a2ac659), `GetTopicIDByUniqueKey()` (ea97f91), and `GetExtendedAttribute()` (28a4694) functions, as well as a `UniqueKeyIndex` view (b09ca5d) to the SQL database schema (1e9b1d5) - Added and implemented (68492d2) the `AddOrReplace()` (cd92791) and `TryAdd()` (027ae25) methods to the `StaticTypeLookupService` to simplify inheritance (6687431) - Significant updates to `GenerateNestedSet` to support transactions and topic ordering, while eliminating the need for `Topics.RangeRight` to allow `NULL` (c6b50f3) Bug Fixes - Fixed a bug where a deleted attribute might not get saved since deleted attributes didn't result in the `AttributeValueCollection` being marked as `IsDirty()` (1e4812f) - Updated `GetAttributes()` stored procedure as a function (aa040ef) to return the latest version of both indexed and extended attributes (05ae378) - Used UTC time for `@Version` parameter when updating the database via `SqlTopicRepository.Save()` to avoid time mismatches between computers (d85743d) - Updated `RelatedTopicCollection.RemoveTopic()` to remove reciprocal `IncomingRelationships` in order to avoid stale content or orphaned references (4514244) - Improved validation for `TopicRepositoryBase.Delete()` (67b70ca), including checks for `isRecursive` mismatches (29c904a) and orphaned `DerivedTopic`s (58057e1), as well as handling of orphaned relationships (13e4fe9, 2550779) Cleanup - Cleanup of SQL objects (c997b0e), including moving `UniqueKeyIndex` (4a17205), `LeftRightRange` (e565f0e), and `Hierarchy` (now `AdjacencyList`) to the `Utilities` schema (17b98b4), and removal of legacy `SimpleIntListToTbl` and `Split` functions (f0e781b). - Applied updates based on new code analysis warnings (b00cfad) Potentially Breaking Changes - Moving, renaming, and deleting of utility objects in SQL database schema (c997b0e) - Setting default for `ITopicRepositoryBase.Delete()`'s `isRecursive` parameter from `false` to `true` to maintain backward compatibility (1773113) Note: These aren't expected to break any actual implementations. In particular, utility objects are not referenced from the products, and most weren't previously documented, so it's not expected that they would have been integrated with or called from third-party implementations. Similarly, while the change to `ITopicRepositoryBase.Delete()` changes the default, it does so to _avoid_ a behavioral change.
PreviousNext