Modernize Existing .NET Applications - kloia Blog
Together with the Cloud movement, its functions and benefits, Software practices and trends have been converging towards creating or migrating the applications towards a Cloud Native compliant architecture. This may include several options including
- Microservices, where you have independently deployable applications with their isolated data persistent layers which are not shared along with other services
- Polyglot architecture, where you are not tied to a homogenous stack with single programming language and data persistency option, rather using different language stacks for different purposes and also benefiting from several different types of Database and Datastore options.
- Containers, where you define all your application dependencies inside, thus guaranteeing the portability all the way from developer workstation, till production.
- Serverless, where you split your application into functions and deploy those functions to a Cloud managed cluster where you do not notice any underlying server and middleware maintenance and can define several options to trigger those services.
Furthermore to all those evolving trends, .NET Programming language is also adapting itself to those changes in the software industry. One of the major changes is cross-platform support.
.NET can also be build and run on Linux kernel based Operating Systems, which brings cost saving and also option to run .NET on Kubernetes.
Besides, as .NET is OpenSourced, this affected the support from the community in a positive way. Together with its lightweight architecture which brings higher performance compared to the previous .NET versions, .NET Core is now the defacto version of .NET for all new projects and also migration efforts towards this version from the existing legacy applications.
kloia solution: DotNet Modernization
Considering the progress and the trends both in Software in general and also in .NET in particular, kloia is providing a multi-dimensional model for the .NET modernization. There are 3 main dimensions in this model:
- .NET Core Transition: The compatibility of the existing application or the newly developed application on .NETCore
- Splitting the Monolith: Identifying the existing bounded-contexts and splitting those contexts into microservices where each context is an independently deployable code including its Database.
- Cloud Native: Exploiting the advantages of cloud computing delivery model including DevOps practices using the cloud resources managed resources like PaaS or serverless, considering a decoupled polyglot architecture model and using Kubernetes as an orchestration platform.
.NET Core Transition
There are 3 steps that can be illustrated as:
- Assess your current codebase and dependencies, create a report and roadmap
- Transition may have different paths based on the output of the initial step which makes an analysis on possible scenarios and also time cost-complexity of this is estimated. Those are the possible scenarios:
- Refactoring towards .NET Core
- Redevelopment from scratch on .NET Core
- Modernizing with *
- Mono-Project : Building and Running existing .NET applications on Linux with Mono, which is officially supported by Microsoft.
- Blazor: Build legacy .NET Windows UI applications, to be run inside a browser, thus modernising the release cycle and cross platform support, which is officially supported by Microsoft.
- Acceptance of the final state of the application
This model covers various .NET application versions and types. Here is a basic chart of the coverage and possible paths:
--- .NET Transition Paths ---
(Dotted lines mean that this path will be evaluated during the Assess phase and the thicker the line, the higher the complexity)
Splitting the Monolith
This path deals with the transition of an existing Monolith application. For that purpose, the assessment is done, from the bounded-context and Domain-driven perspective rather than .Net Core compatibility. Thus, this path is .NET Core agnostic.
There are 4 steps in that model:
1- Replatforming the current stack to a Cloud Native state with micro-refactoring wherever needed. One example can be AWS Elastic Beanstalk. This step aims to get rid of current manual operations on infrastructure and deployments, thus increasing the focus of the team for the next phase.
2- Assessment of the current code-base with the following activities:
- Domain / Bounded-Contexts Analysis
- Dependency Analysis (Libraries, domains, ...)
- Database Relation Map
The output of this step is a Value-Risk graph where we define the distinct functions and their position in the graph
Sample Risk-Value Graph
3- Pre-splitting tasks are crucial before the actual “major-refactoring” begins, the following pre-requirements should be done for the purpose of managing the unexpected incidents during the journey:
- Test Automation: Before the splitting begins, there should be enough regression test coverage which will run before each refactoring deployed to production
- Monitoring: Creating full visibility of the current stack including:
- Metrics on all levels
- Log Management
4- Refactoring for splitting the bounded-contexts in the order which is agreed with the customer
The functions, resources and services being provided by the cloud providers have been increasing and diversifying. It is very likely that you will find an equivalent service which you normally would develop yourself. Benefiting from those Cloud functions, in other words, Cloud Native approach, saves time and money.
Some of the Cloud functions that we introduce for those modernization projects are
- Managed Resources (PaaS)Databases, Key-value Stores, Message Queues, EKS
- ETL, Import/Export AWS GLue, Athena, EMR
- Object StorageS3
- TriggersVarious triggers after a specific event(i.e. File upload )
Cost Saving: Various options together with Serverless, managed resources, auto-scaling(Even scaling to 0!), Windows OS License
Performance: Moving away from IIS means getting away from various overheads together with .NET Core’s lightweight and lean architecture which boosts performance
Cloud Native: Cloud functions which make your development and deployment cycles less complex and manageable
Cross Platform: Possibility to run your workload both Windows and Linux and even on Kubernetes!
- DotNetCore Transition
- Cloud Native
- Containerization & Serverless
- Splitting the Monolith
As a conclusion, as the last major programming language which is not natively supported on Linux based Kubernetes, .NET versions =<v4.x , definitely needs to be migrated, sooner is better! If you need any any advise just ping us via dotnet at kloia.com , we will be happy to assist you!
Good luck during your journey!
Derya (Dorian) Sezen
Derya, a.k.a. Dorian, ex-CTO of an amazon.com subsidiary, is currently working as Cloud and DevOps Consultant at kloia. He has migrated 10+ companies to AWS and has been involved in Containerisation and DevOps Automation projects in a range of industries. As a AWS DevOps Professional Certified expert, Derya is mentoring the hands-on trainings.