Why I Chose C# for Business Systems and Still Use It

A reflection on business system architecture, solution/project separation, and why C# remains my primary development environment.

This is the first article in C# Architecture Notes. I use C# every day to build business systems, and this series is where I want to explain why I still do that, what I think it does especially well, and how I design systems around it.

This is not a tutorial. It is an architectural reflection based on what I have seen and what I continue to do in production work.

Before web work, there was open systems development

I did not start as a web developer. I started in what Japan typically called open systems development.

In Japan, open systems usually referred to client/server enterprise systems on Windows or UNIX, in contrast to mainframe systems. In international terms, this would generally be described as distributed client/server enterprise development.

Those systems were often large desktop applications with a very high number of screens. Direct database access in a 2-tier model was common. In some projects, database credentials were even stored in configuration files without encryption. This was not rare, and it was not limited to small vendors.

When I started in open systems development, this 2-tier style was the dominant default. Client applications connected to the database directly, and many responsibility decisions were treated as client-side implementation concerns. Validation existed, but it was often distributed and inconsistent because each screen carried part of the burden.

After SOAP-based web services became common, many systems gradually moved toward a 3-tier architecture. The presentation layer, application service layer, and data layer were no longer collapsed into one direct client-to-database flow. Business logic and validation moved toward the server layer, and that change was not only technical. It changed how teams understood responsibility boundaries across the whole system.

The moment server-side validation and integrity guarantees became standard practice changed how I thought about responsibility boundaries. Data consistency no longer depended solely on client discipline.

The impact of server-side integrity

As validation moved to the server, business rules became more centralized and more enforceable. That improved consistency not only for one screen, but across multiple clients and entry points.

Data guarantees became something the architecture could require, rather than something each screen hoped to preserve. Even if a user bypassed UI constraints, the server could still reject invalid state transitions and protect core invariants. In practical operations, that made systems more resilient to both accidental misuse and uneven implementation quality.

To this day, every system I build assumes that data integrity must be guaranteed on the server side.

I never considered that architecture ideal. At the same time, I did not have the authority or political influence to replace those decisions. So my early years were less about ideal design and more about learning how real delivery environments actually behave.

What felt different when .NET appeared

Around the time I entered the industry, .NET appeared and spread quickly. Multiple languages could run on the same framework, and one solution could contain multiple projects that cooperated while staying separate.

That felt structurally new to me. It was not only about syntax. It was about being able to shape system boundaries physically.

Web development was already increasing in the market, but most of my own implementation at that time was desktop work in VB, VC++, and C#. I only began designing web systems on my own after 2010.

The core point: solution aggregation and project boundaries

For me, the key architectural value was simple. A csproj is a physical boundary. A sln can aggregate many projects, but it does not dissolve those boundaries.

That means I can classify system units by business domain, responsibility, and purpose while still keeping them inside one coordinated development space.

As far as I know, this kind of project-level physical and conceptual separation is especially natural in the .NET ecosystem. I say this as personal observation, not as a universal claim.

Why does this matter in practice? Because each functional unit remains physically independent. Safe modification scope becomes narrower. Cognitive load decreases. In team development, merge conflict probability also goes down because change areas are more clearly partitioned.

First web project in .NET

My first web project in .NET was as an implementation member, not as an architecture decision-maker. The team used several vendor-provided components, and my own web knowledge at that point was still limited.

Even so, the framework and project structure allowed me to keep moving productively. That experience reinforced my trust in the environment before I fully understood every web-specific detail.

The PHP phase

The first web system I developed fully by myself was in PHP. The reason was straightforward: it had to run on rental hosting.

Why I returned to C#

I returned to C# for two major reasons. First, Azure removed most of the hosting and runtime constraints that had pushed me away before. Second, C# still gave me the project separation model that I considered essential for long-term operation.

This was the turning point.

My current architecture style

Now I usually create one csproj per business segment or subdomain. In many systems, each project maps to the first URL path segment.

sales and sales-related operations stay in one segment. inventory and stock operations stay in another. management functions stay in their own boundary.

In other words, routing boundary and project boundary are intentionally aligned.

I build large systems alone. Not globally large, but large enough that without strict structural separation, I simply cannot manage them. My cognitive limits are real. If I do not split the system this way, it collapses under its own weight. C# allows me to impose order before chaos appears.

Why this is harder to enforce in PHP

In PHP, separation is usually folder-based. That can work well for small systems. But there is no equivalent project-boundary enforcement at the same level. Cross-domain dependencies are also not structurally restricted in the same way, so boundaries can blur as the codebase expands.

As systems grow and more contributors participate, keeping architectural boundaries stable becomes more fragile. Business systems do not stay small. They evolve with the business, and structure that depends only on discipline eventually gets stressed.

Why I still choose C# today

My current view is that C# is the best choice for business system development in my context.

It is not perfect. In practice, AI-generated code can sometimes be less predictable depending on the ecosystem and available examples. When working in C#, I tend to review generated output more carefully and treat it as a draft rather than final code. I also still feel some frustration that anonymous interface implementation is not available in the same way Java allows.

Even with those limitations, when I balance productivity, structural safety, and long-term maintainability for a single developer, C# remains the best equilibrium I have found.

Where Cotomy fits in this boundary model

Cotomy is a frontend framework. It intentionally does not implement server-side data integrity mechanisms, and it does not assume a specific backend architecture. Developers can implement server logic in the style that fits their application constraints, domain complexity, and operational requirements.

Cotomy does not enforce data integrity because that responsibility belongs to the server layer. It remains intentionally independent from backend-specific design choices. Cotomy assumes that server-side boundaries are already architecturally defined and respected.

Closing

This first note focused on project structure as an architectural boundary.

C# Architecture Notes

This article is part of the Cotomy C# Architecture Notes, which reflect on backend and project-structure decisions around business systems.

Series articles: Why I Chose C# for Business Systems and Still Use It, From Global CSS Chaos to Scoped Isolation , and Unifying Data Design and Code with Entity Framework .

Next article: From Global CSS Chaos to Scoped Isolation

Learn Cotomy

Cotomy is a DOM-first UI runtime for long-lived business applications.