Upgrading an old C# application using AI.

Modernizing a Legacy C# Client/Server Application with gRPC, NLua, and AI-Assisted Refactoring

Over the past few weeks, I have been modernizing an older C# application called LabelPrint. The codebase dates back to 2011 and, although it had gradually moved forward to .NET Framework 4.8, much of the architecture still reflected design choices from an earlier era of the .NET ecosystem.

One of the most obvious examples was its use of .NET Remoting for client/server communication. Remoting served its purpose well in the .NET Framework days, but it is no longer a good fit for a modernized application stack. Replacing it became one of the key architectural goals of the upgrade.

Replacing .NET Remoting with gRPC

The new version is now 64-bit only and uses gRPC as the replacement for .NET Remoting. That shift makes the communication layer more explicit, contract-driven, and better aligned with current .NET development practices. gRPC also provides a cleaner path for defining service boundaries and evolving the application’s client/server protocol over time.

Refactoring the Codebase

Beyond the transport layer, the codebase was updated to use more modern C# constructs and reorganized into a more logical structure. The goal was not simply to make the application compile on a newer stack, but to make the source easier to understand, maintain, and extend.

Lua remains the internal scripting language, but the implementation is now based on NLua. This keeps the scripting model familiar while updating the underlying integration layer. A new WiX installer was also added so the application can be packaged and deployed in a more predictable way.

Using AI as a Refactoring Partner

AI assistance turned out to be useful during the migration, especially for planning and validating refactoring steps. As a GitHub Copilot user, I could ask different models to propose migration strategies, compare their recommendations, and use the overlap between their answers as a signal for the safest path forward.

The biggest challenge was not getting AI to generate code; it was learning how to ask the right questions. Good prompts produced useful migration plans, highlighted risky areas, and suggested incremental changes. Poor prompts tended to generate broad recommendations that were technically plausible but not specific enough to apply directly to the codebase.

Testing and Security Hardening

After the migration, the application was tested to verify that the existing functionality still worked as expected. I also used Claude Fable to perform a security review based on OWASP guidelines. That review led to several additional security improvements, making the client/server application more robust than the original implementation.

Takeaways

Modernizing a legacy application is rarely just a framework upgrade. In this case, it meant replacing obsolete communication infrastructure, revisiting deployment, improving internal structure, validating behavior through testing, and hardening the security model. AI helped accelerate the process, but the real value came from using it as a technical review partner rather than as an automatic code generator.

Leave a Comment