ASP.NET

Optimize Code Quality Using FxCop And StyleCop Analyzers

 

1. Purpose

How to configure FxCop Analyzer and StyleCop Analyzer based on .NET Compiler Platform (“Roslyn”) analyzers to analyze your code for style, quality and maintainability, design, and other issues.

2. What is FxCop Analyzer

Microsoft created a set of analyzers, called Microsoft.CodeAnalysis.FxCopAnalyzers, that contains the most important “FxCop” rules from static code analysis, converted to Roslyn analyzers.
These analyzers check your code for security, performance, and design issues, among others.

It is a meta package of four other analyzer packages:

  • Microsoft.CodeQuality.Analyzers:  The bulk of the “classic” FXCop errors are here. For instance, implementing IDisposable properly and passing URIs instead of strings are both checked in this package.
  • Microsoft.NetCore.Analyzers: .NET core specific warnings/errors appear here, but many are more generic like requiring ICultureInfo to be passed to methods that can accept it.
  • Microsoft.NetFramework.Analyzers: Full framework .net warnings are checked here like handling ISerializable correctly.
  • Text.Analyzers: This package provides some basic spell checking (disabled by default).

3. What is StyleCop Analyzer

StyleCop is like FxCop analyzer, it uses Roslyn Analyzers but does only care about style programming.

Code analysis searches for patterns which may indicate a bug, while StyleCop is simply enforcing style rules, a simple convention used by our team.

4. Is FxCop Analyzer and legacy FxCop same?

Legacy FxCop runs post-build analysis on a compiled assembly. It runs as a separate executable called FxCopCmd.exe. FxCopCmd.exe loads the compiled
assembly, runs code analysis, and then reports the results (or diagnostics).

FxCop analyzers are based on the .NET Compiler Platform (“Roslyn”). You install them as a NuGet package that’s referenced by the project or solution. FxCop analyzers run source-code based analysis during compiler execution. FxCop analyzers are hosted within the compiler process, either csc.exe or vbc.exe, and run analysis when the project is built. Analyzer results are reported along with compiler results.

5. How To Install FxCop Analyzer In Visual Studio

You can install these FxCop analyzers either as a NuGet package or as a VSIX extension to Visual Studio.

First let us create a small MVC test project in Visual Studio for and name it as “CodeAnalysisTest”.

a. On the File menu, choose New > Project.

b. In the New Project dialog box, expand Installed > Visual C#, and then choose Web.

c. Choose the ASP.Net Web Application (.NET Framework) template.

d. In the Name text box, type “CodeAnalysisTest” and then click OK.

e. After the project is created, create new class file under Model folder

f. And few lines code that has naming rules violation to test the Code analyzer.

g. Compile to check, if the code builds without any errors.

Installing FxCop Analyzer using Manage Nuget Pacakage for Solution

a. In Solution Explorer, right-click Solutions and choose Manage NuGet Package for Solution.

b. Make sure “nuget.org” is selected as the Package source.

c. And select the Browse tab, search for FxCop Ananalyzer (or) Microsoft.CodeAnalysis.FxCopAnalyzers, select that package in the list, and select Install:

d. Choose the latest stable version and click Install.

e. Review the changes on the pop-up box shown and click OK.

f. The NuGet package continues with the installation and shows Successfully installed message on the Output window of Visual Studio.

6. How To Install StyleCop Analyzer In Visual Studio

You can install these StyleCop analyzers as a NuGet package to Visual Studio.

Installing StyleCop Analyzer using Manage Nuget Pacakage for Solution

a. In Solution Explorer, right-click Solutions and choose Manage NuGet Package for Solution.

b. Make sure “nuget.org” is selected as the Package source.

c. And select the Browse tab, search for StyleCop Ananalyzer, select that package in the list, and select Install:

d. Choose the latest stable version and click Install.

e. Review the changes on the pop-up box shown and click OK.

f. The NuGet package continues with the installation and shows Successfully installed message on the Output window of Visual Studio.

7. Configure FxCop Analyzer

The FxCop analyzers consist of the most important “FxCop” rules from static code analysis, converted to Roslyn analyzers. You can configure FxCop code  analyzers in two ways:

a. With a rule set.

b. Starting in version 2.6.3 of the Microsoft.CodeAnalysis.FxCopAnalyzers NuGet package, through an .editorconfig file.

Rule Sets

One way to configure FxCop analyzers is by using an XML rule set. A rule set is a grouping of code analysis rules that identify targeted issues and specific conditions.

The predefined analyzer rule sets include three rulesets that affect all the rules in the package-one that enables them all, one that disables them all, and one that honors each rule’s default severity and enablement settings:

1. AllRulesEnabled.ruleset

2. AllRulesDisabled.ruleset

3. AllRulesDefault.ruleset

Additionally, there are two rule sets for each category of rules in the package, such as performance or security. One rule set enables all rules for the category, and one rule set honors the default severity and enablement settings for each rule in the category.

The Microsoft.CodeAnalysis.FxCopAnalyzers NuGet analyzer package includes rule sets for the following categories, which match the rule sets available
for legacy “FxCop” static code analysis:

  • Design
  • Documentation
  • Maintainability
  • Naming
  • Performance
  • Reliability
  • Security
  • Usage
.Net Framework

1. To make a rule set the active rule set for analysis in .NET Framework projects, right-click on the project in Solution Explorer and choose Properties.

2. In the project property pages, select the Code Analysis tab.

3. Under Run this rule set, select Browse, and then select the desired rule set that you copied to the project directory or create a new set of rules.

4. Now you only see rule violations for those rules that are enabled in the selected rule set.

5. A peek into the Rule sets.

.Net Core

1. To make a rule set the active rule set for analysis in .NET Core or .NET Standard projects.

2. Manually add the CodeAnalysisRuleSet property to your project file.

3. For example, the following code snippet sets HelloWorld.ruleset as the active rule set.

XML
<PropertyGroup Condition=”
‘$(Configuration)|$(Platform)’ == ‘Debug|AnyCPU’ “>
..
<CodeAnalysisRuleSet>TA_Rules.ruleset</CodeAnalysisRuleSet></PropertyGroup>
EditorConfig file

You can configure analyzer rules by adding key-value pairs to an .editorconfig file.

A configuration file can be specific

a. To a project

b. It can be shared between two or more projects.

Per-Project Configuration

1. To enable .editorconfig-based analyzer configuration for a specific project, add an .editorconfig file to the project’s root directory.

2. You can add an .editorconfig file to your project by right-clicking on the project in Solution Explorer

3. And selecting Add > New Item.

4. In the New Item dialog box, expand Installed > Visual C#, and then choose General.

5. Choose the Text File template.

6. In the Name text box, type “.editorconfig” and then click Add.

7. Open the .editorconfig file from the Project.

8. And now you can add the required custom rulesets for code quality / analysis.

Shared Configuration

You can share an .editorconfig file for analyzer configuration between two or more projects, but it requires some additional steps.

1. Save the .editorconfig file to a common location.

2. Create a .props file with the following content

XML
<Project DefaultTargets=”Build”
xmlns=”http://schemas.microsoft.com/developer/msbuild/2003″>
<PropertyGroup>
<SkipDefaultEditorConfigAsAdditionalFile>true</SkipDefaultEditorConfigAsAdditionalFile></PropertyGroup><ItemGroup Condition=”Exists(‘<your
path>\.editorconfig’)” >
<AdditionalFiles Include=”<your
path>\.editorconfig” />
</ItemGroup></Project>

3. Add a line to your .csproj or .vbproj file to import the .props file you created in the previous step.

4. This line must be placed before any lines that import the FxCop analyzer .props files.

5. For example, if your .props file is named editorconfig.props:

XML

<Import Project=”..\..\editorconfig.props”

Condition=”Exists(‘..\..\editorconfig.props’)” />

<Import
Project=”..\packages\Microsoft.CodeAnalysis.FxCopAnalyzers.2.6.3\build\Microsoft.CodeAnalysis.FxCopAnalyzers.props”
Condition=”Exists(‘..\packages\Microsoft.CodeAnalysis.FxCopAnalyzers.2.6.3\build\Microsoft.CodeAnalysis.FxCopAnalyzers.props’)”
/>

6. Reload the project.

7. Point to note, we cannot configure legacy FxCop rules (static code analysis FxCop) by using an .editorconfig file.

8. Configure StyleCop Analyzer

After configuring the FxCop Analyzer, now we need to configure the StyleCop Analyzer.

1. by adding the file stylecop.json into the Solution folder (at the same place as your ruleset file).

2. It’s mandatory to add this file to make it work.

stylecop.json

{

“$schema”:

“https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json”,

“settings”: {

“documentationRules”: {

“companyName”: “TA Digital”,

“copyrightText”: “Open source”

}

}

}

9. Custom Analyzer Based On .Net Roslyn Analyzer

Why Do We Need Custom ANALYZER?

Not all required coding standards by specific organization can be achieved with default rulesets. We need to build custom rulesets to cater to our specific requirements.

Let us take for example we need to have custom rulesets to handle:

1. To remove underscore from method names

2. To add prefix to all our class names.

So, we take advantage of Roslyn .Net Platform Complier and its public API to build our own Custom Analyzer, which can be installed as VSIX extensions to our projects.

The .Net compiler platform (Roslyn) mainly consists of two major layers of:

1. Compiler APIs

2. Workspace APIs.

Compiler APIs

Compiler layer always have the information which are exposed at each phase of compiler pipeline and it also contains an immutable snapshot of compiler’s invocation, these includes assembly references, compiler options, and source code files etc., There are two types of Compiler APIs which represent the C# language and the Visual Basic language

1. Diagnostic APIs

2. Scripting APIs

We use compiler APIs to write our own custom analyzers. The most important data structure which is exposed by the compiler APIs is syntax tree.

Workerspace APIs

Work space APIs provide access to the source code projects and documents in a solution and to their associated syntax trees, compilations and semantic models. It has an immutable snapshot of the projects and documents of a solution in visual studio.

How To Create Custom Analyzer

First follow the below steps to create a new analyzer project.

1. Select New project,

2. Visual C#, Extensibility then

3. select “Analyzer with Code Fix (NuGet + VSIX).

It creates three projects under a single solution, one is major project to implement our custom analyzer code, second one is the project to implement tests and another one is setup project.

In major project where we use it to write our analyzer, it creates two important class files:

1. DiagnosticAnalyzer

2. CodeFixProvider.

The class name in DiagnosticAnalyzer code file would be created with suffix “Analyzer” (like {ProjectName}Analyzer) which implements DiagnosticAnalyzer
interface by having [DiagnosticAnalyzer] attribute

And the class name in CodeFixProvider code file would be created with suffix “CodeFixProvider” (like {ProjectName}CodeFixProvider) which implements CodeFixProvider interface by having [ExportCodeFixProvider] attribute.

Now, In DiagnosticAnalyzer class, we need to define DiagnosticId, DiagnosticDescriptor (I.e. custom rule) and other variables like title, message, and description. These values will be displayed on the IDE when this custom rule is applied on code snippet. And we need to include this Rule in immutable Array as shown below in the below screenshot.

Then, register an action to be executed at completion of analysis of SyntaxNode with a proper kind (Kind is an example of method declaration, property declaration and class declaration etc.,), as shown below:

Now for Code fix option to work, In code fix provider class, we need to include our “DiagnosticId” which is defined in above code snippet in an immutable array and register code fix action like shown below:

Now we need to implement an asynchronous method “RemoveUnderscoreAsync” to identify method name to provide new name and providing the solution like
shown below:

Install The VISX Extension To Our Project

We need to install the VSIX extension package of our custom code analyzer to the Visual Studio and then it will be available as code analysis rulesets for our project.

10. Rule precedence

Rule precedence need to be carefully followed, otherwise we might get unwanted warnings.

1. If the same rule is listed two or more times in a rule set with different severities, the compiler generates an error.

XML
<RuleSet Name=”Rules for ClassLibrary21″
Description=”Code analysis rules for
ClassLibrary21.csproj.” ToolsVersion=”15.0″>

<Rules
AnalyzerId=”Microsoft.Analyzers.ManagedCodeAnalysis”
RuleNamespace=”Microsoft.Rules.Managed”>
<Rule Id=”CA1021″ Action=”Warning” /><Rule Id=”CA1021″ Action=”Error” />
</Rules></RuleSet>

2. If the same rule is listed two or more times in a rule set with the same severity, you may see the following warning in the Error List:

Warning on Output window
CA0063:
Failed to load rule set file ‘[your].ruleset’ or one of
its dependent rule set files. The file does not conform
to the rule set schema.

3. If the rule set includes a child rule set by using an Include tag, and the child and parent rule sets both list the same rule but with different severities, then the severity in the parent rule set takes precedence. For example:

XML
<!– Parent rule set –>

<?xml version=”1.0″ encoding=”utf-8″?>

<RuleSet Name=”Rules for ClassLibrary21″
Description=”Code analysis rules for
ClassLibrary21.csproj.” ToolsVersion=”15.0″>

<Include Path=”classlibrary_child.ruleset”
Action=”Default” />

<Rules
AnalyzerId=”Microsoft.Analyzers.ManagedCodeAnalysis”
RuleNamespace=”Microsoft.Rules.Managed”>

<Rule Id=”CA1021″ Action=”Warning” /> <!–
Overrides CA1021 severity from child rule set –>

</Rules>

</RuleSet>

<!– Child rule set –>

<?xml version=”1.0″ encoding=”utf-8″?>

<RuleSet Name=”Rules from child” Description=”Code
analysis rules from child.” ToolsVersion=”15.0″>

<Rules
AnalyzerId=”Microsoft.Analyzers.ManagedCodeAnalysis”
RuleNamespace=”Microsoft.Rules.Managed”>

<Rule Id=”CA1021″ Action=”Error” />

</Rules>

</RuleSet>

11. Build and fix (or) ignore warnings

Once the ruleset files are configured using RulesSet option, the next step is to do a rebuild of the solution and fix (or) ignore any warnings that pop up.

One rule that can be disabled is CA2007 – Do not directly await a Task without calling ConfigureAwait. This rule makes sense when building libraries to be consumed in other projects, but when building applications, this rule isn’t necessary. To disable the rule, follow the steps below.

4. Find the rule in the analyzer list under References > Analyzers > [Analyzer Name].

5. In the case of CA2007, the analyzer name is Microsoft.CodeQuality.Analyzers.

6. Under the code analyzer, find the rule you want to disable and right-click on it and set the Rule Set Severity to None.

7. Repeat the process above for all rules you wish to disable or fix the warnings that show up

12. Testing the Rule sets

Now, finally we are going to use the sample project created to test the Code Quality using FxCop analyzer.

Code Fix using Analyzers

1. FxCop analyzer violations appear in Error List.

2. In addition, FxCop analyzer violations also show up in the code editor as squiggles under the offending code.

3. The color of the squiggly depends on the severity setting of the rule.

4. The following screenshot shows the code fix options available:

IDisposable (using statement)

1. A sample of warnings for not using the IDisposable’s using statement in the code @ line no. 47

2. And after adding the using statement, the ruleset warning clears off for line no. 47

Coding Standards

1. StyleCop analyzer violations appear in Error List.

2. In addition, StyleCop analyzer violations also show up in the code editor as squiggles under the offending code.

3. The color of the squiggly depends on the severity setting of the rule.

4. The following screenshot shows the code fix options available:

Code Fix using Custom Analyzers

1. Custom analyzer violations appear in Error List.

2. In addition, Custom analyzer violations also show up in the code editor as squiggles under the offending code.

3. The color of the squiggly depends on the severity setting of the rule.

4. The following screenshot shows the code fix options available:

References

1. https://docs.microsoft.com/en-us/visualstudio/code-quality/install-fxcop-analyzers?view=vs-2017
2. https://stackoverflow.com/questions/44726384/enabling-microsofts-code-analysis-on-net-core-projects
3. https://docs.microsoft.com/en-us/visualstudio/code-quality/code-analysis-for-managed-code-overview?view=vs-2017

About The Author