MmiSoft.Core 0.1.7

dotnet add package MmiSoft.Core --version 0.1.7                
NuGet\Install-Package MmiSoft.Core -Version 0.1.7                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MmiSoft.Core" Version="0.1.7" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add MmiSoft.Core --version 0.1.7                
#r "nuget: MmiSoft.Core, 0.1.7"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install MmiSoft.Core as a Cake Addin
#addin nuget:?package=MmiSoft.Core&version=0.1.7

// Install MmiSoft.Core as a Cake Tool
#tool nuget:?package=MmiSoft.Core&version=0.1.7                

Toolbox

Build status Build status Nuget Nuget

About

A collection of classes methods and utilities that seem useful and quite common to me. The code is pretty simple and most of the times what you need to know is in documentation, which admittedly is not complete yet.

Currently the library's public API is NOT stable. It might change as I evolve the projects using it. That said and since the project is for self-learning, I am trying to maintain backwards compatibility, pretend that there are other people besides me using it, and undergo the whole 9 yards of maintaining a shared library. As the versioning is not 100% compatible with semver yet, messages of commits with breaking changes will be prefixed with BREAKING.

Most of the code comes from elements of DARSSY and thus this code is used in a real world application. Now where I come from we use to say "one equals none" but I say one is better than none. Anyway, once I decide which parts of the original code I will open source, I will release a stable 1.0 version, hopefully with some unit tests as well. Currently the test coverage is at a humble 25%.

Contents

Like with a real toolbox, you need to know its contents before you open it, before even taking it onboard. Either an amateur handyman looking at the toolbox and wondering "what we have here" or a professional one who knows with eyes closed what's where, the result is the same. You need to know your toolbox's contents. Let's go then:

(Attention: work in progress)

Extensions

Extension methods can be a powerful tool (LINQ anyone?) and there are some framework types that could benefit from extension methods. For example I find it more practical to get an absolute value from the subtraction of 2 signed numbers like this (a - b).Abs() instead of Math.Abs(a - b). The former is more fluent.

It's worth noting that most of the "wrapper" extensions (like Abs Round etc) are AggressiveInlined and some early benchmarks show that inlining makes a difference. Not all methods have the inline directive at them but the goal is to add it everywhere there is a benefit from it. For example .NET Framework 4.8 fails to inline methods that are calling a delegate but in .NET 7 that's not the case.

Bellow you can find a list of the most important extension methods grouped per category.

Collections

static T Last<T>(this IList<T> list)<br/> Retrieves the last element of a list. That is if you can't use list[^1]

LinkedListNode<T> GetNode<T>(this LinkedList<T> list, Func<T, bool> condition)<br/> Retrieves an element that fulfills the provided condition

V GetOrCreate<K, V>(this IDictionary<K, V> dictionary, ...) overloads<br/> Tired of the "if exists then get it otherwise create it" pattern? So was I, hence the GetOrCreate extension. Example:

SolidBrush solidBrush = BrushCache.GetOrCreate(e.Item.BackColor, color => new SolidBrush(color));
e.Graphics.FillRectangle(solidBrush, new Rectangle(Point.Empty, e.Item.Size));

or if you don't care about the closure allocation:

SolidBrush solidBrush = BrushCache.GetOrCreate(e.Item.BackColor, () => new SolidBrush(e.Item.BackColor));
e.Graphics.FillRectangle(solidBrush, new Rectangle(Point.Empty, e.Item.Size));
String and char extensions

Join(this IEnumerable<char> chars, char separator = ' ')<br/>Allows us to join a series of characters with another character. Similar to string.Join().

Logging

You can use EventLogger static class logger wrapper if you want to wrap a logging library inside an ILogWrapper and then switch implementation if you change your mind. You can skip EventLogger altogether and go straight to ILogWrapper if you are hard-core into DI, but I consider it an overkill. Whenever I want to log, I want to log. Not to think how the heck I could get the logger in XYZ class.

You can use ConsoleLogWrapper which logs in the console; it is suggested only in early testing cases as most sophisticated logging libraries have a gazillion of sinks, among others a Console sink.

UnitTestLogger can help you assert that some logs were created during a run. Useful when you want to ensure that the test executed a part of the code that you can't easily "reach" otherwise.

Finally, LogEntry struct can be used to hold log creation time, severity, message and optionally the exception

Railway Oriented Programming (ROP)

Well not exactly ROP as ROP is a more complex concept than just a Result type, but the Result and its variants are inspired by the ROP concept. Use a Result return type when a method failing is not an exceptional case and as a result throwing an exception is an overkill. Instead of using an out argument which might not be elegant or even practical you can return a Result<ActualResultType, string> where the second generic argument is the text describing the possible error.

It's worth to note that Result and its variants are not "just tuples" but they also contain properties (like Success for example to check the status) and implicit cast operators that help reduce boilerplate.

Product Compatible and additional computed target framework versions.
.NET net7.0-windows7.0 is compatible.  net8.0-windows was computed. 
.NET Framework net462 is compatible.  net463 was computed.  net47 was computed.  net471 was computed.  net472 is compatible.  net48 is compatible.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on MmiSoft.Core:

Package Downloads
SharpConvert.JsonNet

JSON.net additions for SharpConvert.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.1.7 139 4/16/2024
0.1.6 156 1/14/2024
0.1.5 160 6/24/2023
0.1.4 165 6/20/2023