Nabs.Launchpad.Core.Dtos
10.0.214
Prefix Reserved
dotnet add package Nabs.Launchpad.Core.Dtos --version 10.0.214
NuGet\Install-Package Nabs.Launchpad.Core.Dtos -Version 10.0.214
<PackageReference Include="Nabs.Launchpad.Core.Dtos" Version="10.0.214" />
<PackageVersion Include="Nabs.Launchpad.Core.Dtos" Version="10.0.214" />
<PackageReference Include="Nabs.Launchpad.Core.Dtos" />
paket add Nabs.Launchpad.Core.Dtos --version 10.0.214
#r "nuget: Nabs.Launchpad.Core.Dtos, 10.0.214"
#:package Nabs.Launchpad.Core.Dtos@10.0.214
#addin nuget:?package=Nabs.Launchpad.Core.Dtos&version=10.0.214
#tool nuget:?package=Nabs.Launchpad.Core.Dtos&version=10.0.214
Nabs Launchpad Core DTOs Library
The Nabs Launchpad Core DTOs library provides foundational Data Transfer Object (DTO) interfaces and transitive dependency references for building consistent data models across the application. This library serves as a base package that other projects can reference to access common MVVM, validation, and localization capabilities.
Key Features
- Standardized List Item Interface: Common interface for list/dropdown items across the application
- MVVM Support: Includes CommunityToolkit.Mvvm for observable objects, properties, and commands
- Validation Framework: FluentValidation integration for declarative validation rules
- Localization Ready: Microsoft.Extensions.Localization support for multi-language applications
- Lightweight Foundation: Minimal overhead with maximum flexibility
Core Components
IListItem
The foundational interface for list items used in dropdowns, selection lists, and other UI components requiring ID/display value pairs.
Usage Examples
Implementing IListItem
// Simple list item implementation
public class CategoryListItem : IListItem
{
public string Id { get; init; } = default!;
public string DisplayValue { get; init; } = default!;
public string? SubText { get; set; }
}
// Creating list items
var categories = new[]
{
new CategoryListItem
{
Id = "1",
DisplayValue = "Electronics",
SubText = "Computers, phones, and accessories"
},
new CategoryListItem
{
Id = "2",
DisplayValue = "Clothing",
SubText = "Apparel and fashion items"
},
new CategoryListItem
{
Id = "3",
DisplayValue = "Books",
SubText = "Physical and digital books"
}
};
Using with Dropdowns and ComboBoxes
// In Blazor component
@using Nabs.Launchpad.Core.Dtos
<SfComboBox TValue="string"
TItem="CategoryListItem"
DataSource="@categories"
@bind-Value="@selectedCategoryId">
<ComboBoxFieldSettings Value="Id" Text="DisplayValue"></ComboBoxFieldSettings>
</SfComboBox>
@code {
private string? selectedCategoryId;
private List<CategoryListItem> categories = new();
protected override void OnInitialized()
{
categories = GetCategories();
}
}
Using CommunityToolkit.Mvvm (Transitive Dependency)
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
// Observable DTO with validation
public partial class UserDto : ObservableObject
{
[ObservableProperty]
private string _firstName = string.Empty;
[ObservableProperty]
private string _lastName = string.Empty;
[ObservableProperty]
private string _email = string.Empty;
// Computed property
public string FullName => $"{FirstName} {LastName}";
// Command
[RelayCommand]
private async Task SaveAsync()
{
// Save logic
await Task.CompletedTask;
}
}
Using FluentValidation (Transitive Dependency)
using FluentValidation;
using Microsoft.Extensions.Localization;
// Validator with localization support
public class UserDtoValidator : AbstractValidator<UserDto>
{
public UserDtoValidator(IStringLocalizer<UserDtoValidator> localizer)
{
RuleFor(x => x.FirstName)
.NotEmpty()
.WithMessage(localizer["FirstNameRequired"])
.MaximumLength(50)
.WithMessage(localizer["FirstNameTooLong"]);
RuleFor(x => x.LastName)
.NotEmpty()
.WithMessage(localizer["LastNameRequired"])
.MaximumLength(50)
.WithMessage(localizer["LastNameTooLong"]);
RuleFor(x => x.Email)
.NotEmpty()
.WithMessage(localizer["EmailRequired"])
.EmailAddress()
.WithMessage(localizer["EmailInvalid"]);
}
}
Using Localization (Transitive Dependency)
using Microsoft.Extensions.Localization;
public class ProductDto : IListItem
{
private readonly IStringLocalizer<ProductDto> _localizer;
public ProductDto(IStringLocalizer<ProductDto> localizer)
{
_localizer = localizer;
}
public string Id { get; init; } = default!;
public string DisplayValue { get; init; } = default!;
public string? SubText { get; set; }
public string GetLocalizedCategory(string categoryKey)
{
return _localizer[categoryKey];
}
}
// Resource file: ProductDto.resx
// Key: Electronics, Value: Electronics
//
// Resource file: ProductDto.es.resx (Spanish)
// Key: Electronics, Value: Electr�nicos
Converting Domain Models to List Items
// Domain model
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Category { get; set; } = string.Empty;
public decimal Price { get; set; }
}
// Extension method for conversion
public static class ProductExtensions
{
public static ProductListItem ToListItem(this Product product)
{
return new ProductListItem
{
Id = product.Id.ToString(),
DisplayValue = product.Name,
SubText = $"{product.Category} - ${product.Price:F2}"
};
}
}
// Usage
var products = await productService.GetAllAsync();
var productListItems = products.Select(p => p.ToListItem()).ToList();
API Reference
IListItem
Interface for standardized list items used in UI components.
Properties
Id
public string Id { get; init; }
Unique identifier for the list item. Typically a GUID, database ID, or other unique value.
DisplayValue
public string DisplayValue { get; init; }
The text displayed to the user in lists, dropdowns, and other UI components.
SubText
public string? SubText { get; set; }
Optional secondary text for additional context or description.
Included Transitive Dependencies
This library includes the following packages as transitive dependencies, making them available to consuming projects:
CommunityToolkit.Mvvm
Provides MVVM infrastructure including:
ObservableObject: Base class for objects that notify property changes[ObservableProperty]: Source generator for automatic property change notification[RelayCommand]: Source generator for ICommand implementationsINotifyPropertyChangedandINotifyPropertyChangingimplementations- Messenger for loosely-coupled communication
Documentation: https://learn.microsoft.com/dotnet/communitytoolkit/mvvm/
FluentValidation
Declarative validation framework providing:
- Rule-based validation with fluent interface
- Built-in validators (email, length, range, etc.)
- Custom validator support
- Async validation support
- Integration with dependency injection
Documentation: https://docs.fluentvalidation.net/
Microsoft.Extensions.Localization
Localization support providing:
IStringLocalizer<T>for type-specific resource access- Resource file (.resx) support
- Culture-aware string resolution
- Parameterized localization strings
Documentation: https://learn.microsoft.com/aspnet/core/fundamentals/localization
Best Practices
IListItem Implementation
- Use Immutable Initialization: Use
initfor Id and DisplayValue to prevent modification - Meaningful Display Values: Ensure DisplayValue is user-friendly and localized if needed
- SubText for Context: Use SubText to provide additional information without cluttering the main display
- Consistent IDs: Use consistent ID formats (GUIDs, integers as strings, etc.) across the application
MVVM Patterns
- Use ObservableObject: Inherit from
ObservableObjectfor automatic change notification - Use Source Generators: Prefer
[ObservableProperty]and[RelayCommand]attributes over manual implementations - Separate Concerns: Keep DTOs focused on data, move business logic to services
- Two-Way Binding: Leverage observable properties for efficient two-way data binding in Blazor
Validation
- Localize All Messages: Always use
IStringLocalizerfor validation messages - Register Validators: Register validators in dependency injection for automatic discovery
- Validate Early: Validate DTOs before sending to services or APIs
- Reuse Validators: Create reusable validator classes for common validation patterns
Localization
- Use Resource Files: Store all user-facing strings in .resx files
- Namespace Resources: Use type-specific localizers (
IStringLocalizer<T>) - Parameterized Strings: Use parameterized localization for dynamic content
- Culture Testing: Test with multiple cultures during development
Localization Example Structure
MyProject/
Resources/
UserDto.resx (default/English)
UserDto.es.resx (Spanish)
UserDto.fr.resx (French)
ValidationMessages.resx (default/English)
ValidationMessages.es.resx (Spanish)
Resource file content (UserDto.resx):
<data name="FirstNameRequired" xml:space="preserve">
<value>First name is required</value>
</data>
<data name="FirstNameTooLong" xml:space="preserve">
<value>First name must be 50 characters or less</value>
</data>
Spanish resource file (UserDto.es.resx):
<data name="FirstNameRequired" xml:space="preserve">
<value>El nombre es obligatorio</value>
</data>
<data name="FirstNameTooLong" xml:space="preserve">
<value>El nombre debe tener 50 caracteres o menos</value>
</data>
Testing
Testing IListItem Implementations
[Fact]
public void ListItem_Properties_ShouldBeSetCorrectly()
{
// Arrange
var id = Guid.NewGuid().ToString();
var displayValue = "Test Item";
var subText = "Additional context";
// Act
var item = new TestListItem
{
Id = id,
DisplayValue = displayValue,
SubText = subText
};
// Assert
item.Id.Should().Be(id);
item.DisplayValue.Should().Be(displayValue);
item.SubText.Should().Be(subText);
}
Testing with FluentValidation
[Fact]
public async Task Validator_InvalidEmail_ShouldFail()
{
// Arrange
var dto = new UserDto
{
FirstName = "John",
LastName = "Doe",
Email = "invalid-email"
};
var validator = new UserDtoValidator(mockLocalizer);
// Act
var result = await validator.ValidateAsync(dto);
// Assert
result.IsValid.Should().BeFalse();
result.Errors.Should().Contain(e => e.PropertyName == nameof(UserDto.Email));
}
Architecture and Design
DTO as Foundation
This library serves as a foundational package that:
- Defines common interfaces (like
IListItem) - Provides transitive dependencies for MVVM, validation, and localization
- Enables consistent patterns across all DTO implementations in the solution
Separation of Concerns
- DTOs: Data structures for transferring data between layers
- Validators: Separate classes for validation logic
- View Models: Use
ObservableObjectfor UI binding - Resources: Separate resource files for localization
Dependencies
- FluentValidation: For declarative validation rules and validators
- CommunityToolkit.Mvvm: For MVVM infrastructure including ObservableObject and commands
- Microsoft.Extensions.Localization: For localization and resource management
Note: These dependencies are transitive, meaning any project that references this library automatically has access to these packages.
Target Framework
- .NET 10
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- CommunityToolkit.Mvvm (>= 8.4.0)
- FluentValidation (>= 12.1.1)
- Microsoft.Extensions.Localization (>= 10.0.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Nabs.Launchpad.Core.Dtos:
| Package | Downloads |
|---|---|
|
Nabs.Launchpad.Core.ViewModels
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 10.0.214 | 32 | 1/1/2026 | |
| 10.0.213 | 71 | 1/1/2026 | |
| 10.0.212 | 41 | 1/1/2026 | |
| 10.0.211 | 60 | 12/31/2025 | |
| 10.0.210 | 84 | 12/30/2025 | |
| 10.0.209 | 101 | 12/30/2025 | |
| 10.0.208 | 97 | 12/30/2025 | |
| 10.0.207 | 105 | 12/29/2025 | |
| 10.0.206 | 110 | 12/29/2025 | |
| 10.0.205 | 194 | 12/24/2025 | |
| 10.0.204 | 190 | 12/21/2025 | |
| 10.0.203 | 286 | 12/18/2025 | |
| 10.0.202 | 286 | 12/17/2025 | |
| 10.0.200 | 296 | 12/17/2025 | |
| 10.0.199 | 450 | 12/10/2025 | |
| 10.0.197 | 183 | 12/5/2025 | |
| 10.0.196 | 688 | 12/3/2025 | |
| 10.0.195 | 691 | 12/3/2025 | |
| 10.0.194 | 693 | 12/3/2025 | |
| 10.0.193 | 695 | 12/2/2025 | |
| 10.0.192 | 190 | 11/28/2025 | |
| 10.0.190 | 198 | 11/27/2025 | |
| 10.0.189 | 185 | 11/23/2025 | |
| 10.0.187 | 181 | 11/23/2025 | |
| 10.0.186 | 162 | 11/23/2025 | |
| 10.0.184 | 424 | 11/20/2025 | |
| 10.0.181-rc3 | 306 | 11/11/2025 | |
| 10.0.180 | 306 | 11/11/2025 | |
| 10.0.179-rc2 | 256 | 11/11/2025 | |
| 10.0.178-rc2 | 210 | 11/10/2025 | |
| 10.0.177-rc2 | 203 | 11/10/2025 | |
| 10.0.176-rc2 | 167 | 11/6/2025 | |
| 10.0.175-rc2 | 168 | 11/6/2025 | |
| 10.0.174-rc2 | 184 | 11/5/2025 | |
| 10.0.172-rc2 | 179 | 11/2/2025 | |
| 10.0.170-rc2 | 171 | 11/1/2025 | |
| 10.0.169-rc2 | 170 | 11/1/2025 | |
| 10.0.168-rc2 | 173 | 10/31/2025 | |
| 10.0.166-rc2 | 176 | 10/31/2025 | |
| 10.0.164-rc2 | 237 | 10/28/2025 | |
| 10.0.162-rc2 | 226 | 10/24/2025 | |
| 9.0.151 | 222 | 10/17/2025 | |
| 9.0.150 | 295 | 9/10/2025 | |
| 9.0.146 | 232 | 8/15/2025 | |
| 9.0.145 | 286 | 8/11/2025 | |
| 9.0.144 | 303 | 8/8/2025 | |
| 9.0.137 | 239 | 7/29/2025 | |
| 9.0.136 | 252 | 7/29/2025 | |
| 9.0.135 | 259 | 7/28/2025 | |
| 9.0.134 | 300 | 7/9/2025 | |
| 9.0.133 | 299 | 7/9/2025 | |
| 9.0.132 | 306 | 7/9/2025 | |
| 9.0.131 | 305 | 7/9/2025 | |
| 9.0.130 | 293 | 7/7/2025 |