JamSoft.Helpers
1.1.0
See the version list below for details.
dotnet add package JamSoft.Helpers --version 1.1.0
NuGet\Install-Package JamSoft.Helpers -Version 1.1.0
<PackageReference Include="JamSoft.Helpers" Version="1.1.0" />
paket add JamSoft.Helpers --version 1.1.0
#r "nuget: JamSoft.Helpers, 1.1.0"
// Install JamSoft.Helpers as a Cake Addin #addin nuget:?package=JamSoft.Helpers&version=1.1.0 // Install JamSoft.Helpers as a Cake Tool #tool nuget:?package=JamSoft.Helpers&version=1.1.0
<img align="center" height="50" src="img/logo.png">
JamSoft.Helpers
A collection of general helpers for applications and libraries. The goal is to provide convienience methods and core building blocks. All in a cross-platform .NET Standard 2.0 library with minimal dependencies.
GitHub Pages Site
https://jamsoft.github.io/JamSoft.Helpers/
Install
Nuget
Install-Package JamSoft.Helpers -Version 1.1.0
CLI
dotnet add package JamSoft.Helpers --version 1.1.0
Package Reference
<PackageReference Include="JamSoft.Helpers" Version="1.1.0" />
Package Reference
paket add JamSoft.Helpers --version 1.1.0
xUnit Tests
There is a high level of test coverage as shown in the badge above (around 97%), however, at the moment the pipeline executes only on Windows which means some tests cannot be run in this environment. The library has been fully tested on Windows 10, OSX Catalina and Fedora 31.
The following test classes also show basic example implementations and uses of the provided pattern classes.
- ObserverTests
- MementoTests
- MyTestViewModel
- ATestSettingsClass
- BTestSettingsClass
- PersonViewModel
Configuration & Settings
Rather than getting embroiled in the convoluted and sometimes awkward user settings infrastructure provided by .NET (*.settings), sometimes you just want to store some values in a file, yes?
The issues and additional complications around user.config and strong names can sometimes get in the way. Using the SettingsBase<T>
class can bypass this.
Set Up
Create a POCO class containing your settings properties, default values and inherit SettingsBase<T>
, such as:
public sealed class MySettings : SettingsBase<MySettings>
{
public string ASetting { get; set; } = "A Default Value";
}
Loading & Access
Now you can load, save and manage your settings at rumetime like:
string myDefaultSettingsPath = "C:\Some\location\on\disk";
MySettings.Load(myDefaultSettingsPath);
This call will either load the settings from a file called mysettings.json
, the name is automatically taken from the type name, or if no file exists, the defaults are loaded.
You can also load and save from a provided file name instead of deriving from the type name, such as:
string myDefaultSettingsPath = "C:\Some\location\on\disk";
MySettings.Load(myDefaultSettingsPath, "custom-name.json");
You can access the values using the instance:
var theValue = MySettings.Instance.ASetting;
Or
MySettings.Instance.ASetting = theValue;
Saving
Saving the settings is a call to the Save()
method, like:
MySettings.Save();
This will always save back to the same file the settings were originally loaded from, or if there was no file, the file will be created and the settings saved.
Reset
You can easily return back to the defaults by calling the ResetToDefaults()
method, like:
MySettings.ResetToDefaults();
This will reset all settings to their default values and immediately write them to disk. If you do not want to write them to disk, simply pass a false
to the method.
MySettings.ResetToDefaults(saveToDisk:false);
Dirty Object Tracking
Using the attributes and validators you can track classes with changes, such as view models, in order save new data or update UI state accordingly.
First implement the simple interface on your class, such as:
public class PersonViewModel : IDirtyMonitoring
{
public string Name { get; set; }
[IsDirtyMonitoring]
public string DisplayName { get; set; }
public bool IsDirty { get; set; }
public string Hash { get; set; }
}
In this example only the DisplayName
property is monitored for changes. After an object has completed being initialised and is in it's "clean" state, validate it.
IsDirtyValidator.Validate(p);
Now, at any point in time you can validate it again to detect if the class is dirty.
p.DisplayName = "Original";
IsDirtyValidator.Validate(p).IsDirty; // false
p.DisplayName = "SomedifferentValue";
IsDirtyValidator.Validate(p).IsDirty; // true
p.DisplayName = "Original";
IsDirtyValidator.Validate(p).IsDirty; // false
In order to restart the whole validation process, simply call the Validate
method and pass a true
in the reset parameter.
IsDirtyValidator.Validate(p, true).IsDirty // false
At the moment this is limited to just informing you that the object is different, not which properties contain new values. This is planned for a future release.
Collections
Shuffle Collections
IEnumerable<int> ints = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IEnumerable<int> shuffledInts = ints.Shuffle();
Or you can provide your own instance of Random
.
Random randomiser = new Random();
IEnumerable<int> ints = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IEnumerable<int> shuffledInts = ints.Shuffle(randomiser);
Environment Variables
There are a handful of helper methods and classes for access environment variables on various platforms.
Common Variables
var path = EnvEx.GetVariable(EnvExVariableNames.Path);
Windows Variables
var appData = EnvEx.GetVariable(EnvExWinVariableNames.AppData); // C:\Users\username\AppData\Roaming
OSX Variables
var shell = EnvEx.GetVariable(EnvExOsxVariableNames.Shell); // "/bin/bash"
Linux Variables
var manPath = EnvEx.GetVariable(EnvExLinuxVariableNames.ManPath); // ":"
More variables names are included in the library than are shown above. You can make use of these via helper constants in the following classes:
- EnvExVariableNames (Common)
- EnvExWinVariableNames
- EnvExOsxVariableNames
- EnvExLinuxVariableNames
Since the EnvEx.GetVariable
method just takes a string, any value can be passed, such as:
var envValue = EnvEx.GetVariable("MYVARIABLENAME");
On Window you can also pass a target parameter of type EnvironmentVariableTarget
. The default for this is Process
as Linux and OSX do not support this parameter. If anything
other than Process
is passed on a non-Windows platform it will be defaulted to Process
to prevent exceptions being raised.
RSA Cryptography
There is a new little class to help digitally sign data with RSA Cryptography. The main class is created via a factory which can be registered in your DI container of choice.
public interface IRsaCryptoFactory
{
}
container.Register<IRsaCryptoFactory, RsaCryptoFactory>();
You can then use this factory to obtain instances of the service.
var crypto = cryptoFactory.Create();
There are many overloads of the create method to control how the service is built and how you want it configued.
You should also wrap each use of this within a using statement such as:
using(var crypto = cryptoFactory.Create(_privateKey, _publicKey, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1))
{
// do your stuff.
}
Once you have created an instance if you do not provide either of the keys, you can obtain the used keys for storage via the two properties, such as:
var crypto = cryptoFactory.Create();
var publicKey = sut.PublicKey;
var privateKey = sut.PrivateKey;
Graphics
Convert to HEX
int red = 121;
int green = 155;
int blue = 56;
var hex = Graphics.Colors.ToHex(red, green, blue);
Or you can also use an alpha value.
var hex = Graphics.Colors.ToHex(alpha, red, green, blue);
You can also pass values as an array
var hex = Graphics.Colors.ToHex(new[] { alpha, red, green, blue });
Convert to RGB
int red = 255;
int green = 169;
int blue = 104;
var color = Graphics.Colors.ToRgb("#FFA968");
Convert to ARGB
This can be useful for WPF and XAML which supports an alpha value in the HEX.
int alpha = 255;
int red = 146;
int green = 145;
int blue = 145;
var c = Graphics.Colors.ToArgb("#FF929191");
Human Readable UI Values
Data Sizes
Converts integer
and long
values representing data sizes to human readable form
int input = 10000000;
input.ToHumanReadable(); returns "9.54 Mb"
long input = 2000000000000000000;
input.ToHumanReadable(); returns "1.73 Eb"
Time
double input = 3657;
input.ToTimeDisplayFromSeconds() returns "01:00:57"
double input = 3657.12;
input.ToTimeDisplayFromSeconds(withMs: true) returns "01:00:57:120"
Math Things
Even or Odd
Even number detection
int value = 2;
var isMyNumberEven = value.IsEvenNumber();
Percentages
Basic percentage calculations
int value = 500;
int total = 2000;
var percent = value.IsWhatPercentageOf(total) // 25
String Distances
Hamming Distance
Calculates the number of edits required to go from one string to another must be equal lengths to start
var inputOne = "InputString1";
var inputTwo = "InputString2";
var distance = Distance.GetHammingDistance(inputOne, inputTwo);
inputOne.HammingDistanceTo(inputTwo)
Levenshtein Distance
Calculates the number of edits required to go from one string to another
var inputOne = "InputString1";
var inputTwo = "InputString2";
var distance = Distance.GetLevenshteinDistance(inputOne, inputTwo);
inputOne.LevenshteinDistanceTo(inputTwo)
Shorten Strings
This method allows you to shorten strings to a predetermined length and pad with ...
or any pattern you provide.
string input = "Thisismylongstringthatneedsshortening";
var result = input.DotShortenString(10, 20); // "Thisism...shortening"
string input = "Thisismylongstringthatneedsshortening";
var result = input.DotShortenString(10, 20, ";;;"); // "Thisism;;;shortening"
Remove All Multispaces
var input = " This has too many spaces ";
input.RemoveAllMultiSpace(); // " This has too many spaces "
var input = " This has too many spaces ";
input.RemoveAllMultiSpace(trim:true); // "This has too many spaces"
var input = " This has too many spaces ";
input.RemoveAllMultiSpace("--"); // "--This--has--too--many--spaces--"
var input = " This has too many spaces ";
input.RemoveAllMultiSpace(pattern:"--", trim:true) // "This--has--too--many--spaces"
String Compare
string input = "string1";
string pattern = "strinG1";
input.IsExactlySameAs(pattern); // false
Serialization
XML Encoding Formatting
Adds a strict uppercased UTF-8 to XML declarations
using (var sw = new UppercaseUtf8StringWriter())
{
xsSubmit.Serialize(sw, new TestObject { SomeProperty = "SomeValue" });
xml = sw.ToString();
}
Patterns
Mvvm - ViewModelBase
A very bare bones view model with property changed updates
public abstract class ViewModelBase : INotifyPropertyChanged
{
...
public bool IsEditable ...
...
public bool IsBusy ...
...
protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = "")
{
...
}
}
Mvvm - SuperObservableCollection<T>
An observable collection that mutes change notifications when adding a range of objects and allows sorting
public class SuperObservableCollection<T> : ObservableCollection<T>
{
public SuperObservableCollection(IEnumerable<T> coll)
{
}
public void AddRange(IEnumerable<T> list, bool suppressNotifications = true, bool notifiyOnceAllAdded = true)
{
...
}
public void Sort(bool suppressNotifications = false)
{
...
}
public void Sort(IComparer<T> comparer, bool suppressNotifications = false)
{
...
}
}
Observer
A very basic implementation of the core bits of the observer pattern
public interface IObservable
{
void Attach(IObserver observer);
void Detach(IObserver observer);
void Notify();
}
public interface IObserver
{
void Update(IObservable observable);
}
public abstract class ObservableBase : IObservable
{
}
Memento
public interface IMemento
{
object GetState();
}
public interface IMementoOwner
{
IMemento Save();
void Restore(IMemento memento);
}
public class MementoManager
{
...
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 is compatible. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.8
- System.Text.Json (>= 6.0.4)
-
.NETStandard 2.0
- System.Text.Json (>= 6.0.4)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on JamSoft.Helpers:
Package | Downloads |
---|---|
JamSoft.Helpers.AvaloniaUI
A collection of general helpers for AvaloniaUI applications. |
GitHub repositories
This package is not used by any popular GitHub repositories.