Skip to content

Releases: MADE-Apps/MADE.NET

v3.0.0

17 May 16:42

Choose a tag to compare

Changelog

v3.0.0

Breaking Changes

Target Framework Updates

  • All libraries now target net8.0 and net10.0. Previous target frameworks have been removed.

Newtonsoft.Json Replaced with System.Text.Json

The following libraries have migrated from Newtonsoft.Json to System.Text.Json. All public APIs that previously accepted Newtonsoft.Json.JsonSerializerSettings now accept System.Text.Json.JsonSerializerOptions.

MADE.Web.Mvc

  • JsonResult constructor parameter type changed from JsonSerializerSettings to JsonSerializerOptions.
  • JsonResult.SerializerOptions property type changed from JsonSerializerSettings to JsonSerializerOptions.
  • ControllerBaseExtensions.Json() parameter type changed from JsonSerializerSettings to JsonSerializerOptions.

MADE.Web

  • All HttpResponseExtensions.WriteJsonAsync() overloads that accepted JsonSerializerSettings now accept JsonSerializerOptions.

MADE.Networking

  • Internal serialization switched from Newtonsoft.Json to System.Text.Json. All deserialization uses PropertyNameCaseInsensitive = true to maintain behavioral compatibility.
  • No public API signature changes.

MADE.Data.Serialization

  • JsonTypeMigrationSerializationBinder has been removed. Use JsonTypeMigrationConverter instead (see migration guide below).
  • AddTypeMigrationAsync has been renamed to AddTypeMigration and is now synchronous (uses lock instead of SemaphoreSlim).

IEventLogger Methods Changed from void to Task

All 15 methods on IEventLogger (WriteDebug, WriteInfo, WriteWarning, WriteError, WriteCritical and their overloads) now return Task instead of void. Implementations must be updated accordingly.

Timer Moved from MADE.Runtime to MADE.Threading

Timer and ITimer have moved from the MADE.Runtime namespace to MADE.Threading. Update using statements accordingly.

Removed Windows UWP Converters

The obsolete Windows UWP-specific partial classes BooleanToStringValueConverter.Windows.cs and DateTimeToStringValueConverter.Windows.cs (guarded by #if WINDOWS_UWP) have been removed.

Removed Dependencies

Library Removed Dependency Replacement
MADE.Networking Newtonsoft.Json System.Text.Json (built-in)
MADE.Web Newtonsoft.Json System.Text.Json (built-in)
MADE.Web.Mvc Newtonsoft.Json System.Text.Json (built-in)
MADE.Data.Serialization Newtonsoft.Json System.Text.Json (built-in)
MADE.Data.EFCore Z.EntityFramework.Plus.EFCore Custom implementation using Expression trees

New Features

MADE.Threading

  • AdaptiveSemaphore - A semaphore that dynamically adjusts its concurrency limit at runtime. Supports TryShrinkAsync() to reduce and TryGrow() to increase the permit count, bounded by configurable minimum and maximum values.
  • AsyncLazy<T> - Thread-safe lazy initialization for async factories. Supports await directly via GetAwaiter() or explicitly via GetValueAsync().
  • Debouncer - Delays execution of an action until a configurable quiet period (default 300ms) has elapsed since the last invocation. Supports both sync (Debounce) and async (DebounceAsync) actions.
  • Throttler - Limits execution of an action to at most once per configurable interval (default 300ms). Supports both sync (Throttle) and async (ThrottleAsync) actions.

MADE.Networking

  • INetworkRequestFactory / NetworkRequestFactory - Factory for creating typed network requests (Get, Post, Put, Patch, Delete, GetStream, PostMultipart). Integrates with IHttpClientFactory and supports named clients via WithClient(string clientName).
  • MultipartFormDataPostNetworkRequest - Network request for sending multipart form data, with fluent AddStringContent, AddStreamContent, and AddByteArrayContent methods.
  • RetryDelegatingHandler - An HttpMessageHandler that retries failed requests with exponential backoff. Configurable max retries (default 3) and initial delay.
  • ServiceCollectionExtensions.AddNetworkRequestFactory() - DI registration for INetworkRequestFactory with optional named HttpClient configuration.

MADE.Data.Converters

  • DateTimeToUnixTimestampValueConverter - Converts between DateTime and Unix timestamps (long).
  • StringToEnumValueConverter<TEnum> - Generic converter between string and any Enum type, with configurable case sensitivity.
  • FileSizeExtensions.ToHumanReadableFileSize() - Extension methods on long and double to format byte counts as human-readable strings (e.g., "1.5 MB").
  • TimeSpanExtensions - ToHumanReadableString() for friendly duration formatting and TotalWeeks() for week count.

MADE.Data.EFCore

  • ISoftDeletable - Interface for entities supporting soft delete, with IsDeleted and DeletedDate properties.
  • IAuditableEntity - Interface for entities tracking CreatedBy and UpdatedBy.
  • SoftDeleteExtensions - Extension methods for applying global soft-delete query filters (ApplySoftDeleteFilter), marking entities as soft-deleted (SoftDelete), restoring them (Restore), and intercepting deletions to convert them to soft deletes (InterceptSoftDeletions).
  • QueryableExtensions.Page() - Pagination extension using Skip/Take.
  • QueryableExtensions.OrderBy() - Dynamic ordering by property name using Expression trees, replacing Z.EntityFramework.Plus.EFCore.

MADE.Data.Validation

  • IAsyncValidator - Async counterpart to IValidator, with ValidateAsync(object value, CancellationToken).
  • AsyncValidatorCollection - Collection of IAsyncValidator instances with aggregate validation via ValidateAsync(), exposing IsInvalid, IsDirty, and FeedbackMessages.

MADE.Web.Mvc

  • ForbiddenObjectResult - An ObjectResult that returns HTTP 403 Forbidden with a response body.

MADE.Testing (New Library)

A new test-framework-agnostic assertion library with fluent Should* extension methods:

  • BooleanAssertExtensions - ShouldBeTrue(), ShouldBeFalse()
  • ObjectAssertExtensions - ShouldBeNull(), ShouldNotBeNull()
  • StringAssertExtensions - ShouldContain(), ShouldNotContain(), ShouldStartWith(), ShouldEndWith()
  • ComparableAssertExtensions - ShouldBeGreaterThan(), ShouldBeGreaterThanOrEqualTo(), ShouldBeLessThan(), ShouldBeLessThanOrEqualTo()
  • ExceptionAssertExtensions - ShouldThrow<T>(), ShouldThrowAsync<T>(), ShouldNotThrow(), ShouldNotThrowAsync()

Bug Fixes

  • Timer.Start dueTime calculation - Fixed Timer.Start(TimeSpan dueTime) using dueTime.Milliseconds (the milliseconds component only, 0-999) instead of (int)Math.Ceiling(dueTime.TotalMilliseconds) (the full duration). This caused timers with due times of 1 second or more to use incorrect delays.
  • Timer.Start not updating DueTime property - Start(TimeSpan dueTime) and Start(int dueTime) overloads now correctly update the DueTime property before starting the timer.

Migration Guide

Newtonsoft.Json to System.Text.Json

Replace using Newtonsoft.Json with using System.Text.Json and update any JsonSerializerSettings references to JsonSerializerOptions.

// Before (v2)
using Newtonsoft.Json;

var result = controller.Json(value, HttpStatusCode.OK, new JsonSerializerSettings
{
    NullValueHandling = NullValueHandling.Ignore
});

// After (v3)
using System.Text.Json;

var result = controller.Json(value, HttpStatusCode.OK, new JsonSerializerOptions
{
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
});

JsonTypeMigrationSerializationBinder to JsonTypeMigrationConverter

The Newtonsoft.Json-based JsonTypeMigrationSerializationBinder in the MADE.Data.Serialization.Json.Binders namespace has been replaced with JsonTypeMigrationConverter in the MADE.Data.Serialization.Json.Converters namespace.

// Before (v2)
using MADE.Data.Serialization.Json.Binders;

var binder = new JsonTypeMigrationSerializationBinder();
binder.AddTypeMigration(new JsonTypeMigration("OldAssembly", "OldNamespace.OldType", typeof(NewType)));

var settings = new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.All,
    SerializationBinder = binder
};
var result = JsonConvert.DeserializeObject<object>(json, settings);

// After (v3)
using MADE.Data.Serialization.Json.Converters;

var converter = new JsonTypeMigrationConverter();
converter.AddTypeMigration(new JsonTypeMigration("OldAssembly", "OldNamespace.OldType", typeof(NewType)));

var options = new JsonSerializerOptions();
options.Converters.Add(converter);
var result = JsonSerializer.Deserialize<object>(json, options);

Timer Namespace Change

// Before (v2)
using MADE.Runtime;

// After (v3)
using MADE.Threading;

Code Quality Improvements

  • File-scoped namespaces: All source files converted to file-scoped namespace declarations.
  • ConfigureAwait(false): Added to all await expressions in library code to prevent deadlocks in synchronization-context-bound environments.
  • ArgumentNullException.ThrowIfNull: Replaced manual null-check-and-throw patterns with ArgumentNullException.ThrowIfNull().
  • Nullable reference type annotations: Added ? annotations to parameters, return types, fields, and properties that accept or return null.
  • Async correctness: FileEventLogger and AppDiagnostics rewritten for proper async patterns, removing async void methods.
  • Comprehensive .editorconfig: Added modern .NET analysis rules including CA2007, CA1822, CA1849, and async naming conventions.

v2.0.0

29 Dec 21:18

Choose a tag to compare

What's Changed

This release brings support for .NET 7 & 8, as well as significant increments to package dependencies.

Support for Xamarin specific application code has been removed in this version. UWP support increases to a minimum of the last stable release of Windows 10.

Full Changelog: v1.6.0...v2.0.0

v1.7.0-preview1

30 Aug 17:42

Choose a tag to compare

v1.7.0-preview1 Pre-release
Pre-release

What's Changed

Full Changelog: v1.6.0...v1.7.0-preview1

v1.6.0

24 May 08:55
4c54e00

Choose a tag to compare

Collections

  • Added Sort and SortDescending extensions for ObservableCollection instances
  • Added IsNullOrEmpty validation extension for IEnumerable instances
  • Added GetValueOrDefault extension for Dictionary instances
  • Removed UWP as target framework (no longer required)

Data Converters

  • Added ToFormattedString extension to bool and nullable bool instances
  • Added ToDelimitedString extension for IEnumerable objects with custom string delimiter option
  • Added ToMeters and ToMiles conversion extensions for double instances
  • Modified the BooleanToStringValueConverter to extract non-platform specific logic out to be used cross-platforms
  • Marked the UWP specific value converters as obsolete and target the UI.Data.Converters library

Data Entity Framework

  • Added Page and column name based OrderBy extensions for Entity Framework Queryable objects to ease the implementation of paginated requests
  • Updated EF Core and EF Core Plus packages to latest versions

Data Serialization

  • Added Data.Serialization library with a service for handling type migrations within JSON files saved with Type information contained within it

Data Validation

  • Added IValidationCollection interface that can be used to create custom validation collection solution and updated the ValidatorCollection implementation to support this
  • Added Base64Validator to ensure a value is a valid bas64 string
  • Added GuidValidator to ensure a value can be parsed as a GUID
  • Added LongitudeValidator and LatitudeValidator to ensure a value is within the expected ranges for lat and long
  • Added MacAddressValidator to ensure a value is a valid MAC address using the .NET PhysicalAddress parser
  • Added PredicateValidator to provide a mechanism to validate objects based on custom validation logic for it
  • Added WellFormedUrlValidator to ensure a value is considered a well-formed URL (https/http/ftp/etc.)
  • Updated BetweenValidator to include Inclusive flag to customize the min/max range of validity
  • Updated the Validate method to virtual to allow custom pre or post validation logic for custom built regular expression validators
  • Removed UWP as target framework (no longer required)

Data Validation for Fluent Validation

Runtime

  • Added GetPropertyNames extension for object instances to get all the property names from the specified object as a list of strings

What's Changed

Full Changelog: v1.5.0...v1.6.0

v1.6.0-preview2

28 Apr 06:34
9b40476

Choose a tag to compare

v1.6.0-preview2 Pre-release
Pre-release

What's Changed

Full Changelog: v1.6.0-preview1...v1.6.0-preview2

v1.6.0-preview1

27 Apr 12:57
ea7492d

Choose a tag to compare

v1.6.0-preview1 Pre-release
Pre-release

What's Changed

Added validation support for FluentValidation, and providing the framework to build out for other validation frameworks.

To be tested with MADE for Uno Platform.

Full Changelog: v1.5.0...v1.6.0-preview1

v1.5.0

16 Apr 18:12
0bde84a

Choose a tag to compare

  • Added AddIf, AddRangeIf, RemoveIf, RemoveRangeIf conditional collection extensions
  • Added Shuffle collection extension for randomly sorting an enumerable
  • Added ToDaySuffix date extension to provide the st, nd, rd, or th day suffix
  • Added Truncate string extension for shortening a value with an ellipsis suffix (...)
  • Added to/from Base 64 string conversion extensions and value converter
  • Updated EntityBase configuration to support setting up the primary key ID
  • Added IsLike string extension for validating a wildcard LIKE style query against a specified value (e.g. "He*")
  • Added JsonResult and controller extensions to support returning the JSON result and internal server error result
  • Added dependency injection extensions for registering included web services such as the user accessor, and exception handling
  • Updated EF NuGet packages to latest versions, supporting .NET 5 & 6 (dropped support for .NET Core 3.1)
  • Added extensions for easily enabling API versioning via URL or header
  • Migrated out Uno Platform / Windows specific components to MADE-Uno

What's Changed

Full Changelog: v1.4.0...v1.5.0

v1.4.0

10 Nov 21:38
d2a1346

Choose a tag to compare

What's Changed

Introduced .NET 6 support for the Web and Web MVC projects.

Full Changelog: v1.3.2...v1.4.0

v1.3.2

06 Nov 15:18
7b2a2dc

Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v1.3.1...v1.3.2

Release 1.3.1

20 Oct 19:22
d86de66

Choose a tag to compare

Packages available on NuGet

What's Changed 🤔

Bump NuGet packages ☝🏻

NuGet packages have been bumped to newer minor releases. These include:

  • Uno [3.9.7 => 3.10.11]
  • EF Core (.NET 5) [5.0.9 => 5.0.11]
  • EF Core (.NET Core 3.x) [3.1.18 => 3.1.20]

More Information 💭

Full Changelog: 1.3.0...v1.3.1