A Roslyn analyzer that checks Mapster.Adapt method calls for type compatibility issues, particularly nullable to non-nullable mappings.
$ dotnet add package MapsterChecker.AnalyzerA Roslyn analyzer that performs static analysis on Mapster.Adapt method calls to detect type compatibility issues at build time, with a focus on nullable to non-nullable type mapping violations.
MapsterChecker helps prevent runtime null reference exceptions by analyzing your Mapster mapping calls during compilation. It identifies potentially dangerous mappings where nullable types are mapped to non-nullable types, as well as fundamentally incompatible type mappings.
dotnet add package MapsterChecker.Analyzer
Install-Package MapsterChecker.Analyzer
<PackageReference Include="MapsterChecker.Analyzer" Version="1.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
Severity: Warning
Category: MapsterChecker.Nullability
Detects when mapping from a nullable type to a non-nullable type, which may result in null reference exceptions.
// ⚠️ MAPSTER001: Warning
string? nullableString = GetNullableString();
var result = nullableString.Adapt<string>(); // May throw if nullableString is null
// ⚠️ MAPSTER001: Warning
int? nullableInt = GetNullableInt();
var number = nullableInt.Adapt<int>(); // May throw if nullableInt is null
// ✅ Safe: Non-nullable to nullable
string nonNullableString = "test";
var result = nonNullableString.Adapt<string?>(); // Safe conversion
Severity: Error
Category: MapsterChecker.Compatibility
Detects when attempting to map between fundamentally incompatible types that cannot be converted.
// ❌ MAPSTER002: Error
int number = 42;
var dateTime = number.Adapt<DateTime>(); // Incompatible types
// ❌ MAPSTER002: Error
string text = "hello";
var guid = text.Adapt<Guid>(); // Cannot convert arbitrary string to Guid
// ✅ Safe: Compatible numeric types
int number = 42;
long longNumber = number.Adapt<long>(); // Valid widening conversion
Severity: Info
Category: MapsterChecker.Mapping
Will detect when destination type contains properties not present in the source type.
You can configure rule severity in your .editorconfig file:
[*.cs]
# Set MAPSTER001 to error instead of warning
dotnet_diagnostic.MAPSTER001.severity = error
# Disable MAPSTER002 completely
dotnet_diagnostic.MAPSTER002.severity = none
# Set MAPSTER003 to suggestion
dotnet_diagnostic.MAPSTER003.severity = suggestion
You can suppress specific diagnostics using standard C# suppression methods:
// Suppress via pragma
#pragma warning disable MAPSTER001
var result = nullableString.Adapt<string>();
#pragma warning restore MAPSTER001
// Suppress via attribute
[SuppressMessage("MapsterChecker", "MAPSTER001")]
public string ConvertToString(string? input) => input.Adapt<string>();
MapsterChecker analyzes the following Mapster usage patterns:
var destination = source.Adapt<DestinationType>();
var destination = new DestinationType();
source.Adapt(destination);
using Mapster;
var result = sourceObject.Adapt<TargetType>();
string? → string: ⚠️ MAPSTER001 (Warning)string → string?: ✅ Safeint? → int: ⚠️ MAPSTER001 (Warning)int → int?: ✅ Safeint → long: ✅ Safe (widening conversion)float → double: ✅ Safe (widening conversion)long → int: ⚠️ Potential data loss (but allowed by Mapster)string → int: ❌ MAPSTER002 (Incompatible)List<T> → IEnumerable<U>: Checks T → U compatibilityT[] → List<U>: Checks T → U compatibility# Clone the repository
git clone https://github.com/mapsterchecker/mapsterchecker.git
cd mapsterchecker
# Restore dependencies
dotnet restore
# Build the solution
dotnet build
# Run tests
dotnet test
# Create NuGet package
dotnet pack --configuration Release
The repository includes a sample application demonstrating various mapping scenarios:
cd samples/SampleApp
dotnet build # This will show analyzer warnings/errors
dotnet run # Run the sample application
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)MapsterChecker is designed to be fast and responsive:
This project is licensed under the MIT License - see the LICENSE file for details.