SamSoft.Common
1.2.2
dotnet add package SamSoft.Common --version 1.2.2
NuGet\Install-Package SamSoft.Common -Version 1.2.2
<PackageReference Include="SamSoft.Common" Version="1.2.2" />
<PackageVersion Include="SamSoft.Common" Version="1.2.2" />
<PackageReference Include="SamSoft.Common" />
paket add SamSoft.Common --version 1.2.2
#r "nuget: SamSoft.Common, 1.2.2"
#:package SamSoft.Common@1.2.2
#addin nuget:?package=SamSoft.Common&version=1.2.2
#tool nuget:?package=SamSoft.Common&version=1.2.2
SamSoft.Common
SamSoft.Common is a .NET class library that centralizes reusable building blocks for application code: a Result model with structured errors, an optional Maybe<T> type, and many extension methods for strings, collections, dates, binary data, and cryptography.
| Target framework | .NET 8.0 |
| Language | C# (nullable reference types enabled) |
| License | MIT (see PackageLicenseExpression in SamSoft.Common.csproj) |
| Package readme | This file is packed as the NuGet readme (PackageReadmeFile) |
Table of contents
- Why use this library
- Installation
- Repository layout
- Namespaces and API reference
- Behavior notes and pitfalls
- Security (cryptography)
- Build, test, and package
- Versioning and releases
- Contributing
Why use this library
- Predictable error handling — Model failures with
Result/Errorinstead of scattering try/catch for control flow. - Optional values —
Maybe<T>for presence/absence without overloadingnullsemantics everywhere. - Less boilerplate — Extensions for common string, collection, and date operations used across services and UI layers.
- Single dependency surface — One package instead of copying helpers into each solution.
Installation
Project reference (source / monorepo)
<ItemGroup>
<ProjectReference Include="..\SamSoft.Common\SamSoft.Common.csproj" />
</ItemGroup>
NuGet (when the package is published)
dotnet add package SamSoft.Common
Ensure the consuming project targets .NET 8 or higher (or a compatible TFM that can reference net8.0 libraries).
Repository layout
SamSoft.Common/
├── SamSoft.Common/ # Main library (net8.0)
│ ├── Enums/ # CurrencyCodes, CurrencyCodeExtension
│ ├── ExtensionMethods/ # String, enumerable, date, crypto, etc.
│ ├── OptionObject/ # Maybe<T>, MaybeExtensions
│ ├── Results/ # Result, Result<T>, Error, ResultExtensions
│ └── TokenResponse.cs
├── SamSoft.Common.Tests/ # Unit tests (xUnit.net v3)
├── SamSoft.Common.sln
└── README.md # This file (also packed for NuGet)
Namespaces and API reference
SamSoft.Common.Results
| Type | Purpose |
|---|---|
Result |
Discriminated success/failure without a value. IsSuccess / IsFailure, Error on failure. |
Result<TValue> |
Success carries Value; on failure Value is default. Implicit conversion from T to success. |
Error |
Record: Code, Message, ErrorType. Static helpers: Failure, Validation, NotFound, Conflict, Problem, Create(Exception). Error.None, Error.NullValue. Implicit conversions to string (code) and Result. |
ErrorType |
Failure, Validation, NotFound, Conflict, Problem, None. |
ResultExtensions |
Ensure, Map (sync and Task), Map on Task<Result> → bool, Bind (async), TryCatch, Tap, Match (async overloads), FirstFailure. |
Result factories
Result.Success(),Result.Success<T>(T value)Result.Failure(Error),Result.Failure<T>(Error)Result.Create<T>(T? value, Error)/Result.Create<T>(T value)(reference types)Result.FirstFailureOrSuccess(params Result[] results)
SamSoft.Common.OptionObject
| Type | Purpose |
|---|---|
Maybe<T> |
HasValue / HasNoValue, Value (throws if none), None, From(T?), implicit T → Maybe<T>. GetValueOrDefault(), GetValueOrDefault(T), TryGetValue(out T). Equals / GetHashCode. |
MaybeExtensions |
Bind (async), Match on Task<Maybe<T>>. |
SamSoft.Common (root)
| Type | Purpose |
|---|---|
TokenResponse |
Primary constructor: token, expiry, isSuperAdmin, refreshToken, tenantId, isAdmin. Properties: Token, Expiry, IsSuperAdmin, IsAdmin, RefreshToken, TenantId. |
SamSoft.Common.Enums
| Type | Purpose |
|---|---|
CurrencyCodes |
ISO-style numeric currency enum with [Description] metadata; JSON string enum converter. |
CurrencyCodeExtension |
GetCurrencyName(this CurrencyCodes) — resolves description from attributes. |
SamSoft.Common.ExtensionMethods (selected groups)
StringExtension
Null-tolerant helpers where applicable: IsNotNullOrEmpty, EqualWithIgnoreCase, NotEqual, IsNumeric, ToCamelCase, IsDate, IsValidEmailAddress, IsValidUrl, IsGuid, ToInt (with optional default), ToDecimal, ToDateTime (multiple overloads), IsDateTime, ToBoolean, IsEmailAddress, IsValidJson, TryParseJson<T>, ToTitleCase, IsArabic, TryGetInt, FormatWithMask (two overloads), IsDateTime with format → (bool, DateTime), IsNumber.
EnumerableExtensions
IsNullOrNotItem, NotNullOrEmpty, Do, ForEach (three overloads: Action, non-generic IEnumerable, Func projection), RemoveAll on ICollection<T>, Count for non-generic IEnumerable, SetValue, IsNullOrEmpty, NotExists (with/without predicate), ForEachAsync, SelectManyRecursive, IsNotNullOrEmpty, ToObservableCollection, ConvertTo, Each, Cache.
PredicateBuilder
And, Or for combining Expression<Func<T, bool>> with parameter rebinding (useful for dynamic LINQ to Entities predicates).
DateTimeExtensionMethods
TryParseTime, IsValidTime (string), ToDateByLocalTime (Egypt Standard Time), GetLocalFromUtc, DateOnly/DateTime conversions, Range between dates, BeginOfMonth / EndOfMonth, BeginOfYear / EndOfYear, WithoutMilliseconds, ConvertToUrlFormat, ToDateFromUrlFormat, EndOfDay, IsBetween, ConvertToSqlFormat, GetDateTimeSqlFormat.
EnumExtensionMethods
GetDescription, ToEnum<TEnum>, ToValues<T> (flags-style enumeration; see pitfalls).
GuidGenerator / GuidVersion
Time-based GUID generation (GenerateTimeBasedGuid overloads), GetVersion, GetDateTimeOffset / GetDateTime / GetLocalDateTime / GetUtcDateTime.
TextEncryptDecrypt
Legacy: SsEncrypt, SsDecrypt. Secure: SsEncryptSecure, SsDecryptSecure (password, optional PBKDF2 iterations). See Security.
DeepCopyHelper
DeepCopy<T> via System.Text.Json serialize/deserialize (throws if deserialization yields null).
ExceptionExtension
GetInnerExceptionString, ToFullBlownString, GetMostInner, ExceptionJson.
HashCodeByPropertyExtensions
GetHashCodeOnProperties, GetListHashCode.
ByteArrayExtension / GetFileDataFromFileUrl
GetImageUrl, GetMimeType, FromImageUrl → Result<FileData>.
FileData
Record FileData(byte[] File, string MimeContentType); CreateFromUrl with MIME allowlist validation.
Behavior notes and pitfalls
Maybe<T> and value types
HasNoValue is implemented as _value is null. For reference types, null means “none.” For unconstrained value types (e.g. Maybe<int>), there is no distinct “none” separate from default(T); None and 0 are not distinguishable the same way as for references. Prefer Maybe<T?> (e.g. Maybe<int?>) or reference types when you need a clear empty state.
EnumerableExtensions.ForEach and lambdas
There are two ForEach overloads: one takes Action<T>, another Func<T, TResult>. A lambda like x => n += x can bind to the Func overload (because += yields a value). Use a block x => { n += x; } when you intend side effects only.
EnumExtensionMethods.ToValues<T>
Validation (T must be an enum type) runs when the iterator is executed (e.g. foreach, ToList()), not merely when ToValues() is called.
JSON deep copy
DeepCopy<T> depends on System.Text.Json semantics. Polymorphic graphs, cycles, or types that do not round-trip cleanly may fail or throw.
DateTimeExtensionMethods.ToDateByLocalTime
Uses TimeZoneInfo.FindSystemTimeZoneById("Egypt Standard Time"). Availability depends on the OS time zone database; call sites should handle missing zones if you deploy cross-platform.
Security (cryptography)
| API | Use case |
|---|---|
SsEncrypt / SsDecrypt |
Legacy compatibility only for data encrypted by older versions. Weak by modern standards (fixed IV, MD5-based key material). Do not use for new secrets. |
SsEncryptSecure / SsDecryptSecure |
Preferred for new data: random salt and IV per message, PBKDF2 (SHA-256), AES-CBC. Pass passwords or key material from configuration, vaults, or user input—never embed secrets in source code or commit them to the repository. |
Rotate keys and migration strategies if you move from legacy to secure formats.
Build, test, and package
# Restore and compile
dotnet build SamSoft.Common.sln
# Run tests (xUnit.net v3)
dotnet test SamSoft.Common.sln
# Optional: create a NuGet package
dotnet pack SamSoft.Common/SamSoft.Common.csproj -c Release
The test project (SamSoft.Common.Tests) targets .NET 8 and uses xUnit.net v3 with broad coverage of public APIs and regression scenarios.
Versioning and releases
- Assembly and NuGet version are driven by
SamSoft.Common.csproj(AssemblyVersion,Version,FileVersion). - Bump the version when you publish a new package or introduce breaking API changes (document them for consumers).
- License acceptance:
PackageRequireLicenseAcceptanceis set in the project file; consumers may need to acknowledge the MIT license in internal feeds.
Contributing
- Keep changes focused and consistent with existing naming and patterns.
- Add or update unit tests in
SamSoft.Common.Testsfor any new or changed behavior. - Update this README when you add public API surface that users depend on.
- Do not commit secrets, credentials, or production connection strings.
Additional resources
- Result pattern (background): the
ErrorTypeenum file references an external talk link in source; seeErrorType.csin the repository.
For questions or improvements, use your team’s usual code review and issue workflow.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on SamSoft.Common:
| Package | Downloads |
|---|---|
|
SamSoft.Mediator.CQRS
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.