Skip to content

Commit ee45ce8

Browse files
committed
docs: enhance documentation and features across multiple articles
- Updated threading.md to include ITimer interface and TaskExtensions for better async task handling. - Added JsonResult for returning JSON with custom status codes in web-mvc.md. - Introduced AuthenticatedUser and API versioning support in web.md. - Revised intro.md to reflect updated target frameworks and added new features in various packages. - Removed obsolete Media Image section from the table of contents. - Updated docfx.json to target net10.0 and modified templates for a modern look. - Created a new custom CSS file for improved styling on the landing page. - Deleted outdated material template files to streamline the documentation structure. - Adjusted table of contents to point to articles instead of docs.
1 parent 0abfbe3 commit ee45ce8

19 files changed

Lines changed: 620 additions & 813 deletions

File tree

.github/workflows/docs.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,9 @@ jobs:
3737
- name: Install DocFX
3838
run: dotnet tool install -g docfx
3939

40-
- name: Generate DocFX metadata
41-
working-directory: docs
42-
run: docfx metadata docfx.json
43-
continue-on-error: false
40+
- name: Restore projects
41+
run: dotnet restore
42+
working-directory: src
4443

4544
- name: Build DocFX site
4645
working-directory: docs

docs/articles/features/collections.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,81 @@ public async Task ProcessMessagesAsync(IEnumerable<Message> messages, Cancellati
158158
}
159159
}
160160
```
161+
162+
There is also a `Chunk` extension for `IQueryable<T>` in the `MADE.Collections.QueryableExtensions` class, which splits a query into smaller queries for batch processing.
163+
164+
## Conditionally adding or removing items with AddIf and RemoveIf
165+
166+
The `AddIf` and `RemoveIf` extensions on `IList<T>` allow you to add or remove an item based on a condition function.
167+
168+
```csharp
169+
public void AddPermissionIfAdmin(IList<Permission> permissions, Permission permission, bool isAdmin)
170+
{
171+
permissions.AddIf(permission, () => isAdmin);
172+
}
173+
```
174+
175+
Similarly, `AddRangeIf` and `RemoveRangeIf` extensions allow you to conditionally add or remove a collection of items.
176+
177+
## Inserting items at a sorted position with InsertAtPotentialIndex
178+
179+
The `InsertAtPotentialIndex` extension on `IList<T>` inserts an item at the position determined by a predicate, useful for maintaining sorted collections.
180+
181+
```csharp
182+
public void InsertSorted(IList<int> sortedList, int value)
183+
{
184+
sortedList.InsertAtPotentialIndex(value, (newItem, existingItem) => newItem > existingItem);
185+
}
186+
```
187+
188+
The companion `PotentialIndexOf` extension returns the index without inserting, if you need to determine the position first.
189+
190+
## Shuffling a collection with the Shuffle extension
191+
192+
The `Shuffle` extension randomly reorders the elements of an `IEnumerable<T>`.
193+
194+
```csharp
195+
var shuffled = myItems.Shuffle();
196+
```
197+
198+
## Sorting an ObservableCollection with Sort and SortDescending
199+
200+
`ObservableCollection<T>` objects don't have built-in sorting. The `Sort` and `SortDescending` extensions allow you to sort in place while correctly raising collection changed events.
201+
202+
```csharp
203+
myObservableCollection.Sort(item => item.Name);
204+
myObservableCollection.SortDescending(item => item.Date);
205+
```
206+
207+
## Checking if a collection is null or empty with IsNullOrEmpty
208+
209+
The `IsNullOrEmpty` extension on `IEnumerable<T>` provides a quick check for whether a collection is null or contains no items.
210+
211+
```csharp
212+
if (myItems.IsNullOrEmpty())
213+
{
214+
// No items to process
215+
}
216+
```
217+
218+
## Working with dictionaries using DictionaryExtensions
219+
220+
The `MADE.Collections.DictionaryExtensions` class provides extensions for `Dictionary<TKey, TValue>`.
221+
222+
### AddOrUpdate
223+
224+
Adds a value to the dictionary, or updates it if the key already exists.
225+
226+
```csharp
227+
var settings = new Dictionary<string, string>();
228+
settings.AddOrUpdate("Theme", "Dark");
229+
settings.AddOrUpdate("Theme", "Light"); // Updates existing key
230+
```
231+
232+
### GetValueOrDefault
233+
234+
Gets a value from a dictionary by key, or returns a default value if the key does not exist.
235+
236+
```csharp
237+
var theme = settings.GetValueOrDefault("Theme", "Light");
238+
```

docs/articles/features/data-converters.md

Lines changed: 57 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,26 @@ title: Using the Data Converters package
77

88
The Data Converters package provides a collection of value converters and extensions to manipulate data in your applications.
99

10-
## Converting a DateTime to a String using the DateTimeToStringValueConverter
10+
## Converting a bool to a String using the BooleanToStringValueConverter
1111

12-
Value converters are a common coding practice for building XAML applications that allow values to be bound to a view, converted to a different type and back depending on the binding mode.
12+
The `MADE.Data.Converters.BooleanToStringValueConverter` converts `bool` values to configurable `String` representations using the `TrueValue` and `FalseValue` properties.
1313

14-
Why should that be limited to just XAML applications though?
14+
```csharp
15+
var converter = new BooleanToStringValueConverter
16+
{
17+
TrueValue = "Yes",
18+
FalseValue = "No"
19+
};
1520

16-
The `MADE.Data.Converters.DateTimeToStringValueConverter` works across any .NET application, including your XAML bindings.
21+
string result = converter.Convert(true); // "Yes"
22+
bool original = converter.ConvertBack("No"); // false
23+
```
1724

18-
It converts a `DateTime` value to a `String` using a format parameter. The format parameter must be a valid `DateTime` string format [based on the Microsoft documentation](https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings).
25+
## Converting a DateTime to a String using the DateTimeToStringValueConverter
26+
27+
The `MADE.Data.Converters.DateTimeToStringValueConverter` converts a `DateTime` value to a `String` using a format parameter. The format parameter must be a valid `DateTime` string format [based on the Microsoft documentation](https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings).
1928

20-
Below is an example of this in use in any C# application.
29+
Below is an example of this in use.
2130

2231
```csharp
2332
namespace App.Conversions
@@ -41,67 +50,57 @@ namespace App.Conversions
4150
}
4251
```
4352

44-
You can also take advantage of this converter in your XAML applications too.
45-
46-
```xml
47-
<Page
48-
x:Class="App.Conversions.MainPage"
49-
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
50-
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
51-
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
52-
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
53-
xmlns:converters="using:MADE.Data.Converters"
54-
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
55-
mc:Ignorable="d">
56-
57-
<Page.Resources>
58-
<converters:DateTimeToStringValueConverter x:Key="DateTimeToStringValueConverter" />
59-
</Page.Resources>
60-
61-
<RelativePanel Padding="12">
62-
<TextBlock Text="{x:Bind ViewModel.Date, Converter={StaticResource DateTimeToStringValueConverter}, ConverterParameter='g'}" />
63-
</RelativePanel>
64-
</Page>
65-
```
66-
6753
## Creating your own custom value converters
6854

69-
If you want to take advantage of what goes into a value converter, you can build your own using the `MADE.Data.Converters.IValueConverter` interface which provides the signatures for the `Convert` and `ConvertBack` methods.
55+
If you want to take advantage of what goes into a value converter, you can build your own using the `MADE.Data.Converters.IValueConverter<TFrom, TTo>` interface which provides the signatures for the `Convert` and `ConvertBack` methods.
7056

7157
These can be used to convert any type to another. Whatever data conversion you think you may need, you'll be able to build out a value converter to satisfy that need for your project.
7258

73-
You can then build out your own, similar to our `DateTimeToStringValueConverter`.
59+
If there is a common value converter you think is missing from MADE.NET, [raise a tracking item on GitHub](https://github.com/MADE-Apps/MADE.NET/issues/new/choose) and we'll get it implemented.
7460

75-
```csharp
76-
namespace MADE.Data.Converters
77-
{
78-
using System;
79-
using System.Globalization;
61+
## DateTime extensions
8062

81-
public partial class DateTimeToStringValueConverter : IValueConverter<DateTime, string>
82-
{
83-
public string Convert(DateTime value, object parameter = default)
84-
{
85-
string format = parameter?.ToString();
86-
return !string.IsNullOrWhiteSpace(format)
87-
? value.ToString(format, CultureInfo.InvariantCulture)
88-
: value.ToString(CultureInfo.InvariantCulture);
89-
}
63+
The `MADE.Data.Converters.Extensions.DateTimeExtensions` class provides a comprehensive set of extensions for working with `DateTime` values:
9064

91-
public DateTime ConvertBack(string value, object parameter = default)
92-
{
93-
if (string.IsNullOrWhiteSpace(value))
94-
{
95-
return DateTime.MinValue;
96-
}
65+
- `ToCurrentAge()` - Calculates an age in years from a date to today.
66+
- `ToDaySuffix()` - Returns the day suffix (st, nd, rd, th) for a date.
67+
- `ToNearestHour()` - Rounds a date to the nearest hour.
68+
- `StartOfDay()` / `EndOfDay()` - Gets the start or end of the day.
69+
- `StartOfWeek()` / `EndOfWeek()` - Gets the start or end of the week.
70+
- `StartOfMonth()` / `EndOfMonth()` - Gets the start or end of the month.
71+
- `StartOfYear()` / `EndOfYear()` - Gets the start or end of the year.
72+
- `SetTime()` - Overrides the time part of a `DateTime` value (multiple overloads).
9773

98-
bool parsed = DateTime.TryParse(value, out DateTime dateTime);
99-
return parsed ? dateTime : DateTime.MinValue;
100-
}
101-
}
102-
}
74+
## String extensions
75+
76+
The `MADE.Data.Converters.Extensions.StringExtensions` class provides extensions for manipulating `String` values:
77+
78+
- `ToTitleCase()` - Converts a string to title case.
79+
- `ToDefaultCase()` - Converts a string to default (lower) case.
80+
- `Truncate()` - Truncates a string to a specified length.
81+
- `ToBase64()` / `FromBase64()` - Converts to and from Base64 encoding.
82+
- `ToMemoryStreamAsync()` - Converts a string to a `MemoryStream`.
83+
- `ToInt()` / `ToNullableInt()` - Parses a string to an integer.
84+
- `ToFloat()` / `ToNullableFloat()` - Parses a string to a float.
85+
- `ToDouble()` / `ToNullableDouble()` - Parses a string to a double.
86+
- `ToBoolean()` - Parses a string to a boolean.
87+
88+
## Boolean extensions
89+
90+
The `MADE.Data.Converters.Extensions.BooleanExtensions` class provides the `ToFormattedString` extension for formatting `bool` values to custom string representations.
91+
92+
```csharp
93+
bool isActive = true;
94+
string result = isActive.ToFormattedString("Active", "Inactive"); // "Active"
10395
```
10496

105-
If you want to build a XAML specific value converter, you can also apply the `Windows.UI.Xaml.Data.IValueConverter` to your class and implement the additional methods calling directly into your `Convert` and `ConvertBack` methods.
97+
## Math extensions
10698

107-
If there is a common value converter you think is missing from MADE.NET, [raise a tracking item on GitHub](https://github.com/MADE-Apps/MADE.NET/issues/new/choose) and we'll get it implemented.
99+
The `MADE.Data.Converters.Extensions.MathExtensions` class provides extensions for common mathematic expressions including `ToRadians` to convert a degrees value to radians.
100+
101+
## Length extensions
102+
103+
The `MADE.Data.Converters.Extensions.LengthExtensions` class provides extensions for converting length values:
104+
105+
- `ToMeters()` - Converts a value from miles to meters.
106+
- `ToMiles()` - Converts a value from meters to miles.

docs/articles/features/data-efcore.md

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
2-
uid: package-data-converters
3-
title: Using the Data Converters package
2+
uid: package-data-efcore
3+
title: Using the Data EF Core package
44
---
55

66
# Using the Data Entity Framework Core package
@@ -17,9 +17,9 @@ These are:
1717
- A date the entity was created
1818
- A date the entity was last updated
1919

20-
This is what the `MADE.Data.EFCore.EntityBase` type provides for you. It even goes as far as to initialize your created and last updated date values for you when you create your object.
20+
This is what the `MADE.Data.EFCore.EntityBase` type provides for you. It initializes your created and last updated date values when you create your object.
2121

22-
To use it for your own entities, it's as simple as inheriting from the `EntityBase` type.
22+
To use it for your own entities, inherit from the `EntityBase` type. By default, it uses a `Guid` identifier.
2323

2424
```csharp
2525
namespace MyApp.Data
@@ -36,3 +36,70 @@ namespace MyApp.Data
3636
}
3737
}
3838
```
39+
40+
### Using a custom key type with EntityBase
41+
42+
If you need a different identifier type, use the generic `EntityBase<TKey>`:
43+
44+
```csharp
45+
public class Product : EntityBase<int>
46+
{
47+
public string Name { get; set; }
48+
49+
public decimal Price { get; set; }
50+
}
51+
```
52+
53+
### Entity interfaces
54+
55+
The following interfaces are available for implementing custom entity types:
56+
57+
- `IDatedEntity` - Defines `CreatedDate` and `UpdatedDate` properties.
58+
- `IEntityBase<TKey>` - Extends `IDatedEntity` with a typed `Id` property.
59+
- `IEntityBase` - A convenience interface that uses `Guid` as the key type.
60+
61+
## Configuring entities with EntityBaseExtensions
62+
63+
The `MADE.Data.EFCore.Extensions.EntityBaseExtensions` class provides extensions for configuring entity types in your `DbContext` model builder.
64+
65+
```csharp
66+
protected override void OnModelCreating(ModelBuilder modelBuilder)
67+
{
68+
// Configures the entity key and UTC date properties for a Guid-based entity
69+
modelBuilder.Entity<User>().Configure();
70+
71+
// For entities with a custom key type
72+
modelBuilder.Entity<Product>().ConfigureWithKey<Product, int>();
73+
}
74+
```
75+
76+
The `ConfigureDateProperties` extension can be used independently to configure UTC date properties on any entity implementing `IDatedEntity`.
77+
78+
## Storing dates in UTC with UtcDateTimeConverter
79+
80+
The `MADE.Data.EFCore.Converters.UtcDateTimeConverter` helps ensure that entity model dates are stored and read in UTC format.
81+
82+
Use the `IsUtc()` annotation on date properties in your entity configuration, then apply the converter to the model builder:
83+
84+
```csharp
85+
protected override void OnModelCreating(ModelBuilder modelBuilder)
86+
{
87+
modelBuilder.ApplyUtcDateTimeConverter();
88+
}
89+
```
90+
91+
## DbContext extensions
92+
93+
The `MADE.Data.EFCore.Extensions.DbContextExtensions` class provides additional helpers:
94+
95+
- `UpdateAsync<T>` - Updates an entity and saves changes in a single call.
96+
- `RemoveWhere<T>` - Removes entities from a `DbSet` matching a predicate.
97+
- `SetEntityDates` - Automatically sets `CreatedDate` and `UpdatedDate` on tracked entities. Best called from an override of `SaveChangesAsync`.
98+
- `TrySaveChangesAsync` - Attempts to save changes to the database and handles concurrency exceptions.
99+
100+
## Query extensions
101+
102+
The `MADE.Data.EFCore.Extensions.QueryableExtensions` class provides helpers for querying:
103+
104+
- `Page<T>` - Applies skip and take pagination to a query based on page number and page size.
105+
- `OrderBy<T>` - Dynamically orders query results by a property name string, with optional descending sort.

0 commit comments

Comments
 (0)