Jump to content
Xtreme .Net Talk

  • Posts

    • MSTest, also known as Microsoft Testing Framework, simplifies the testing experience for .NET applications. This test framework allows users to write and execute tests while providing test suites integrated into the Test Explorer’s of Visual Studio and Visual Studio Code, as well as many CI pipelines. Fully supported, open-source, and cross-platform, MSTest works with all supported .NET targets while maintaining support for VSTest as well as adding support for the improved experience with Microsoft.Testing.Platform (MTP). MSTest 3.8 highlights We continually work to improve MSTest, address your feedback and offer smoother testing experience. MSTest 3.8 is a big release, with lots of great new features: Filtering: The VSTestBridge extension of Microsoft.Testing.Platform (MTP) 1.6 and later now supports filtering while discovering tests (–list-tests). This feature has been highly requested by users to help verify the tests applicable to a given filter. Running tests with MSBuild: Extended support for the -t:Test or /t:Test target to support MSBuild.exe. Improved iterating experience: Updated the Microsoft.Testing.Extensions.TrxReport extension behavior to overwrite the content instead of failing when the TRX file already exists. Enriched metapackage: Simplified using TRX report and Code Coverage by removing the requirement to manually declare these MTP extensions. Support of modern UWP: MSTest now supports .NET 9 in UWP. Improved assertions: Introduced new assertion APIs like Assert.Throws, Assert.ThrowsAsync, Assert.ThrowsExactly, and Assert.ThrowsExactlyAsync. Better data-driven tests: Parameterized generic test methods are now supported. Retrying flaky tests: Introduced RetryAttribute to automatically retry failing test methods. Introducing conditional tests: Added OSConditionAttribute for fine-grained control over where your tests run. Analyzers: The MSTestAnalysisMode feature allows you to control the severity levels of code analyzers within your test projects. Read on for more, and check out the full changelog on GitHub for details. Filtering The VSTestBridge extension of Microsoft.Testing.Platform (MTP) 1.6 and later now supports filtering while discovering tests (--list-tests). This feature has been highly requested by users to help verify the tests applicable to a given filter. This gives more confidence that you have the correct filter when you run tests. Because MSTest with MTP uses the VSTestBridge, that feature is available in MSTest 3.8 and later. Based on your requests, we also added support for the runsettings TestCaseFilter element in MTP. Note that this is also available for any test framework relying on Microsoft.Testing.Extensions.VSTestBridge extension. Running tests with MSBuild Another of your requests was to extend the support of the -t:Test or /t:Test target that was a dotnet build only feature to support MSBuild.exe. This is now available for MSTest 3.8, and any test framework based on MTP 1.6+. Improved iterating experience We updated the Microsoft.Testing.Extensions.TrxReport extension behavior when the TRX file already exists to overwrite the content instead of failing. The extension will display a warning message to notify that the file already exists and will be overwritten. For example, when running the following command twice: dotnet run -- --report-trx --report-trx-filename test.trx The second run will not fail, but instead show the following warning: Warning: Trx file 'path/to/TestResults/test.trx' already exists and will be overwritten. Enriched metapackage Since most MSTest projects use both TRX report and Code Coverage, we’ve simplified using them by removing the requirement to manually declare these MTP extensions. With MSTest 3.8 and MTP, you can simplify your projects from: <ItemGroup> <PackageReference Include="MSTest" /> <PackageReference Include="Microsoft.Testing.Extensions.CodeCoverage" /> <PackageReference Include="Microsoft.Testing.Extensions.TrxReport" /> </ItemGroup> to: <ItemGroup> <PackageReference Include="MSTest" /> </ItemGroup> Support of modern UWP UWP recently announced support for .NET 9 in Modernize your UWP app with preview UWP support for .NET 9 and Native AOT blog post and through close collaboration, we are happy to announce that MSTest supports this new mode. For that to work, you need to be using Microsoft.NET.Test.Sdk version 17.14.0-preview-25107-01 or above. Stay tuned for a dedicated blog post with all the information and examples coming soon. Improved assertions Exception asserts Historically, only Assert.ThrowsException and Assert.ThrowsExceptionAsync were available, requiring an exact match between the specified exception type and the one thrown. Many users requested a simpler naming convention and support for derived exceptions. In response, this release introduces: Assert.Throws Assert.ThrowsAsync Assert.ThrowsExactly Assert.ThrowsExactlyAsync To facilitate a smooth upgrade to MSTest 3.8 without causing disruptions to your projects, the old APIs remain available. However, when creating new tests, they will not appear in IntelliSense, encouraging the use of simpler names. The following is an example of usage of the new APIs: [TestClass] public sealed class Test1 { [TestMethod] public void TestMethod1() { // Will pass because the exceptions have the exact same type Assert.Throws<OperationCanceledException>(() => throw new OperationCanceledException()); // Will pass because TaskCanceledException derives from OperationCanceledException Assert.Throws<OperationCanceledException>(() => throw new TaskCanceledException()); // Will fail because the exceptions do not have exactly the same type Assert.ThrowsExactly<OperationCanceledException>(() => throw new TaskCanceledException()); } } We also include MSTEST0039 analyzer along with a codefix to help you with transitioning away from the old APIs to the new ones. In addition, we added new overloads to the new APIs that accepts a messageBuilder parameter, which is a Func<Exception?, string>. This allows you to customize the failure message based on information from the exception thrown (if any). For example: [TestMethod] public void TestMethod1() { Assert.ThrowsExactly<InvalidOperationException>( () => throw new ArgumentException("Message of ArgumentException"), messageBuilder: actualException => { if (actualException is null) { return "Expected InvalidOperationException but no exception was thrown."; } return $"Expected InvalidOperationException, but found {actualException.GetType().Name} with message {actualException.Message}"; }); } The above test will fail as follows: Assert.ThrowsExactly failed. Expected exception type:<System.InvalidOperationException>. Actual exception type:<System.ArgumentException>. Expected InvalidOperationException, but found ArgumentException with message Message of ArgumentException Collection asserts We introduced new collection-related assertion APIs in the Assert class, designed to work with IEnumerable<T>, expanding the assertion capabilities for collections: Assert.HasCount: Asserts that an IEnumerable<T> has a given number of elements. Assert.IsEmpty: Asserts that an IEnumerable<T> doesn’t have any elements. Assert.IsNotEmpty: Asserts that an IEnumerable<T> has at least one element. Assert.ContainsSingle: Asserts that an IEnumerable<T> has exactly a single element and returns that element. These new APIs have been added to the Assert class instead of CollectionAssert to improve discoverability. We also plan to make all CollectionAssert APIs available on Assert. Interpolated string handler overloads for message parameter Finally, we added new interpolated string handler overloads for many existing assertion APIs. If you heavily use the Assert methods overload with message parameter and use an interpolated string as argument to the message parameter, this will unnecessarily allocate a string that will end up being unused in most cases, as this message is only used in case the assertion failed. Starting with 3.8, new overloads that use interpolated string handler will ensure that the string isn’t allocated unless the assertion fails. Better data-driven tests Parameterized generic test methods are now supported, allowing you to write tests like: [TestClass] public sealed class TestClass1 { [TestMethod] [DataRow(2, 5, 10)] [DataRow(2.0d, 5.0d, 10.0d)] [DataRow(5, 5, 25)] [DataRow(5.0d, 5.0d, 25.0d)] public void TestMethod1<T>(T number1, T number2, T expectedResult) where T : IMultiplyOperators<T, T, T> { Assert.AreEqual(expectedResult, number1 * number2); } } Additionally, we’ve enhanced the behavior of DynamicDataAttribute to automatically detect the type of the referenced member used as the data source as the default. With this improvement, you can simplify your tests from: [DynamicData(nameof(MyProperty), DynamicDataSourceType.Property)] [DynamicData(nameof(MyMethod), DynamicDataSourceType.Method)] to: [DynamicData(nameof(MyProperty))] [DynamicData(nameof(MyMethod))] Another highly requested feature was the ability to ignore specific data sources from parameterized tests. Starting in 3.8, DataRowAttribute and DynamicDataAttribute have an IgnoreMessage property. When it’s set to non-null string, the source will be ignored. We are also allowing any custom ITestDataSource to have a similar behavior by simply implementing the ITestDataSourceIgnoreCapability. With this change, you can now do: [TestMethod] [DataRow(0)] [DataRow(1, IgnoreMessage = "This row is ignored")] [DataRow(2)] public void TestMethod1(int x) { Assert.AreNotEqual(1, x); } or [TestMethod] [DynamicData(nameof(Data1))] [DynamicData(nameof(Data2), IgnoreMessage = "This dynamic data source is ignored")] [DynamicData(nameof(Data3))] public void TestMethod1(int x) { Assert.IsTrue(x < 10); } // 0 to 3 - passes public static IEnumerable<int> Data1 => Enumerable.Range(0, 4); // 50 to 59 - ignored, and will fail if not ignored public static IEnumerable<int> Data2 => Enumerable.Range(50, 10); // 4 to 9 - passes public static IEnumerable<int> Data3 => Enumerable.Range(4, 6); Finally, we have introduced TestDataRow<T> allowing users to wrap their data in a customizable container where you can set the display name, ignore the entry and much more to come. Any ITestDataSource can now return IEnumerable<TestDataRow<T>>. For example: [TestMethod] [DynamicData(nameof(GetData))] public void TestMethod1(int num1, int num2, int expectedSum) { Assert.AreEqual(expectedSum, num1 + num2); } private static IEnumerable<TestDataRow<(int Num1, int Num2, int ExpectedSum)>> GetData() { yield return new((1, 2, 3)); yield return new((2, 3, 5)); yield return new((3, 4, 7)) { DisplayName = "This test case has a special display name" }; yield return new((3, 3, 7)) { IgnoreMessage = "Ignored because of ..." }; } Retrying flaky tests We’re excited to introduce RetryAttribute, a powerful new feature that lets you automatically retry failing test methods! With just one attribute, you can configure MaxRetryAttempts, MillisecondsDelayBetweenRetries, and BackoffType (choosing between Constant and Exponential strategies for smarter retries). For example: [TestMethod] [Retry(3, MillisecondsDelayBetweenRetries = 100, BackoffType = DelayBackoffType.Constant)] public void TestMethod() { Assert.Fail("Failing test"); } This test method will run four times (the original run and 3 retries), with a time delay of 100 milliseconds between each run. Need more flexibility? You can create your own custom retry logic by inheriting from RetryBaseAttribute, the same foundation as the RetryAttribute. If you are using MTP, enabling retries across your entire test suite is even easier, just leverage the retry extension and let your tests recover automatically! Introducing conditional tests MSTest now includes OSConditionAttribute, giving you fine-grained control over where your tests run. This attribute lets you specify which operating systems a test should or should not execute on, making it easier to handle OS-specific behavior in your test suite. Here are some examples of this attribute: [TestClass] public sealed class MyTestClass { [TestMethod] [OSCondition(OperatingSystems.Windows)] public void TestMethodRunningOnlyOnWindows() { } [TestMethod] [OSCondition(OperatingSystems.Linux | OperatingSystems.OSX)] public void TestMethodRunningOnlyOnLinuxAndMac() { } [OSCondition(ConditionMode.Exclude, OperatingSystems.Windows)] public void TestMethodRunningOnAllOSesButWindows() { } } As part of the development of this feature, we are providing the ConditionBaseAttribute abstract class as parent of OSConditionAttribute and IgnoreAttribute. You can use this new attribute as the root of any conditional feature you would like to implement. We have many ideas for extra conditional features we could provide, and we would really appreciate your input in prioritizing the ones that would be the most useful to you! Analyzers The MSTestAnalysisMode feature allows you to control the severity levels of code analyzers within your test projects. By setting the MSTestAnalysisMode MSBuild property, you can determine which analyzers are enabled and their corresponding severity levels. Available Modes: None: Disables all analyzers. You can enable individual analyzers using .editorconfig or .globalconfig files. Default: Follows the default behavior for each rule. Rules enabled by default will use their default severity, while those disabled by default will have a severity of none. Recommended: Elevates rules enabled by default with an Info (suggestion) severity to warnings. Certain rules may be escalated to errors in both Recommended and All modes.For example, MSTEST0003: Test methods should have valid layout is escalated to an error in these modes. All: More aggressive than Recommended. All rules are enabled as warnings, with certain rules escalating to errors. Usage Example: To set the MSTestAnalysisMode to Recommended, include the following in your project file or in Directory.Build.props: <PropertyGroup> <MSTestAnalysisMode>Recommended</MSTestAnalysisMode> </PropertyGroup> This configuration ensures that your test projects adhere to best practices by appropriately adjusting the severity levels of various analyzers. Note that using Directory.Build.props is more recommended than project file, as it ensures the property applies to all your test projects and you add it in one place instead of multiple project files. It’s also safe if MSTestAnalysisMode is defined for non-test projects via Directory.Build.props. It only affects MSTest projects. For more detailed information, refer to the MSTest code analysis documentation. Let’s now focus on 2 newly added analyzers that have shown promising results during internal dogfood: MSTEST0038: Don’t use ‘Assert.AreSame’ or ‘Assert.AreNotSame’ with value types MSTEST0040: Do not assert inside ‘async void’ contexts MSTEST0038 warns when the methods Assert.AreSame and Assert.AreNotSame are called with a value type argument. These methods work by comparing references, making its usage with value types incorrect as it yields unexpected results. The following use of Assert.AreSame will always fail: Assert.AreSame(0, 0); This is because we pass them to ReferenceEquals, which accepts object. So, each argument will be boxed into a different object, and they will not have equal references. The same applies to Assert.AreNotSame, but is more critical. Assert.AreNotSame(0, 0); By applying the same logic, the above assert will always pass. This can hide real production bugs as you may not be asserting what you want. Note that the above examples are for demonstration purposes only and are not real-world examples. A more realistic example can be: // This will still pass even if the array has a single element. Assert.AreNotSame(1, myArray.Length); For more information, see MSTEST0038: Don’t use ‘Assert.AreSame’ or ‘Assert.AreNotSame’ with value types. MSTEST0040 warns for usage of assertion APIs in async void. Depending on whether you use a custom SynchronizationContext and whether you use VSTest under .NET Framework, an exception thrown in async void context can either be swallowed completely or can crash the test host. For more information, see MSTEST0040: Do not assert inside ‘async void’ contexts. Wrapping up With MSTest 3.8, we’re continuing our mission to make testing in .NET easier, more powerful, and more enjoyable. This release brings highly requested features, reduces tedious tasks, and enhances the overall developer experience — allowing you to focus on writing great tests instead of wrestling with infrastructure. We hope these improvements help streamline your workflow and showcase our commitment to listening to your feedback and evolving MSTest to meet your needs. As always, we’d love to hear your thoughts — try out MSTest 3.8 and let us know what you think by opening an issue or a discussion on microsoft/testfx GitHub repository! Try MSTest 3.8 Today A huge shoutout to @SimonCropp for his incredible contributions to MTP and MSTest! His dedication and expertise continue to make a lasting impact, and this release is no exception. We’re grateful for his ongoing support and invaluable efforts in helping shape a better testing experience for the entire .NET community. Thank you, Simon! The post MSTest 3.8: Top 10 features to supercharge your .NET tests! appeared first on .NET Blog. View the full article
    • Today, we are excited to announce the second preview release of .NET 10 with enhancements across the .NET Runtime, SDK, libraries, C#, ASP.NET Core, Blazor, .NET MAUI, and more. Check out the full release notes linked below and get started today. Download .NET 10 Preview 2 This release contains the following improvements. Libraries Encryption algorithm can now be specified in PKCS#12/PFX Export Full Release Notes Runtime Array Enumeration De-Abstraction Inlining of Late Devirtualized Methods Devirtualization Based on Inlining Observations Support for Casting and Negation in NativeAOT’s Type Preinitializer Full Release Notes SDK More consistent command order for dotnet CLI Full Release Notes C# Partial events and constructors Full Release Notes F# This release you will find updates across the F# language, FSharp.Core standard library, and FSharp.Compiler.Service. Visual Basic No new features added in this preview release. Full Release Notes ASP.NET Core & Blazor Reconnection UI component added to the Blazor Web App project template NavigateTo no longer scrolls to the top for same page navigations Ignore query string and fragment when using NavLinkMatch.All Close QuickGrid column options Populate XML doc comments into OpenAPI document Upgrade to OpenAPI.NET v2.0.0-preview7 Treat empty strings in form posts as null for nullable value types New authentication and authorization metrics Full Release Notes .NET MAUI ShadowTypeConverter SpeechOptions Rate Styling Modal as Popover Switch.OffColor HybridWebView new InvokeJavascriptAsync Method Deprecations Full Release Notes .NET for Android This release was focused on quality improvements. A detailed list can be found on dotnet/android GitHub releases. .NET for iOS, Mac Catalyst, macOS, tvOS This release was focused on quality improvements. A detailed list can be found on dotnet/macios GitHub releases including a list of Known issues. Windows Forms Clipboard Code Sharing with WPF Ported more System.Windows.Forms.Design UITypeEditors Quality Enhancements Full Release Notes Windows Presentation Foundation (WPF) Performance Improvements Fluent Style Changes Bug Fixes Engineering Health Full Release Notes Entity Framework Core Support for the .NET 10 RightJoin operator Small improvements Full Release Notes Container Images Native AOT SDK images Full Release Notes Get started To get started with .NET 10, install the .NET 10 SDK. If you’re on Windows using Visual Studio, we recommend installing the latest Visual Studio 2022 preview. You can also use Visual Studio Code and the C# Dev Kit extension with .NET 10. Join us for .NET 10 Preview 2 Unboxed Live Stream Join us for an unboxing video with the team to discuss what’s new in this preview release, with live demos from the dev team! .NET 10 Discussions The team has been making monthly announcements alongside full release notes on the dotnet/core GitHub Discussions and has seen great engagement and feedback from the community. Stay up-to-date with .NET 10 You can stay up-to-date with all the features of .NET 10 with: What’s new in .NET 10 What’s new in C# 14 What’s new in .NET MAUI What’s new in ASP.NET Core What’s new in Entity Framework Core What’s new in Windows Forms What’s new in WPF Breaking Changes in .NET 10 .NET 10 Releases Additionally, be sure to subscribe to the GitHub Discussions RSS news feed for all release announcements. We want your feedback, so head over to the .NET 10 Preview 2 GitHub Discussion to discuss features and give feedback for this release. The post .NET 10 Preview 2 is now available! appeared first on .NET Blog. View the full article
    • Solution files have been a part of the .NET and Visual Studio experience for many years now, and they’ve had the same custom format the whole time. Recently, the Visual Studio solution team has begun previewing a new, XML-based solution file format called SLNX. Starting in .NET SDK 9.0.200, the dotnet CLI supports building and interacting with these files in the same way as it does with existing solution files. In the rest of this post we’ll show how users can migrate to the new format, explore the new support across the dotnet CLI, and discuss the next steps towards a generally-available release of the format. Getting started Before the 9.0.200 SDK, the only way to create a SLNX file was through the Visual Studio settings. The Environment > Preview Features > Use Solution File Persistence Model setting, when checked, would allow users to Save As their existing .sln files in the new .slnx format. The 9.0.200 SDK provides a command to do this same migration: dotnet sln migrate. Let’s start with a very simple solution and project setup to look at what it takes to migrate. First, we’ll create a new solution: PS C:\Users\chethusk\Code\example> dotnet new sln The template "Solution File" was created successfully. PS C:\Users\chethusk\Code\example> cat .\example.sln Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal Now, we’ll create a project and add it to the solution: PS C:\Users\chethusk\Code\example> dotnet new console -n my-app The template "Console App" was created successfully. Processing post-creation actions... Restoring C:\Users\chethusk\Code\example\my-app\my-app.csproj: Restore succeeded. PS C:\Users\chethusk\Code\example> dotnet sln add .\my-app\ Project `my-app\my-app.csproj` added to the solution. PS C:\Users\chethusk\Code\example> cat .\example.sln Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "my-app", "my-app\my-app.csproj", "{845B7716-6F03-4D02-8E86-79F95485B5D7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|Any CPU.Build.0 = Debug|Any CPU {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|x64.ActiveCfg = Debug|Any CPU {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|x64.Build.0 = Debug|Any CPU {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|x86.ActiveCfg = Debug|Any CPU {845B7716-6F03-4D02-8E86-79F95485B5D7}.Debug|x86.Build.0 = Debug|Any CPU {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|Any CPU.ActiveCfg = Release|Any CPU {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|Any CPU.Build.0 = Release|Any CPU {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|x64.ActiveCfg = Release|Any CPU {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|x64.Build.0 = Release|Any CPU {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|x86.ActiveCfg = Release|Any CPU {845B7716-6F03-4D02-8E86-79F95485B5D7}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal Now, let’s convert our solution to the new format: PS C:\Users\chethusk\Code\example> dotnet sln migrate .slnx file C:\Users\chethusk\Code\example\example.slnx generated. PS C:\Users\chethusk\Code\example> cat .\example.slnx <Solution> <Configurations> <Platform Name="Any CPU" /> <Platform Name="x64" /> <Platform Name="x86" /> </Configurations> <Project Path="my-app/my-app.csproj" /> </Solution> The new format is XML-based and is much more concise than the old format – but it contains all of the same data! The data that is missing from the new format is part of the defaults of the format, so no functionality is lost. This migration is made possible because the Visual Studio Solution team has created a new open-source library for parsing and working with both classic and XML-based solution files – the library is called Microsoft.VisualStudio.SolutionPersistence. Managing projects from the CLI You can do more than migrating solution files using the CLI, too. As you might expect, you can build the new solutions the same way you would build the old: PS C:\Users\chethusk\Code\example> dotnet build .\example.slnx Restore complete (0.6s) my-app succeeded (4.3s) → my-app\bin\Debug\net9.0\my-app.dll Build succeeded in 5.3s Note We specified the .slnx file explicitly above because it’s an error to run dotnet build or other commands that need to build in a directory with both a .sln and a .slnx – we don’t know which one to build! All of the other interactions you expect from the dotnet CLI work as well. We can add projects: PS C:\Users\chethusk\Code\example> dotnet new classlib -n my-lib The template "Class Library" was created successfully. Processing post-creation actions... Restoring C:\Users\chethusk\Code\example\my-lib\my-lib.csproj: Restore succeeded. PS C:\Users\chethusk\Code\example> dotnet sln .\example.slnx add my-lib Project `my-lib\my-lib.csproj` added to the solution. PS C:\Users\chethusk\Code\example> cat .\example.slnx <Solution> <Configurations> <Platform Name="Any CPU" /> <Platform Name="x64" /> <Platform Name="x86" /> </Configurations> <Project Path="my-app/my-app.csproj" /> <Project Path="my-lib/my-lib.csproj" /> </Solution> We can list the projects in a solution: PS C:\Users\chethusk\Code\example> dotnet sln .\example.slnx list Project(s) ---------- my-app\my-app.csproj my-lib\my-lib.csproj And finally we can remove projects from the solution: PS C:\Users\chethusk\Code\example> dotnet sln .\example.slnx remove .\my-lib\ Project `my-lib\my-lib.csproj` removed from the solution. PS C:\Users\chethusk\Code\example> cat .\example.slnx <Solution> <Configurations> <Platform Name="Any CPU" /> <Platform Name="x64" /> <Platform Name="x86" /> </Configurations> <Project Path="my-app/my-app.csproj" /> </Solution> Tip There are two commands that don’t work in 9.0.200, though – dotnet nuget why and dotnet list package – those will begin working in the 9.0.201 release in March. Support for SLNX across .NET IDEs and Tooling As mentioned above, the dotnet CLI has broad support for the new SLNX file format, but there are still many tools in the ecosystem that have partial or no support for the format. You will need to take this varying level of support into account when choosing whether to migrate to SLNX files. Some examples of tools that have varying levels of support for slnx today are: Visual Studio While the IDE will read the SLNX file when loaded, it currently will not load SLNX files unless the setting to enable SLNX persistence has been enabled. This means if you work on a team and users have not toggled this setting, they will not be able to open SLNX files at all. In addition, double-clicking on SLNX files doesn’t currently open Visual Studio instances the way that sln files do. C# Dev Kit C# DevKit can support SLNX files, but in order to do so you must set the dotnet.defaultSolution property to the path to your slnx file: { "dotnet.defaultSolution": "example.slnx" } slngen The slngen tool is a command-line utility used to synthesize a solution file for a given project to help make repos that prefer not to use solution files interoperate better with Visual Studio. This tool is not yet updated to support SLNX – the status of this support can be tracked at microsoft/slngen#643. JetBrains Rider Rider has preliminary support for the SLNX format, and details about their support can be tracked at RIDER-110777. Feedback and the road to GA Despite this end-to-end support in Visual Studio and the dotnet CLI, the SLNX format itself is still in preview. While we think it’s a great step forward in usability for many .NET developers, we want to hear from you as you try it in your teams. Try the migration paths in Visual Studio and the dotnet CLI, make sure things work as you expect in your CI/CD pipelines and local builds, and make sure to let the teams know about your experiences in the following ways: for CLI experiences, report new issues or discussions at the dotnet/sdk repository for Visual Studio experiences, please raise new tickets at the Visual Studio Developer Community for feature requests for the solution parsing library, report new issues at the microsoft/vs-solutionpersistence repository As we’re able to respond to your feedback and solidify core user experiences, we move closer towards being able to make this the default for Visual Studio and the dotnet CLI. Summary SLNX files are an exciting new change to the solution file format that we think will make it easier for teams to collaborate and understand their projects. The new capabilities in the dotnet CLI allow developers to have a full inner-loop and CI experience using the new format, so we’d love for .NET developers to read through the updated documentation, try the new support, and give us feedback! The post Introducing support for SLNX, a new, simpler solution file format in the .NET CLI appeared first on .NET Blog. View the full article
    • HybridCache is a new .NET 9 library available via the Microsoft.Extensions.Caching.Hybrid package and is now generally available! HybridCache, named for its ability to leverage both in-memory and distributed caches like Redis, ensures that data storage and retrieval is optimized for performance and security, regardless of the scale or complexity of your application. Why use HybridCache? HybridCache reliably simplifies the boilerplate code like object serialization, cache-aside pattern implementation, and data consistency down to a single line of code. It also optimizes the data performance by combining in-memory and distributed cache stores enabling the application to run faster. If you’re building ASP.NET Core applications that use repeated or complicated data queries, have a microservice-based architecture, or require real-time data processing, you should use HybridCache to improve the performance and responsiveness of your applications. Key features Built on top of IDistributedCache which means it is compatible with all existing cache backends such as Redis, SQL Server, CosmosDB, Garnet, etc. Simple and easy-to-use API Cache-stampede protection Cache invalidation with tags Performance enhancements such as inbuilt support for the newer IBufferDistributedCache API Fully configurable serialization for JSON and Protobuf Secure-by-default with authentication and data handling Keep reading to learn more about the key features! Simple API – GetOrCreateAsync If you’ve previously tried caching in your ASP.NET Core applications, you may be familiar with other abstractions such as IDistributedCache or IMemoryCache. With these you’d have to write the code to generate keys, try to retrieve the data matching the key from the cache, deserialize the data if it does exist in the cache, or serialize the data and push it into the cache if it did not exist. This is a very manual process and hooking up all the different components is time consuming, requires the knowledge of multiple APIs, and is difficult to get right. // This is the code without HybridCache public class SomeService(IDistributedCache cache) { public async Task<SomeInformation> GetSomeInformationAsync (string name, int id, CancellationToken token = default) { var key = $"someinfo:{name}:{id}"; // Unique key for this combination. var bytes = await cache.GetAsync(key, token); // Try to get from cache. SomeInformation info; if (bytes is null) { // Cache miss; get the data from the real source. info = await SomeExpensiveOperationAsync(name, id, token); // Serialize and cache it. bytes = SomeSerializer.Serialize(info); await cache.SetAsync(key, bytes, token); } else { // Cache hit; deserialize it. info = SomeSerializer.Deserialize<SomeInformation>(bytes); } return info; } // This is the work we're trying to cache. private async Task<SomeInformation> SomeExpensiveOperationAsync(string name, int id, CancellationToken token = default) { /* ... */ } } HybridCache simplifies the cache-aside pattern down to one single line of code while significantly accelerating your application data performance. // Same code as above, now using HybridCache public class SomeService(HybridCache cache) { public async Task<SomeInformation> GetSomeInformationAsync (string name, int id, CancellationToken token = default) { return await cache.GetOrCreateAsync( $"someinfo:{name}:{id}", // Unique key for this entry. async cancel => await SomeExpensiveOperationAsync(name, id, cancel), token: token ); } } Cache-stampede protection A cache stampede occurs when multiple clients request the same data simultaneously after it expires from the cache, leading to a surge of redundant computations and database queries. This can significantly slow down a web application and degrade the user experience, especially under high traffic conditions. HybridCache prevents cache stampedes by ensuring that when multiple requests for the same data arrive, it only performs the necessary computations once. Instead of allowing every request to independently regenerate the data, HybridCache detects the situation, processes the request a single time, and returns the result to all queued requests. This approach maintains data consistency and optimizes performance at scale. Cache invalidation with tags When you add an item to a cache, you can assign one or more tags to it, which are simply string values that help categorize this data. HybridCache now makes it easier to manage and invalidate data in bulk via tagging. For example, when needing to invalidate many items at a time from a cache, instead of deleting the keys one-by-one, you can delete all items with a specific tag with one API call. You can even delete items with multiple tags at a time simply by passing a set of tags. It’s no longer necessary to rely exclusively on unique keys for identifying, grouping, and deleting data from the cache. Summary With all these new features hot off the press, it’s time to try the new .NET 9 HybridCache! To get started or learn more, visit the documentation. The post Hello HybridCache! Streamlining Cache Management for ASP.NET Core Applications appeared first on .NET Blog. View the full article
    • Welcome to our combined .NET servicing updates for March 2025. Let’s get into the latest release of .NET & .NET Framework, here is a quick overview of what’s new in these releases: Security improvements This month you will find CVEs that have been fixed this month: CVE # Title Applies to CVE-2025-24070 .NET Elevation of Privilege Vulnerability .NET 9.0, .NET 8.0 .NET 8.0 .NET 9.0 Release Notes 8.0.14 9.0.3 Installers and binaries 8.0.14 9.0.3 Container Images images images Linux packages 8.0.14 9.0.3 Known Issues 8.0 9.0 Release changelogs ASP.NET Core: 8.0.14 | 9.0.3 Entity Framework Core: 9.0.3 Runtime: 8.0.14 | 9.0.3 SDK: 8.0.14 | 9.0.3 Winforms: 9.0.3 Share feedback about this release in the Release feedback issue. .NET Framework March 2025 Updates This month, there are no new security and non-security updates. For recent .NET Framework servicing updates, be sure to browse our release notes for .NET Framework for more details. See you next month That’s it for this month, make sure you update to the latest service release today. The post .NET and .NET Framework March 2025 servicing releases updates appeared first on .NET Blog. View the full article
  • Member Statistics

    • Total Members
      47758
    • Most Online
      704

    Newest Member
    Arena Properties
    Joined
  • Forum Statistics

    • Total Topics
      31.9k
    • Total Posts
      126.2k
    • 29 replies
    • 60.6k views
    Calobima
    • 0 replies
    • 4.4k views
    rbulph
    • 0 replies
    • 2.7k views
    yaniv
    • 0 replies
    • 9k views
    groads2
  1. groads2
  2. IIS hosted WCF service

    • 0 replies
    • 2.5k views
    groads2
    • 1 reply
    • 7.1k views
    • 4 replies
    • 2.5k views
  3. sattu
      • Administrators
    • 3 replies
    • 4.8k views
    • 1 reply
    • 4.3k views
    BrettW
      • Administrators
    • 3 replies
    • 4.3k views
    • 1 reply
    • 1.9k views
    haydenw
      • Administrators
    • 1 reply
    • 2.2k views
    • 0 replies
    • 3.2k views
    osos
      • Administrators
    • 3 replies
    • 3.5k views
      • Leaders
    • 3 replies
    • 4.3k views
    Leade
  • Who's Online   0 Members, 0 Anonymous, 81 Guests (See full list)

    • There are no registered users currently online
×
×
  • Create New...