It has been an incredible journey, and I am thrilled to announce the release of Spargine 8, now transformed to leverage Microsoft .NET 8, accompanied by updated NuGet packages. Spargine encompasses foundational code that I have been crafting since the days of .NET 2! Additionally, it features a library designed to assist with your testing and another dedicated to benchmarking your code.
Given that .NET 8 is a long-term support version, I seized the opportunity to thoroughly update Spargine. This version also incorporates some impactful changes, including breaking modifications. If you are a Spargine user, I strongly recommend reading this article to familiarize yourself with these alterations. I believe I’ve addressed the majority of them.
Transitioning to Spargine has markedly enhanced its overall performance. If your team leverages .NET, I strongly recommend migrating to this new version expeditiously! To download .NET, kindly visit the following URL: https://dotnet.microsoft.com/en-us/download/dotnet/8.0. Additionally, ensure you update Visual Studio 2022 to the latest version.
To access the source code, please visit: https://github.com/RealDotNetDave/dotNetTips.Spargine.8
To seamlessly integrate these packages into your projects, execute the following commands in the .NET CLI:
- dotnet add package DotNetTips.Spargine.8
- dotnet add package DotNetTips.Spargine.8.Benchmarking
- dotnet add package DotNetTips.Spargine.8.Core
- dotnet add package DotNetTips.Spargine.8.Extensions
- dotnet add package DotNetTips.Spargine.8.Tester
New Code
I have incorporated additional features into Spargine as well! Below, you’ll find the details.
DotNetTips.Spargine
In the FileHelper class, I’ve implemented an overloaded method for CopyFile() that enables the copying of a file while providing real-time progress updates during the operation. This method utilizes a CopyProgressRoutine delegate, which invokes a callback function providing information such as total file size, total bytes transferred, stream size, stream bytes transferred, stream number, and callback reason. The method returns a Boolean indicating whether the operation was successful. Below is an example demonstrating how to test this new method:
var file = new FileInfo(RandomData.GenerateTempFile(900000));
var directory = new DirectoryInfo(App.ExecutingFolder());
CopyProgressRoutine callback = new CopyProgressRoutine(CopyProgressCallback);
var result = FileHelper.CopyFile(file: file, destination: directory, progressCallback: callback);
private static CopyProgressResult CopyProgressCallback(long totalFileSize,
long totalBytesTransferred,
long streamSize,
long streamBytesTransferred,
uint dwStreamNumber,
CopyProgressCallbackReason dwCallbackReason,
IntPtr hSourceFile,
IntPtr hDestinationFile,
IntPtr lpData)
{
Trace.WriteLine($"TotalFileSize:{totalFileSize}");
Trace.WriteLine($"TotalBytesTransferred:{totalBytesTransferred}");
Trace.WriteLine($"StreamSize:{streamSize}");
Trace.WriteLine($"StreamBytesTransferred:{streamBytesTransferred}");
Trace.WriteLine($"dwStreamNumber:{dwStreamNumber}");
Trace.WriteLine($"CopyProgressCallbackReason:{dwCallbackReason}");
return CopyProgressResult.Continue;
}
Here is the output generated by CopyProgressCallback:
Callback #1
TotalFileSize:900000
TotalBytesTransferred:0
StreamSize:900000
StreamBytesTransferred:0
dwStreamNumber:1
CopyProgressCallbackReason:StreamSwitch
Callback #2
TotalFileSize:900000
TotalBytesTransferred:262144
StreamSize:900000
StreamBytesTransferred:262144
dwStreamNumber:1
CopyProgressCallbackReason:ChunkFinished
Callback #3
TotalFileSize:900000
TotalBytesTransferred:524288
StreamSize:900000
StreamBytesTransferred:524288
dwStreamNumber:1
CopyProgressCallbackReason:ChunkFinished
Callback #4
TotalFileSize:900000
TotalBytesTransferred:786432
StreamSize:900000
StreamBytesTransferred:786432
dwStreamNumber:1
CopyProgressCallbackReason:ChunkFinished
Callback #5
TotalFileSize:900000
TotalBytesTransferred:900000
StreamSize:900000
StreamBytesTransferred:900000
dwStreamNumber:1
CopyProgressCallbackReason:ChunkFinished
This CopyFile method is particularly useful for displaying copy progress in a UI, as a similar method is not available in .NET, necessitating the use of a CopyFileExW Windows API.
DotNetTips.Spargine.Core
Here are the methods added to the App type:
- CurrentThreadId(): Retrieves a unique identifier for the current managed thread.
- ProcessId(): Retrieves the unique identifier for the current process.
- ProcessPath(): Returns the path of the executable that initiated the currently executing process. Returns null when the path is not available.
These are the methods added to the RegexProcessor:
- ContainsFirstLastName(): Determines if the string contains a person’s first and last name.
- IsMACAddress(): Determines if the string is a MAC (Media Access Control) address.
- IsSHA1Hash(): Determines if the string is a SHA1 (Secure Hash Algorithm 1) hash.
- IsUrlDomainAddress(): Determines whether the string URL contains a domain address.
- IsValidString(): Determines whether the string is a valid string.
- ReplaceCrLf(): Replaces carriage return line feeds with a string of your choosing. The default is an empty string.
All of these methods utilize a source generator to ensure optimal performance.
The following methods have been incorporated into the TypeHelper:
- BuiltinTypes(): Retrieves a collection of built-in types.
- IsBuiltinType(): This method assesses whether a given type is a built-in type.
I express a desire for additional methods of this nature to be added to .NET.
DotNetTips.Spargine.Extensions
Introducing the latest additions to the extensions library:
- ToReadOnlyCollection<T>(): Converts a ConcurrentBag into a ReadOnlyCollection.
- ToReadOnlyCollection<TKey, TValue>(): Transforms a Dictionary collection into a ReadOnlyCollection of KeyValuePairs. This aligns with recommended coding standards and follows the established .NET convention for returning a Dictionary from a public API.
DotNetTips.Spargine.Tester
Here are the new methods added to this library to enhance your unit test and benchmark projects:
- Countries.GetCountry(CountryName): This method retrieves a Country object based on one of the values in the CountryName enum.
- CountryGetCountry(Id): This method returns a Country object based on the specified country Id.
- GeneratePersonNames(): Generates a collection of PersonName with random values. The PersonName properties include FirstName, LastName, and FullName.
- RandomData.GenerateAddressCollection<T>(): Generates a collection of addresses based on a Country with random data for any type that implements IAddress. The default number of addresses generated is 2.
Significant Transformations, Including Breaking Modifications
DotNetTips.Spargine.Core
Below are the breaking changes to this library and NuGet package:
EasyLoggerhas been renamedFastLogger.FastLoggernow logs exceptions much faster than using ILogger, thanks to the implementation of source generators.
DotNetTips.Spargine.Benchmark
In this library and associated NuGet package, I have made adjustments to the Count property for the following types:
LargeCollectionsBenchmark: Count is now adjusted to 64, 128, 256, 512, 1024, 2048, 4096, 8192.SmallCollectionsBenchmark: Count is now set to 16, 32, 64, 128, 256, 512, 1024, 2048.
Additionally, I’ve introduced a new collection benchmark with smaller counts, primarily intended for benchmarking string methods.
TinyCollectionsBenchmark: Count is now specified as 2, 4, 8, 16, 32, 64, 128, 256.
DotNetTips.Spargine.Extensions
Below are the breaking changes to this library and NuGet package:
The AddIfNotExists() method now adds an item to a collection only if it does not already exist, guaranteeing the uniqueness of items in the collection. The revised version of this method returns a Boolean value to indicate whether the addition was successful. Moreover, it has been enhanced to exclude null values from being added and includes a check for the collection’s read-only status to ensure that modifications are permitted.
Previously, several methods in Spargine that took a string representing a file or directory path have been updated to use the FileInfo or DirectoryInfo types. Here is an example:
person.ToJsonFile(new FileInfo(fileName));
DotNetTips.Spargine.Tester
This project is designed for use with your unit tests and benchmark projects. The following modifications have been implemented in this version.
PersonProper
The previous Person type has been removed, and the former PersonProper has been updated to Person.
CoordinateProper
The former Coordinate type has been eliminated, and the former CoordinateProper has been revised to Coordinate.
Other Changes
- GenerateCreditCards now returns a
ReadOnlyCollection<string>. - GenerateRefPerson has been renamed to
GeneratePersonRefto align with the naming convention of other methods in the class. - GenerateValPerson has been renamed to
GeneratePersonValto maintain consistency with other methods in the class.
Generating a Person Object
When generating a Person object, there have been some updates to the methods. The previous RandomData.GenerateRefPerson<Person>() is now replaced with RandomData.GeneratePersonRef<Address>().
Similar adjustments apply when creating a Person value type.
Generating a Collection of Person
With the previous version of Spargine, the method for creating a collection of Person for testing was as follows: RandomData.GeneratePersonRefCollection<PersonProper>(10). In the updated version, this has changed to RandomData.GeneratePersonRefCollection<Address>(10).
Similar adjustments have been made when creating a collection of Person value types.
Generating Random Phone Numbers
In the previous version of Spargine, you may recall a method called GeneratePhoneNumberUSA() which produced a random phone number specifically for the USA. This has now been updated to a more versatile method named GeneratePhoneNumber(). This revised method can take either a Country object or one of the enumerations in CountryName as parameters, allowing it to generate a proper phone number for any country. Additionally, you have the option to include the country code. Here’s an example:
var stringValue = RandomData.GeneratePhoneNumber(CountryName.Taiwan, true);
Example output for Taiwan: 886-352346002
Summary
If your team has transitioned to .NET 8, I encourage you to make the most of the updated version of Spargine and the corresponding NuGet packages. As a routine practice, if there are specific features you desire in Spargine, feel free to submit a pull request or contact me via email at dotnetdave@live.com. I rely on Spargine in my daily coding activities, and I trust it will prove valuable for you and your team as well.
Discover more from dotNetTips.com
Subscribe to get the latest posts sent to your email.
