Cofoundry 0.4 Released – .NET Core 2.1, Copy Custom Entities and more

Cofoundry | Thursday, September 6, 2018

In this release we have updated Cofoundry to target ASP.NET Core 2.1 and implemented a number of bug fixes and features. The release includes breaking changes; the ones you'll most likely encounter are mentioned here, but for a comprehensive list check out the full 0.4 release notes and do get in touch if you have any issues.

Please note that due to a tagging mishap the actual NuGet package version is 0.4.1.

Upgrading to .NET Core 2.1

Upgrading from .NET Core 2.0 to .NET Core 2.1 is a fairly painless process and is not considered a breaking change; you can find guidance from Microsoft on the upgrade process here.

There's a few ASP.NET 2.1 related changes in Cofoundry that you should be aware of when upgrading:

Compatibility Version

Cofoundry automatically sets the CompatibilityVersion to Version_2_1. In future updates we'll increment the compatibility version inline with framework updates once we've tested them with Cofoundry. You can override this behaviour by setting the compatibility version after AddCofoundry() is called e.g.

Startup

Cofoundry does not set CookiePolicyOptions or run UseHsts, UseHttpsRedirection, or UseCookiePolicy. These are outside the scope of Cofoundry and you should set them as appropriate for your application. As before, Cofoundry does handle errors and static files so there's no need to run UseDeveloperExceptionPage, UseExceptionHandler or UseStaticFiles which are shown in the Microsoft upgrade document.

A Cofoundry 0.4 equivalent of the example startup.cs file would look like this:

Duplicate custom entity

Cofoundry has always had the ability to duplicate/clone a page, but not a custom entity. We've now added that feature and also fixed page duplication so that it also copies all the block data.

To clone a custom entity, simply click the 'Duplicate' button in the admin panel and fill out the identity fields.

Referencing the ambient visual editor mode

We've added an injectable service that provides access to the visual editor mode of the request. This is useful if your displaying versioned data such as custom entities in a separate component and you want to display the correct version of the data to match the edit mode.

In the example below we use IVisualEditorStateService to get an object representing the visual editor state for request and use it to get a PublishStatusQuery value that we can use to query the blog post listing. If the visual editor is in live mode then only published blog posts will be returned from the query, otherwise the latest version (including drafts) will be returned.

Changes to custom entity sorting

We've updated the default ordering of custom entities for SearchCustomEntityRenderSummariesQuery to order by title, which puts it inline with the behavior of other custom entity queries. This is a breaking change so if you were relying on that query to return entities by the create date then you can specify the sorting explicitly on the query:

Note that if your definition implements IOrderableCustomEntityDefinition then this change does not effect custom entities with a custom set ordering.

Specifying the default sort type

Alternatively you can now set the default sorting options on the custom entity definition by implementing ISortedCustomEntityDefinition. This has the additional benefit of changing the sorting for the custom entity list view in the admin panel.

A good example of a custom entity we might want to change the sorting for is a blog post, which typically you'd want to order by publish date. Here's an example of what that might look like:

Setting the bounds of a pageable query

Cofoundry has built-in classes you can use to make paging your data models easier. You can create a query that supports paging by implementing IPageableQuery, which is usually done by inheriting from the SimplePageableQuery base class.

We've added some new extension methods to help you manage the bounds of your queries, setting the default page size and limiting the maxium page size to prevent large data requests.

Changes to transactions and message publishing

In a typical Cofoundry site it's unlikely that you'll be orchestrating transactions and dealing with messaging/events, but it's worth mentioning that the way we handle transactions has changed with this release.

I won't go into too much detail here, but our abstraction has been renamed fromITransactionScopeFactory to ITransactionScopeManager and our default implementation has moved away from using EF transactions to using System.Transactions, which was recently re-introduced in .NET Standard 2.0.

We've also added the ability for ITransactionScopeManager to queue up tasks that will execute after the transaction has completed, namely cache busting and message publishing tasks. The upshot of this is that when coordinating multiple commands that each trigger their own message publishing, you can rely on the messages only being published after the transaction has completed.

This is mostly an internal detail of Cofoundry, but if you're using transactions, particularly if you have your own DbContext, then it's worth reading up on our new entity framework and transactions documentation. The main change you'll notice with this is that completion is now an async operation which allows for async tasks to be run after the scope has completed.

Automatic database updates

Please note that this release contains automated database updates.

These will apply when you run your application for the first time so please ensure you are not connecting to production databases from your development environment and have tested the update before applying it to production systems.

Notable breaking changes

Whilst many of the breaking changes are unlikely to affect a typical Cofoundry site, there's a few that are worth highlighting here:

ApiResponseHelper.SimpleQueryResponse now returns a 404 status code if the result is null.

IEntityFrameworkSqlExecutor: All sync operations have been removed.

PropertyBuilderExtensions has been moved to Cofoundry.Core.EntityFramework namespace.

IDatabase is no longer injected, use ICofoundryDatabase.

ModelBuilder.UseDefaultConfig has been replaced with HasAppSchema because since the migration to EF Core no other configuration was being performed here other than setting the default schema.

Removed the generic versions of IOrderableCustomEntityDefinition and ICustomizedTermCustomEntityDefinition. Use the non-generic versions instead alongside the generic ICustomEntityDefinition<TDataModel>. The generic versions were a shortcut, but I think it's better to be explicit here so we don't have multiple ways of doing things which can be confusing.

VisualEditorMode has been moved from the Cofoundry.Web project to the Cofoundry.Domain project.

VisualEditorMode.Draft has been renamed VisualEditorMode.Preview

SortDirection naming has been changed from Ascending/Descending to be Default/Reversed to better describe the behaviour, this is because for publish/create date sorting the default behaviour is latest first which is not technically ascending ordering.