Skip to main content

Umbraco Package Migration to .NET Core: Criteria Providers - Leaning on Umbraco

This is one of a series of posts looking at migrating Umbraco packages to V9 and .NET Core. Other posts in this series:

  1. Introduction
  2. A False Start
  3. A Clean Start - Controllers, Services, Configuration and Caching
  4. Criteria Providers - Working With HttpContext
  5. Leaning on Umbraco
  6. Migrating Tests
  7. Extension Methods
  8. Migrations
  9. Wiring It All Up
  10. Distributing and Wrapping Up

Amends After Review

I received some useful pointers on what I've done so far in this package migration from Bjarke Berg, who heads up the .NET Core transition project at Umbraco. All of which I've now applied. The general theme from all of them is that there are more places where I could lean on existing functionality of Umbraco to help out.

Umbraco Dependency

The first step taken after creating a new project for the package was to reference the Umbraco NuGet package from the nightlies feed. He pointed out that rather than referencing Umbraco.Cms.Core, it would be better to take a reference on Umbraco.Cms.Web.Common, and by doing that, the .NET Core packages I'd previously added would come in automatically, as transitive dependencies of Umbraco. And be not having direct references, as a package developer, I won't have to explicitly update these every time Umbraco update it's dependencies.

In order to do this though, I had to update the target framework I'd selected from the package from netstandard2.0, to net5.0, to match what Umbraco.Cms.Web.Common targets. This is fine though. The only need to target a .NET standard version is for a library that is intended to work on both .NET Framework and .NET Core. For a package running on Umbraco V9, we'll only be on .NET Core, so it does no harm to target that in the first place.

Having done this, dependencies look like this:

    <PackageReference Include="MaxMind.GeoIP2" Version="4.0.1" />
    <PackageReference Include="Umbraco.Cms.Web.Common" Version="9.0.0-alpha004.20210311.16" />

Umbraco Helpers

Bjarke also pointed out a couple of places where I was using underlying .NET Core functionality, that Umbraco has already wrapped and made available via a simpler API or with some enhanced functionality. If looking to multi-target a package to two Umbraco versions, there might be an argument to avoid this, but for now there seems no reason not to use them - the package isn't going to be running anywhere of course other than within an Umbraco solution.

The first was in the replacement for uses of Server.MapPath, used to find the full path to a file on disk, for which I'd used IHostingEnvironment from Microsoft.AspNetCore.Hosting - which now I've updated to net5.0, I can see is actually depreciated for IWebHostEnvironment. Umbraco though has it's own IHostingEnvironment abstraction, found in Umbraco.Cms.Core.Hosting, which has handier methosd to use for map path operations - MapPathWebRoot and MapPathContentRoot - one of which I've used here.

For an explanation of why there are two "roots", see Marius Schulz's explanation here.

Secondly, for sessions, Umbraco provides a helper interface ISessionManager, found in Umbraco.Cms.Core.Web, and providing two methods for GetSessionValue() and SetSessionValue(). By using this I could simplify things a bit, removing my own session abstraction ISessionProvider as Umbraco is already providing an interface I can mock for unit tests. However I've actually kept my own here, which delegates to Umbraco's implementation. It's arguably at least one abstraction too many, but I like consistency! And this way all the "providers" in the package are similar in their implementation and naming.

Following Along

The repository containing the code for the migrated package is here. At the time of writing, the state of the migrated code can be seen using this link.