Kentico 12: Design Patterns Part 18 - Preparing for Kentico 2020
Tags: kentico, mvc, aspnet, dotnet
Published: 2020-01-06 14:04:48

---
title: Kentico 12: Design Patterns Part 18 - Preparing for Kentico 2020
published: true
description: Learn how to prepare your Kentico 12 applications for the eventual upgrade to Kentico 2020 and ASP.NET Core.
cover_image: https://thepracticaldev.s3.amazonaws.com/i/ileful35fjjl47xyjphp.jpg
tags: kentico, mvc, aspnet, dotnet
series: Kentico 12 - Design Patterns
---

<figcaption>Photo by <a href="https://unsplash.com/@lsgr">Olesya Grichina
</a> on <a href="https://unsplash.com">Unsplash</a></figcaption>

## Kentico 2020: The Phoenix and .NET Core

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](https://www.kentico.com/product/roadmap), 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 😊.

---

## Adopt Kentico + MVC

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).

If you haven't adopted the awesome Kentico 12 + MVC combo, check out [Kentico's documentation on using MVC](https://docs.kentico.com/k12sp/developing-websites/mvc-development-overview) and all the other blog posts in [this series on Kentico 12 Design Patterns](https://dev.to/search?q=kentico%2012%20design%20patterns).

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](https://devnet.kentico.com/) is always happy to help 💪.

---

## Don't Rely on Removed Kentico EMS Features

Along with Portal Engine development, Kentico EMS is going to be removing several [other features in Kentico 2020](https://devnet.kentico.com/articles/phoenix-s-on-fire).

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](https://twitter.com/Kentico) to stay in-the-know 😉.

---

## Write MVC 5 Code Like It's ASP.NET Core

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.

### Don't Use `System.Web.Optimization`

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](https://docs.microsoft.com/en-us/aspnet/mvc/overview/performance/bundling-and-minification) namespace.

However, that code hasn't been updating since 2014 and _both_ CSS and JavaScript have changed _significantly_ since then.

I've run into cases where MVC started throwing exceptions (when trying to bundle and minify) because it couldn't understand my modern ES2015+ JavaScript, despite the fact that Edge/Chrome/Firefox/Safari all ran it without issue 😣.

**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 🤓.

{% link seangwright/kentico-12-design-patterns-part-5-front-end-dependency-management-5m0 %}

{% link seangwright/kentico-12-design-patterns-part-16-integrating-vue-js-with-mvc-2m90 %}

### Use Dependency Injection / IoC Container

While MVC 5 supports Dependency Injection [using a custom Inversion of Control (Ioc) Container like Autofac](https://autofaccn.readthedocs.io/en/latest/integration/mvc.html), 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](https://docs.kentico.com/k12sp/developing-websites/initializing-kentico-services-with-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 🧐.

> {% link seangwright/kentico-12-design-patterns-part-4-adding-dependency-injection-to-the-cms-35a %}

### Use `async`/`await` Where Possible

While MVC 5 supports C#'s `async`/`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 `async`/`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](https://devblogs.microsoft.com/pfxteam/should-i-expose-synchronous-wrappers-for-asynchronous-methods/) 😱.

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...

---

## Isolate ASP.NET Behind Abstractions

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 `using`s for.

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](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/owin?view=aspnetcore-3.1) 🤯).

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 🤔?

Classes like `System.Web.UrlHelper`, `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:

```csharp
public interface IUrlBuilder
{
    string BuildUrl(
        string actionName, 
        string controllerName,
        object routeValues);
}

public class MVCUrlBuilder : IUrlBuilder
{
    public string BuildUrl(
        string actionName, 
        string controllerName,
        object routeValues)
    {
        var requestContext = HttpContext.Current.Request.RequestContext;

        var urlHelper = new UrlHelper(requestContext);
        
        return urlHelper.Action(
            actionName, 
            controllerName, 
            routeValues, 
            Uri.UriSchemeHttps);
    }
}
```

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 `UrlHelper` _and_ `HttpContext` (both of which are in `System.Web`) 🎉.

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_.

{% link seangwright/kentico-12-design-patterns-part-1-writing-testable-code-258a %}

---

## Write Automated Integration and End-to-End Tests

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.

![](https://media.giphy.com/media/RdJIM4Uesg37eN1ZNL/giphy.gif)
<figcaption>This is how we want things to go</figcaption>

> Never written an integration test? Learn how in my post _Kentico 12: Design Patterns Part 8 - Setting Up Integration Tests_.

{% link seangwright/kentico-12-design-patterns-part-8-setting-up-integration-tests-14jg %}

---

## Check Our NuGet Dependencies For Compatibility

.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](https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-core-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 👍.

---

## Updating Our Internal Libraries

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.

### Migrate to the SDK-Style `.csproj` Format

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](https://natemcmaster.com/blog/2017/03/09/vs2015-to-vs2017-upgrade/) 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` now 😎.

{% link seangwright/kentico-12-class-libraries-with-modern-net-core-features-34n5 %}

> My favorite way to do this is using Hans van Bakel's [CsprojToVs2017](https://github.com/hvanbakel/CsprojToVs2017) library, however you can also watch this video from [Scott Hanselman](https://www.hanselman.com/blog/UpgradingAnExistingNETProjectFilesToTheLeanNewCSPROJFormatFromNETCore.aspx) or perform the upgrade [directly in Visual Studio](http://hermit.no/moving-to-sdk-style-projects-and-package-references-in-visual-studio-part-1/).

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 🤣

### Target .NET Standard 2.0 In Our Libraries

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"](https://docs.microsoft.com/en-us/dotnet/standard/analyzers/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 😁.

---

## In Review

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
  - Avoid `System.Web.Optimization`
  - Leverage Dependency Injection
  - Use `async`/`await` from 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 `.csproj` files
  - Target .NET Standard 2.0 where possible

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:

{% tag kentico %}

Or my Kentico blog series:

- [Kentico 12: Design Patterns](https://dev.to/search?q=Kentico%2012%3A%20Design%20Patterns)
- [Kentico CMS Quick Tips](https://dev.to/search?q=Kentico%20CMS%20Quick%20Tip)