Coding Comrade

Automatic code formatting for .NET projects

September 29, 2019

Every programmer has its own coding style preferences, but software development teams should have a well defined standards. It makes it easier to maintain the project, read the code, review pull requests, etc. Team mates join and leave. If there is no common ground, projects start looking like a collection of unrelated things.

To solve this issue, community created a wide variety of tools. For instance, there is an awesome project called Prettier. It formats, or how they call it — prettifies, certain files. Unfortunately, it doesn’t support .NET languages, but don’t get upset. There is something out there that can help us keep our .NET codebases consistent.

Kind people from Microsoft created a handy dotnet tool - dotnet-format. It reads style preferences from an .editorconfig file and formats files accordingly. As a bonus, Visual Studio supports .editorconfig rules as well and can apply them when the code is formatted manually. Looks like we’ve got everything in place now, we can relax and stop worrying about style preferences and formatting. The solution/project can be initially formatted by the dotnet-format and then, before committing a change, each developer will have to make sure they format their change in Visual Studio manually. There is one little problem here though, people tend to forget things. We can do better. We can automate it.

.NET Core 3.0 introduced a concept of local dotnet tools. It’s similar to local executable npm scripts. We can install the dotnet-format as a local tool and then make it format staged files when someone commits the code.

  1. Create a dotnet tools manifest file:
dotnet new tool-manifest
  1. Install the dotnet-format:
dotnet tool install dotnet-format
  1. Add an .editorconfig file to the root of the project. I suggest to use Roslyn team’s config file as a base.
  2. Initialize an npm project:
yarn init
  1. Install the following npm packages as dev dependencies:
yarn add husky lint-staged --dev
  1. Configure husky to run lint-staged as a pre-commit git hook; and configure npm to restore dotnet tools on install. Add the following to package.json:
"husky": {
  "hooks": {
    "pre-commit": "lint-staged -r"
  }
},
"scripts": {
  "preinstall": "dotnet tool restore"
}
  1. The last step is to configure lint-staged to format our staged files and then stage them back. Create a .lintstagedrc.js file with the below content:
module.exports = {
  '*.cs': filenames => [
    `dotnet dotnet-format --files ${filenames.join(',')}`,
    `git add ${filenames.join(' ')}`,
  ],
};


That’s it. I’ve created a template repository, which includes everything I’ve mentioned above; and can be used as a starting point when creating new .NET Core repositories.

Happy coding!


Eugene Yamenko

Hi, I'm Eugene, a Software Engineer in Sydney, Australia.