Recently the hosts of .NET Rocks were joking with Jeff Fritz about Web Forms and the continuing support of INI files. Poking fun at it, phrases like “the 20th century called, they want their configuration files back” were bandied about. It is all in good fun, but at what point did INI files become “old”? More importantly, how can you recognize if your application is “old”?

I’ve heard (and used) vague phrases like “it’s old and crusty,” “there’s code smell,” and even “ugh, just… ugh” to describe applications. While it’s easy to display disgust with an aging application, it’s more difficult to articulate the precise reasons why time and money are well-spent updating it. Here are some signs your application could use a bit of modernization and what can be done about it.

Feature Requests Are Scary

Tell me if this feels familiar: A feature request comes in and the developers are asked for an estimate. They look at each other in fear, pause, and one haltingly starts speaking. “Well, to do that we’ll need to…” If that is more of a habit than an exception, it doesn’t matter if the end of that sentence pertains to updating dependencies, changing the architecture, or modifying the database schema, it’s an indication your app could use some modernization.

In a contrived example, maybe the feature request is a new integration with Instagram and there’s an Instagram-related NuGet package that would reduce development effort by half. That NuGet package relies on .NET 4.6.2 or above, and you are on .NET 2.0. Uh oh. Your choices are to go through the pain of updating the .NET version of your application or pay more for development. That moment might be a good time to bite the bullet and modernize your app by updating the .NET dependency, even though it might require some effort updating the code because of deprecated language features or dependencies.

And now for a public service announcement: If you have an application that is live right now and running .NET 3.0 or older, it’s time to update it. Microsoft notes on their support site, “We strongly encourage customers to migrate to .NET Framework 3.5 SP1.” Why do they strongly encourage that? For one, security. It doesn’t matter if that application is running on a box that’s disconnected from the internet, if there’s anything sensitive at all on it, please upgrade it to .NET 3.5 or better now.

It Breaks All The Time

One of the hallmarks of a modern application is resiliency. When the word “again” is appended to “it’s down” more often than not, maybe it’s time for a rethink.

Utilizing cloud technologies that automatically backup and failover, like Azure’s geo-redundancy features, are a great first step to resiliency that often require few changes to the code. Using queuing technology like Azure Service Bus to send messages between services can allow for eventual consistency of data without resorting to home-grown retry efforts.

In my experience, adding a new feature without regression tests is a recipe for breaking changes. Simply adding tests can be a boon to stability. If your application does not lend itself to testing (no dependency injection, for example), it can be helpful to throw some integration tests around the whole thing and then update the internals to be more testable.

Not In The Cloud

“The Cloud” can be a touchy subject. For CEOs that wonder why that $12,000 server they bought two years ago isn’t good enough anymore, to IT directors who fear their skills won’t translate to the cloud, to software developers who have been doing things the same way for years, “The Cloud” can be scary.

The cloud is no longer a competitive edge, it’s a competitive necessity.

There’s no need to be scared. The cloud no longer is a competitive edge, it’s a competitive necessity. If your application is living in a server on-site or even a data center on a physical server you rent, moving to the cloud can offer a litany of benefits.

For example, we have a client that was renting physical servers because their application was built to run on Windows Server. Much of the year, these physical servers were underutilized due to the seasonal nature of their business. They wanted to move to the cloud to be able to scale up and scale down their computing power as needed. Fantastic!

Their application, while hardly legacy or outdated, used MSMQ as a message queue service. Since they can gain the most scaling potential from using Azure’s Platform-as-a-Service offerings, we helped them rewrite their code to move from using MSMQ (which runs as a service on Windows Server) to using Azure Service Bus (which runs in the cloud). Now, no longer dependent on a physical server or even VMs, they can use Azure App Services to run their code and scale up and scale down as needed.

Examples like these abound, and while every application and use case is different, lifting-and-shifting from on-premises to the cloud is often an easy way to modernize your application.

Deployments Are A Circus

When your jaw is set, and the coffee machine is filled and at the ready, and you have to get a half dozen people in the War Room, your deployments could use a little help. Deployments don’t have to be a circus. There are companies out there that make it part of their process, that create a continuous delivery pipeline so that every check-in to your source control results in a deployment to a dev environment.

Making deployments a part of every day life makes it so when you do decide to go to production, there’s no concern. If the code has automated tests, if the application has been tested by your manual testers, and you feel confident about how it works in your QA environment, you can have the ability to press a button on a Friday at quittin’ time and sleep in on Saturday morning.

If the process is anything less than that, there’s room for improvement and your application (even if the code is great) could use some modernization.

Technology Is Deprecated

Your application could benefit from updates if deprecated technology is keeping you from moving forward. In large applications that were started a long time ago, there’s often a yawning gap between old code and new. Often, there’s a 3rd party library that acts like an anchor because it hasn’t been supported or updated, and if the .NET version of your application changes there’s a fear it will break the older library. Meanwhile, your developers want to use a newer NuGet package that relies on a newer version of .NET. Do you update it and fear breaking the old library, or work around the limitation by re-writing the functionality of the NuGet package yourself?

Unless you don’t plan on supporting your application for long, the answer is to move forward. Update the .NET version, break that anchor, and fix the resulting chaos. There’s never a good time to fix a broken dependency, and the longer you wait the harder it gets. The same applies for code that relies on deprecated databases, server versions, or language features. The sooner you pay off that technical debt, the freer you will be to make updates in the future.


Once “the pain of same” outweighs the “pain of change,” it’s time to do just that. Technical debt that does not get paid off can leave your application begging to declare bankruptcy. While time sneaks up on us all, you can do your application a favor and modernize it rather than spending time adding that new feature.

We Are Coming To A Town Near You

Over the next few months, we are hosting App Modernizations workshops throughout the Southeast, at the following locations:

February 13th: Orlando
February 20th: Raleigh
February 21st: Winston-Salem
February 22nd: Charlotte
February 27th: Tampa
March 1st: Fort Lauderdale
March 27th: Atlanta

You can get more information and sign up here!