Skip to content

Repository files navigation

ApiCheck

Join the chat at https://gitter.im/PMudra/ApiCheck

ApiCheck is a library that compares different versions of an API using reflection to ensure compatibility with third party components. This project contains three components: the library, the console application and the NUnit integration. It is compatible with the following runtimes:

  • netstandard 2.0
  • .NET 6.0

Features

  • Comparing .NET assemblies.
  • Detection of changed API elements such as types, methods, properties and more.
  • Reporting results as XML or HTML files.
  • Console application that can be used in CI environment.
  • NUnit integration for nice analysis of the results of the comparison.

CI Build

Build statusNuGet status

Installing via NuGet

Installing the library to your project (referencing ApiCheck.dll):

Install-Package ApiCheck

Installing the console application to packages/ApiCheck.Console/tools:

Install-Package ApiCheck.Console

Installing the NUnit integration to your project. This package depends on ApiCheck and NUnit which will be added automatically as NuGet packages.

Install-Package ApiCheck.NUnit

Using the ApiCheck Library

using(AssemblyLoaderassemblyLoader=newAssemblyLoader()){// using the included AssemblyLoader that automatically resolves dependenciesAssemblyrefAssembly=assemblyLoader.ReflectionOnlyLoad("MyReferenceVersion.dll");AssemblydevAssembly=assemblyLoader.ReflectionOnlyLoad("MyDevelopmentVersion.dll");// the comparer configuration specifies the severity levels of the changed API elements and which elements to ignoreComparerConfigurationconfiguration=newComparerConfiguration();// all listed elements are not comparedconfiguration.Ignore.Add("Element.To.Be.Ignored");// override the default severitiesconfiguration.Severities.ParameterNameChanged=Severity.Warning;configuration.Severities.AssemblyNameChanged=Severity.Hint;// easy setup of the ApiChecker using the builder patternApiChecker.CreateInstance(refAssembly,devAssembly)// configure the logging and the comparer .WithComparerConfiguration(configuration).WithDetailLogging(s =>WriteLine(s)).WithInfoLogging(s =>WriteLine(s))// write report to desired streams.WithHtmlReport(newFileStream("report.html",FileMode.Create)).WithXmlReport(newFileStream("report.xml",FileMode.Create)).Build()// creating the ApiChecker.CheckApi();// doing the comparison}

Using the console application

The console application provides basic parameters to run an API comparison. This application can be added to a CI build as Post-Build event.

Usage: ApiCheck.Console.exe -r <reference assembly> -n <new assembly> [-x <xml report>] [-h <html report>] [-c <config file>] [-v]

For more information run ApiCheck.Console.exe --help

Using the NUnit integration

Add a new class to your project like this:

usingApiCheck.NUnit;namespaceMyNamespace{[ApiTest(@"Version1\ApiCheckTestProject.dll",@"Version2\ApiCheckTestProject.dll",Category="ApiTest",ComparerConfigurationPath=@"configuration.txt")][ApiTest(@"Version1\ApiCheckTestProject.Extension.dll",@"Version2\ApiCheckTestProject.Extension.dll",Explicit=true)]publicclassComparingApiTest:ApiTest{}}

Detected changes

These are the changes in an API that are detected by the comparer:

Assemblies

DescriptionBeforeAfterSeverity
assembly name changedCompany.MyAssemblyCompany.YourAssemblyError
assembly version changed1.0.0.02.0.0.0Hint
assembly public key token changedB03F5F7F11D50A3A0A3AB03F5F7F11D5Error
assembly culturede-DEen-USWarning
type removedpublic class B { }Error
type addedpublic class B { }Warning
nested type removedpublic class B { public class A { } }public class B { }Error
nested type addedpublic class B { }public class B { public class A { } }Warning

Types

DescriptionBeforeAfterSeverity
enum changedpublic enum E { }public class E { }Error
static type changedpublic static class A { }public class A { }Error
abstract type changedpublic abstract class A { }public class A { }Error
sealed type changedpublic sealed class A { }public class A { }Error
interface changedpublic interface I { }public class I { }Error
serializable changed[Serializable]public class S { }public class S { }Error
interfaces addedpublic class A { }public class A : Interface { }Warning
interfaces removedpublic class A : Interface { }public class A { }Error
base addedpublic class A { }public class A : AbstractClass { }Warning
base changedpublic class A : AbstractClass { }public class A { }Error
method addedpublic int A() { }Warning
method removedpublic int A() { }Error
constructor addedpublic A() { }Warning
constructor removedpublic A() { }Error
property addedpublic int P {get; set;}Warning
property removedpublic int P {get; set;}Error
event addedpublic event DelegateType MyEventWarning
event removedpublic event DelegateType MyEventError
field addedpublic int i;Warning
field removedpublic int i;Error

Methods

DescriptionBeforeAfterSeverity
virtual method changedpublic virtual int A()public int A() { }Error
static method changedpublic static int A()public int A() { }Error
abstract method changedpublic abstract int A()public int A() { }Error
sealed method changedpublic override sealed int A()public int A() { }Error
return type changedpublic int A() { }public string A() { }Error
parameter name changedpublic int A(int i) { }public int A(int j) { }Error
default value changedpublic int A(int i = 0) { }public int A(int i = 1) { }Error
out changedpublic int A(out int i) { }public int A(ref int i) { }Error

Properties, Events & Fields

DescriptionBeforeAfterSeverity
property type changedpublic int A {get; set;}public string A {get;set;}Error
property setter addedpublic int A {get;}public int A {get; set;}Warning
property getter addedpublic int A {set;}public int A {get; set;}Warning
property setter addedpublic int A {get;private set; }public int A {get; set;}Warning
property getter addedpublic int A {private get; set;}public int A {get; set;}Warning
property setter removedpublic int A {get; set;}public int A {get;}Error
property getter removedpublic int A {get; set;}public int A {set;}Error
property setter removedpublic int A {get; set;}public int A {get;private set;}Error
property getter removedpublic int A {get; set;}public int A {private get;set;}Error
static property changedpublic static int A {get; set;}public int A {ret; set;}Error
event type changedpublic event DelegateType MyEventpublic event NewDelegateType MyEventError
static event changedpublic static event DelegateType MyEventpublic event DelegateType MyEventError
field type changedpublic int ipublic string iError
static field changedpublic static int ipublic string iError
const enum value changedpublic const E i = E.X;public const E i = E.Y;Error

Comparison configuration

The comparer can be configured by providing a YAML based configuration file. This configuration allows you to;

  • Specify which elements to exclude from the comparison
  • Override the default comparer severities

Configuration format

This is the format of the comparer configuration file:

---
# ApiCheck comparer configuration for MyProject
# specifies which elements to exclude from the comparison
# these can be types or members, listed by their fully qualified name
ignore: - MyCompany.MyNamespace.MyClass.SomeMember
- MyCompany.MyNamespace.MyClass2 # exclude MyClass2 because it changes a lot # override the default comparer severities
# the rule names match the descriptions from the table above in camelCase
# the severity levels can be set to error/warning/hint
severities:
parameterNameChanged: warning # globally set the check for changed parameter names to warning
assemblyNameChanged: hint

About

Library comparing different versions of an api using reflection to ensure compatibility with third party components. Including console application and NUnit integration.

Resources

Stars

9 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages