The next version of Kentico EMS, which will be Kentico 2020 and has a pre-production name of "Phoenix", will usher in a new era for Kentico 🤗.
Kentico's Portal Engine development architecture will be removed completely, Kentico's core libraries will target .NET Standard 2.0, and Kentico itself will support .NET Core (and therefore ASP.NET Core) 👏.
These are some major changes (and depending on your perspective, bigger than Kentico 12's move to ASP.NET MVC 5).
Kentico 2020 will likely be released, with a full suite of features, in November of 2020 (if past releases set any precedent).
But why, you ask, is Sean writing about Kentico 2020 when this blog series is about Kentico 12 🤔?!
Well there is a pretty simple answer. Unless we want our Kentico 12 sites to always run on Kentico 12, at some point, we will be upgrading them to Kentico 2020.
Below, I'd like to detail some recommendations to prepare all of us for that eventual effort, laying the groundwork now to help our future selves look back on us with kinder eyes 😊.
Since Kentico 2020 won't support Portal Engine, building a site in Portal Engine with Kentico 12 means that there isn't going to be an upgrade path - using Portal Engine today is a non-starter (unless you don't plan on upgrading).
At this point, Kentico 12 has been out for well over a year, so there are many other Kentico developers writing blog posts about their experiences with MVC, and the community on DevNet is always happy to help 💪.
Along with Portal Engine development, Kentico EMS is going to be removing several other features in Kentico 2020.
Most of the features are strongly tied to Portal Engine development, so if we are doing Kentico 12 + MVC then we probably don't have much to worry about.
But we should be familiar with the list anyway to save ourselves some heartache 💔 later.
There's also been discussions of "Related Pages" potentially being removed in Kentico 14 (or whatever comes after Kentico 2020). This is definitely not set in stone, but knowing this kind of stuff well in advance is a great reason to frequent DevNet and follow Kentico on Twitter to stay in-the-know 😉.
Although a lot looks the same when comparing MVC 5 running on ASP.NET to ASP.NET Core, there are many things that have changed.
While we could go looking for the new ASP.NET Core-ish way of doing things when we upgrade our code, it might be easier to do this ahead of time.
When it comes to managing client-side dependencies in ASP.NET MVC 5, the standard approach has been to leverage the types found in the System.Web.Optimization namespace.
Avoid the types in this namespace where possible and adopt alternative approaches to managing client-side dependencies, like the ones I mention in my post about managing front-end dependencies or Vue.js with Kentico 12 below 🤓.
While MVC 5 supports Dependency Injection using a custom Inversion of Control (Ioc) Container like Autofac, ASP.NET Core requires it for framework types and strongly encourages it for developer's custom code 😮.
Kentico's MVC 5 documentation explains Dependency Injection and how to set it up, so we already have all the tools we need to get started down this path, today 👍.
Note: We can even add Dependency Injection to the CMS, check out my blog post Kentico 12: Design Patterns Part 4 - Adding Dependency Injection to the CMS to find out how 🧐.
While MVC 5 supports C#'s
await syntax (which leads to performance gains when handling many HTTP requests concurrently), it's kinda apparent that support was added after-the-fact.
ASP.NET Core, however, takes a
await-first approach from the beginning 💪!
This means that it's no longer a question of worrying about synchronous calls to async code resulting in deadlocks 😱.
Async code should be async from top to bottom, and since ASP.NET Core allows and encourages developers to adopt this pattern, let's do it where it brings easy wins.
It should be noted that sometimes we have to use what we're given and we need to rely on what's provided in ASP.NET MVC 5, even though we know it's not there in ASP.NET Core.
For these scenarios there's another option...
The move to MVC for Kentico 12 has brought about a lot of new framework features to leverage, NuGet packages to consume, and namespaces to add
These parts of MVC are great because they help us get our work done, but they are a double-edged sword - they can be a liability 😕.
ASP.NET MVC 5 was built on
System.Web and a large part of the original motivation behind ASP.NET Core was to get away from
System.Web (it was modeled after ASP.NET Web API's independence of
System.Web using OWIN 🤯).
This means any code that relies on
System.Web could see its types moved, or worse, removed in ASP.NET Core ☹.
A lot of MVC 5 features are still in ASP.NET Core, but because of the changes, my advice is to put your use of ASP.NET specific types behind abstractions.
What would this look like 🤔?
System.Web.Routing.RouteCollection, and especially
System.Web.HttpContext can be put behind custom interfaces that we create, instead of being spread throughout our codebase.
Below is an example:
public interface IUrlBuilder
public class MVCUrlBuilder : IUrlBuilder
public string BuildUrl(
var requestContext = HttpContext.Current.Request.RequestContext;
var urlHelper = new UrlHelper(requestContext);
This might seem like a weird thing to do since we created a new interface and class to do the same things that
UrlHelper already did.
However, if we use this interface (along with Inversion of Control and Dependency Injection) throughout our codebase, we've removed a dependency on
HttpContext (both of which are in
As a side bonus, by removing dependencies on things like
HttpContext, our code becomes a lot more unit testable 💪.
I cover this topic further in my blog post Kentico 12: Design Patterns Part 1 - Writing Testable Code.
On the topic of tests, an upgrade from ASP.NET MVC 5 to ASP.NET Core is likely going to involve a lot of moving pieces, especially if it's being performed at the same time as a Kentico upgrade.
How can we ensure that our app's behavior still reflects the expectations of the stakeholders? How can we make this kind of change without disrupting the business and site visitors, from a functionality perspective 🤷♂️?
Integration tests can go a long way towards ensuring that business logic behavior is well defined, the units of our code play nice together, and this verification can be automated and reproducible 😉.
If we need more guarantees, end-to-end (E2E) tests can prove that the sign-up form or checkout experience is functioning as required, despite the fact that we've just pulled the framework-as-tablecloth out from underneath the dishes.
Never written an integration test? Learn how in my post Kentico 12: Design Patterns Part 8 - Setting Up Integration Tests.
.NET Standard 2.0 and ASP.NET Core have been out for a little while now (ASP.NET Core is currently at version 3.1) and a large part of the .NET community has updated their libraries and tools to support these newer targets.
However, since the adoption of ASP.NET Core is likely to be a new thing for a lot of Kentico developers, there could be some skeletons in our closets - libraries that are no long maintained or haven't yet been upgraded.
The last thing we want to happen is, halfway through a Kentico upgrade, realize that the library we depend on can't come with us, due to incompatibility, and needs to be replaced 😞.
So, we can check our dependencies now and plan for the future with alternatives if necessary 👍.
In addition to external library dependencies, we are probably using some libraries that we've written ourselves.
As library authors, there's a couple things that we can do to help prepare for a future of Kentico 2020 built with ASP.NET Core.
Along with the changes to the runtime and frameworks, the move to .NET Core brings changes to the tooling.
One that many developers will probably notice is the update to the
.csproj file that defines a .NET project. This new
.csproj format is called is related to the new Common Project System for .NET and is often referred to as SDK-Style 🤔.
Initially this change was delivered as something specific to .NET Core, but it is also supported for .NET Framework class libraries.
Last year, in my post Kentico 12 Class Libraries with Modern .NET Core Features, I detailed how Kentico developers can start leveraging the new
.csproj brings many quality-of-life changes for developers, which means it's not just a technical change with no benefit.
There's an old proverb I'm reminded of...
"The best time to update to the SDK-Style project was 3 years ago. The second best time is now" - Sean G. Wright 🤣
While we're updating the project format, we might as well update the target framework!
Since the interop between .NET Core and .NET Framework has lots of sharp edges, and since we can't use
System.Web with ASP.NET Core, upgrading our libraries to .NET Standard 2.0 is a great next step.
Microsoft provides a "portability analyzer" that can show the bits of framework not supported in a library if it were to be upgraded to .NET Core 🙂.
If we've managed to isolate those ASP.NET types that don't exist in ASP.NET Core, we might be able to update our libraries without downstream consumers (our Kentico applications) being effected 😁.
Preparing our Kentico applications for Kentico 2020 can seem daunting! It very well might be if we're tasked with it next year and we didn't formulate a plan.
However, there are several things we can do to put ourselves and our code in the best place possible when that upgrade day comes.
- Adopt Kentico + MVC instead of Portal Engine
- Identify which Kentico EMS features are being removed in Kentico 2020
- Write our MVC 5 code like it's ASP.NET Core
- Leverage Dependency Injection
awaitfrom the top -> down in our applications
- Isolate ASP.NET specific types behind abstractions when we need to use them
- Ensure consistent application behavior after upgrades with automated integration and end-to-end tests
- Check 3rd part NuGet dependencies for ASP.NET Core compatibility
- Update our internal libraries
- Migrate to SDK-Style
- Target .NET Standard 2.0 where possible
- Migrate to SDK-Style
Wow, that was a lot! If you haven't read any of my Kentico blog posts before, this could be like drinking from the firehose 🚒🔥👨🚒.
Fortunately we still have time, before Kentico 2020 is out, to adopt the things I mentioned in this blog post. Maybe it will make for a good starting point to plan your upgrade strategy 👐!
As always, thanks for reading 🙏!
If you are looking for additional Kentico content, checkout the Kentico tag here on DEV:
Or my Kentico blog series: