Skip to content

Deprecate WithNuget #2812

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions docs/articles/samples/IntroNuGet.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
---
uid: BenchmarkDotNet.Samples.IntroNuGet
---

## Sample: IntroNuGet

You can set specific versions of NuGet dependencies for each job.
You can set specific versions of NuGet dependencies for each job using MsBuild properties in your csproj.
It allows comparing different versions of the same package (if there are no breaking changes in API).

### Source code
Expand All @@ -13,14 +13,11 @@ It allows comparing different versions of the same package (if there are no brea

### Output

| Method | Job | NuGetReferences | Mean | Error | StdDev |
|------------------------- |------- |----------------------- |---------:|----------:|----------:|
| SerializeAnonymousObject | 10.0.1 | Newtonsoft.Json 10.0.1 | 2.926 us | 0.0795 us | 0.0283 us |
| SerializeAnonymousObject | 10.0.2 | Newtonsoft.Json 10.0.2 | 2.877 us | 0.5928 us | 0.2114 us |
| SerializeAnonymousObject | 10.0.3 | Newtonsoft.Json 10.0.3 | 2.706 us | 0.1251 us | 0.0446 us |
| SerializeAnonymousObject | 11.0.1 | Newtonsoft.Json 11.0.1 | 2.778 us | 0.5037 us | 0.1796 us |
| SerializeAnonymousObject | 11.0.2 | Newtonsoft.Json 11.0.2 | 2.644 us | 0.0609 us | 0.0217 us |
| SerializeAnonymousObject | 9.0.1 | Newtonsoft.Json 9.0.1 | 2.722 us | 0.3552 us | 0.1267 us |
| Method | Job | Arguments | Mean | Error | StdDev |
|-------------------------- |------- |-------------------- |---------:|----------:|----------:|
| ToImmutableArrayBenchmark | v9.0.0 | /p:SciVersion=9.0.0 | 1.173 μs | 0.0057 μs | 0.0086 μs |
| ToImmutableArrayBenchmark | v9.0.3 | /p:SciVersion=9.0.3 | 1.173 μs | 0.0038 μs | 0.0058 μs |
| ToImmutableArrayBenchmark | v9.0.5 | /p:SciVersion=9.0.5 | 1.172 μs | 0.0107 μs | 0.0157 μs |

### Links

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
<ItemGroup Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' ">
<Reference Include="System.Reflection" />
</ItemGroup>
<PropertyGroup>
<!-- Use 9.0.0 as baseline package for IntroNuGet -->
<SciVersion Condition="'$(SciVersion)' == ''">9.0.0</SciVersion>
</PropertyGroup>
<ItemGroup>
<!-- Use v9.0.0 as baseline package for WithNuGet tests -->
<PackageReference Include="System.Collections.Immutable" Version="9.0.0" />
<PackageReference Include="System.Collections.Immutable" Version="$(SciVersion)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="9.0.5" />
Expand Down
25 changes: 16 additions & 9 deletions samples/BenchmarkDotNet.Samples/IntroNuGet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,26 @@ namespace BenchmarkDotNet.Samples
/// Benchmarks between various versions of a NuGet package
/// </summary>
/// <remarks>
/// Only supported with the CsProjCoreToolchain toolchain
/// Only supported with CsProj toolchains.
/// </remarks>
[Config(typeof(Config))]
public class IntroNuGet
{
// Specify jobs with different versions of the same NuGet package to benchmark.
// The NuGet versions referenced on these jobs must be greater or equal to the
// same NuGet version referenced in this benchmark project.
// Example: This benchmark project references Newtonsoft.Json 13.0.1
// Setup your csproj like this:
/*
<PropertyGroup>
<!-- Use 9.0.0 as default package version if not specified -->
<SciVersion Condition="'$(SciVersion)' == ''">9.0.0</SciVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Collections.Immutable" Version="$(SciVersion)" />
</ItemGroup>
*/
// All versions of the package must be source-compatible with your benchmark code.
private class Config : ManualConfig
{
public Config()
{
var baseJob = Job.MediumRun;

string[] targetVersions = [
"9.0.0",
"9.0.3",
Expand All @@ -34,8 +39,10 @@ public Config()

foreach (var version in targetVersions)
{
AddJob(baseJob.WithNuGet("System.Collections.Immutable", version)
.WithId($"v{version}"));
AddJob(Job.MediumRun
.WithMsBuildArguments($"/p:SciVersion={version}")
.WithId($"v{version}")
);
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/BenchmarkDotNet/Environments/InfrastructureResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ private InfrastructureResolver()
Register(InfrastructureMode.BuildConfigurationCharacteristic, () => InfrastructureMode.ReleaseConfigurationName);

Register(InfrastructureMode.ArgumentsCharacteristic, Array.Empty<Argument>);

#pragma warning disable CS0618 // Type or member is obsolete
Register(InfrastructureMode.NuGetReferencesCharacteristic, Array.Empty<NuGetReference>);
#pragma warning restore CS0618 // Type or member is obsolete
}
}
}
9 changes: 8 additions & 1 deletion src/BenchmarkDotNet/Jobs/InfrastructureMode.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using BenchmarkDotNet.Characteristics;
using BenchmarkDotNet.Engines;
Expand All @@ -18,6 +20,9 @@ public sealed class InfrastructureMode : JobMode<InfrastructureMode>
public static readonly Characteristic<IEngineFactory> EngineFactoryCharacteristic = CreateCharacteristic<IEngineFactory>(nameof(EngineFactory));
public static readonly Characteristic<string> BuildConfigurationCharacteristic = CreateCharacteristic<string>(nameof(BuildConfiguration));
public static readonly Characteristic<IReadOnlyList<Argument>> ArgumentsCharacteristic = CreateCharacteristic<IReadOnlyList<Argument>>(nameof(Arguments));

[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This will soon be removed")]
public static readonly Characteristic<IReadOnlyCollection<NuGetReference>> NuGetReferencesCharacteristic = CreateCharacteristic<IReadOnlyCollection<NuGetReference>>(nameof(NuGetReferences));

public static readonly InfrastructureMode InProcess = new InfrastructureMode(InProcessEmitToolchain.Instance);
Expand Down Expand Up @@ -64,6 +69,8 @@ public IReadOnlyList<Argument> Arguments
set => ArgumentsCharacteristic[this] = value;
}

[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This will soon be removed")]
public IReadOnlyCollection<NuGetReference> NuGetReferences
{
get => NuGetReferencesCharacteristic[this];
Expand Down
13 changes: 11 additions & 2 deletions src/BenchmarkDotNet/Jobs/JobExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ public static Job WithEnvironmentVariable(this Job job, string key, string value
/// <param name="source">(optional)Indicate the URI of the NuGet package source to use during the restore operation.</param>
/// <param name="prerelease">(optional)Allows prerelease packages to be installed.</param>
/// <returns></returns>
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This method will soon be removed, please start using .WithMsBuildArguments() instead.")]
public static Job WithNuGet(this Job job, string packageName, string? packageVersion = null, Uri? source = null, bool prerelease = false) =>
job.WithCore(j => j.Infrastructure.NuGetReferences =
new NuGetReferenceList(j.Infrastructure.NuGetReferences ?? Array.Empty<NuGetReference>())
Expand All @@ -352,9 +354,14 @@ public static Job WithNuGet(this Job job, string packageName, string? packageVer
/// <param name="job"></param>
/// <param name="nuGetReferences">A collection of NuGet dependencies</param>
/// <returns></returns>
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This method will soon be removed, please start using .WithMsBuildArguments() instead.")]
public static Job WithNuGet(this Job job, NuGetReferenceList nuGetReferences) =>
job.WithCore(j => j.Infrastructure.NuGetReferences = nuGetReferences);

public static Job WithMsBuildArguments(this Job job, params string[] msBuildArguments)
=> job.WithArguments([.. msBuildArguments.Select(a => new MsBuildArgument(a))]);

// Accuracy
/// <summary>
/// Maximum acceptable error for a benchmark (by default, BenchmarkDotNet continue iterations until the actual error is less than the specified error).
Expand Down Expand Up @@ -437,8 +444,10 @@ private static Job WithCore(this Job job, Action<Job> updateCallback)
return newJob;
}

internal static bool HasDynamicBuildCharacteristic(this Job job) =>
job.HasValue(InfrastructureMode.NuGetReferencesCharacteristic)
internal static bool HasDynamicBuildCharacteristic(this Job job)
#pragma warning disable CS0618 // Type or member is obsolete
=> job.HasValue(InfrastructureMode.NuGetReferencesCharacteristic)
#pragma warning restore CS0618 // Type or member is obsolete
|| job.HasValue(InfrastructureMode.BuildConfigurationCharacteristic)
|| job.HasValue(InfrastructureMode.ArgumentsCharacteristic);
}
Expand Down
3 changes: 3 additions & 0 deletions src/BenchmarkDotNet/Jobs/NugetReference.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using System;
using System.ComponentModel;
using System.Text.RegularExpressions;

namespace BenchmarkDotNet.Jobs
{
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This type will soon be removed")]
public class NuGetReference : IEquatable<NuGetReference>
{
public NuGetReference(string packageName, string packageVersion, Uri? source = null, bool prerelease = false)
Expand Down
3 changes: 3 additions & 0 deletions src/BenchmarkDotNet/Jobs/NugetReferenceList.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;

namespace BenchmarkDotNet.Jobs
{
/// <summary>
/// An ordered list of NuGet references. Does not allow duplicate references with the same PackageName.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This type will soon be removed")]
public class NuGetReferenceList : IReadOnlyCollection<NuGetReference>
{
private readonly List<NuGetReference> references = new List<NuGetReference>();
Expand Down
4 changes: 4 additions & 0 deletions src/BenchmarkDotNet/Running/BenchmarkPartitioner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ public bool Equals(BenchmarkCase x, BenchmarkCase y)
return false;
if (AreDifferent(jobX.Infrastructure.Arguments, jobY.Infrastructure.Arguments)) // arguments can be anything (Mono runtime settings or MsBuild parameters)
return false;
#pragma warning disable CS0618 // Type or member is obsolete
if (AreDifferent(jobX.Infrastructure.NuGetReferences, jobY.Infrastructure.NuGetReferences))
return false;
#pragma warning restore CS0618 // Type or member is obsolete
if (!jobX.Environment.Gc.Equals(jobY.Environment.Gc)) // GC settings are per .config/.csproj
return false;

Expand Down Expand Up @@ -81,8 +83,10 @@ public int GetHashCode(BenchmarkCase obj)
hashCode.Add(job.Infrastructure.BuildConfiguration);
foreach (var arg in job.Infrastructure.Arguments ?? Array.Empty<Argument>())
hashCode.Add(arg);
#pragma warning disable CS0618 // Type or member is obsolete
foreach (var reference in job.Infrastructure.NuGetReferences ?? Array.Empty<NuGetReference>())
hashCode.Add(reference);
#pragma warning restore CS0618 // Type or member is obsolete
return hashCode.ToHashCode();
}

Expand Down
10 changes: 10 additions & 0 deletions src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommand.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -57,7 +58,9 @@ public BuildResult RestoreThenBuild()
{
DotNetCliCommandExecutor.LogEnvVars(WithArguments(null));

#pragma warning disable CS0618 // Type or member is obsolete
var packagesResult = AddPackages();
#pragma warning restore CS0618 // Type or member is obsolete
if (!packagesResult.IsSuccess)
return BuildResult.Failure(GenerateResult, packagesResult.AllInformation);

Expand Down Expand Up @@ -97,7 +100,9 @@ public BuildResult RestoreThenBuildThenPublish()
{
DotNetCliCommandExecutor.LogEnvVars(WithArguments(null));

#pragma warning disable CS0618 // Type or member is obsolete
var packagesResult = AddPackages();
#pragma warning restore CS0618 // Type or member is obsolete
if (!packagesResult.IsSuccess)
return BuildResult.Failure(GenerateResult, packagesResult.AllInformation);

Expand All @@ -115,6 +120,8 @@ public BuildResult RestoreThenBuildThenPublish()
return PublishNoRestore().ToBuildResult(GenerateResult);
}

[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This method will soon be removed")]
public DotNetCliCommandResult AddPackages()
{
var executionTime = new TimeSpan(0);
Expand Down Expand Up @@ -150,6 +157,7 @@ public DotNetCliCommandResult PublishNoRestore()
=> DotNetCliCommandExecutor.Execute(WithArguments(
GetPublishCommand(GenerateResult.ArtifactsPaths, BuildPartition, $"{Arguments} --no-restore", "publish-no-restore")));

[Obsolete]
internal static IEnumerable<string> GetAddPackagesCommands(BuildPartition buildPartition)
=> GetNuGetAddPackageCommands(buildPartition.RepresentativeBenchmarkCase, buildPartition.Resolver);

Expand Down Expand Up @@ -204,6 +212,7 @@ private static string GetCustomMsBuildArguments(BenchmarkCase benchmarkCase, IRe
return string.Join(" ", msBuildArguments.Select(arg => arg.TextRepresentation));
}

[Obsolete]
private static IEnumerable<string> GetNuGetAddPackageCommands(BenchmarkCase benchmarkCase, IResolver resolver)
{
if (!benchmarkCase.Job.HasValue(InfrastructureMode.NuGetReferencesCharacteristic))
Expand All @@ -229,6 +238,7 @@ private static string GetMandatoryMsBuildSettings(string buildConfiguration)
return $"{NoMsBuildZombieProcesses} {EnforceOptimizations}";
}

[Obsolete]
private static string BuildAddPackageCommand(NuGetReference reference)
{
var commandBuilder = new StringBuilder();
Expand Down
2 changes: 2 additions & 0 deletions src/BenchmarkDotNet/Toolchains/Mono/MonoAotToolchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@ public override IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCas
benchmarkCase);
}

#pragma warning disable CS0618 // Type or member is obsolete
if (benchmarkCase.Job.HasValue(InfrastructureMode.NuGetReferencesCharacteristic))
{
yield return new ValidationError(true,
"The MonoAOT toolchain does not allow specifying NuGet package dependencies",
benchmarkCase);
}
#pragma warning restore CS0618 // Type or member is obsolete
}
}
}
2 changes: 2 additions & 0 deletions src/BenchmarkDotNet/Toolchains/Roslyn/RoslynToolchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,14 @@ public override IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCas
benchmarkCase);
}

#pragma warning disable CS0618 // Type or member is obsolete
if (benchmarkCase.Job.HasValue(InfrastructureMode.NuGetReferencesCharacteristic))
{
yield return new ValidationError(true,
"The Roslyn toolchain does not allow specifying NuGet package dependencies",
benchmarkCase);
}
#pragma warning restore CS0618 // Type or member is obsolete
}
}
}
2 changes: 2 additions & 0 deletions tests/BenchmarkDotNet.IntegrationTests/NugetReferenceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public NuGetReferenceTests(ITestOutputHelper output) : base(output)
}

[Fact]
[Obsolete]
public void UserCanSpecifyCustomNuGetPackageDependency()
{
var toolchain = RuntimeInformation.GetCurrentRuntime().GetToolchain(preferMsBuildToolchains: true);
Expand All @@ -38,6 +39,7 @@ public void UserCanSpecifyCustomNuGetPackageDependency()
}

[FactEnvSpecific("Roslyn toolchain does not support .NET Core", EnvRequirement.FullFrameworkOnly)]
[Obsolete]
public void RoslynToolchainDoesNotSupportNuGetPackageDependency()
{
var toolchain = RoslynToolchain.Instance;
Expand Down
1 change: 1 addition & 0 deletions tests/BenchmarkDotNet.Tests/Configs/JobTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ public static void AllJobModesPropertyNamesMatchCharacteristicNames() // it's ma
}

[Fact]
[Obsolete]
public static void WithNuGet()
{
var j = new Job("SomeId");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public void CustomClrBuildJobsAreGroupedByVersion()
}

[Fact]
[System.Obsolete]
public void CustomNuGetJobsAreGroupedByPackageVersion()
{
var config = ManualConfig.Create(DefaultConfig.Instance)
Expand Down
Loading