Mesch.RealTree
0.0.1
There is a newer version of this package available.
See the version list below for details.
See the version list below for details.
dotnet add package Mesch.RealTree --version 0.0.1
NuGet\Install-Package Mesch.RealTree -Version 0.0.1
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="Mesch.RealTree" Version="0.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Mesch.RealTree" Version="0.0.1" />
<PackageReference Include="Mesch.RealTree" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Mesch.RealTree --version 0.0.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Mesch.RealTree, 0.0.1"
#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.
#:package Mesch.RealTree@0.0.1
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Mesch.RealTree&version=0.0.1
#tool nuget:?package=Mesch.RealTree&version=0.0.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Mesch.RealTree
A tree hierarchy management abstraction with plugin architecture and eventing.
Overview
RealTree provides a flexible tree implementation where:
- Containers can hold both other containers and items
- Items can hold containers but not other items
- Operations support middleware-style actions and fire-and-forget events
- Validation prevents cyclic references automatically
Core Concepts
Node Types
IRealTreeNode // Base interface for all nodes
├── IRealTreeContainer // Can contain containers and items
├── IRealTreeItem // Can contain containers only
└── IRealTree // Root node (extends container)
Operations Service
All tree modifications go through IRealTreeOperations which provides:
- Middleware-style action pipelines (can intercept/modify operations)
- Event notifications (fire-and-forget, executed after operations)
- Bulk operations for performance
- Copy operations with recursive traversal
Quick Start
// Create tree
var factory = new RealTreeFactory();
var tree = factory.CreateTree(name: "MyTree");
var operations = new RealTreeOperations(factory);
// Add nodes
var container = await operations.AddContainerAsync(tree, null, "Documents");
var item = await operations.AddItemAsync(container, null, "Report.pdf");
// Navigate
var found = tree.FindByPath("/Documents/Report.pdf");
Console.WriteLine(found?.Name); // "Report.pdf"
Middleware Actions
Actions execute before the operation and can intercept, modify, or cancel it:
container.RegisterAddContainerAction(async (context, next) =>
{
// Pre-operation logic
Console.WriteLine($"Adding {context.Container.Name} to {context.Parent.Name}");
// Validate
if (context.Container.Name.StartsWith("temp"))
throw new InvalidOperationException("Temp folders not allowed");
// Continue pipeline
await next();
// Post-operation logic
Console.WriteLine("Container added successfully");
});
Event Handling
Events fire after operations complete and run in parallel:
container.RegisterContainerAddedEvent(async context =>
{
// Log to database
await LogActivity($"Container {context.Container.Name} added");
});
container.RegisterContainerAddedEvent(async context =>
{
// Send notification (runs in parallel with logging)
await NotifyUsers($"New folder: {context.Container.Name}");
});
Bulk Operations
Efficient operations for multiple nodes:
var containers = new List<IRealTreeContainer>
{
factory.CreateContainer(name: "Folder1"),
factory.CreateContainer(name: "Folder2"),
factory.CreateContainer(name: "Folder3")
};
await operations.BulkAddContainersAsync(tree, containers);
Common Patterns
Hierarchical Permissions
// Register at tree level - applies to all operations
tree.RegisterAddContainerAction(async (context, next) =>
{
var user = GetCurrentUser();
var parent = context.Parent;
if (!HasPermission(user, parent, "create"))
throw new UnauthorizedAccessException();
await next();
});
Audit Logging
tree.RegisterNodeUpdatedEvent(async context =>
{
await auditLogger.LogAsync(new AuditEntry
{
UserId = GetCurrentUser().Id,
Action = "Update",
NodeId = context.Node.Id,
OldName = context.OldName,
NewName = context.NewName,
Timestamp = context.OperationTime
});
});
Validation with Context
container.RegisterAddItemAction(async (context, next) =>
{
var parent = context.Parent;
var item = context.Item;
// Business rule: max 10 items per container
if (parent.Items.Count >= 10)
throw new InvalidOperationException("Container full");
// Check for duplicates
if (parent.Items.Any(i => i.Name == item.Name))
throw new DuplicateNameException(item.Name);
await next();
});
Advanced Usage
Custom Node Types
public class FileContainer : RealTreeContainer
{
public string ContentType { get; set; }
public long MaxSize { get; set; }
public FileContainer(string contentType, long maxSize)
: base(name: contentType)
{
ContentType = contentType;
MaxSize = maxSize;
}
}
Operation Context Access
tree.RegisterMoveAction(async (context, next) =>
{
var node = context.Node;
var oldPath = node.Path;
await next(); // Perform the move
var newPath = node.Path;
await UpdateReferences(oldPath, newPath);
});
Delegate Management
// Store reference for later removal
AddContainerDelegate validator = async (context, next) => { /* validation */ };
container.RegisterAddContainerAction(validator);
// Remove when no longer needed
container.UnregisterAddContainerAction(validator);
Exception Handling
// Actions can throw exceptions to cancel operations
container.RegisterAddContainerAction(async (context, next) =>
{
if (SomeValidationFails())
throw new TreeValidationException("Operation not allowed");
await next();
});
// Events log exceptions but don't propagate them
container.RegisterContainerAddedEvent(async context =>
{
try
{
await SomeExternalService.NotifyAsync(context);
}
catch (Exception ex)
{
// Exception logged automatically, operation continues
}
});
Thread Safety
- Tree structure modifications are not thread-safe by design
- Use external synchronization if needed
- Events execute in parallel but individual event handlers should be thread-safe
ReaderWriterLockSlimis available onRealTreeRoot.Lockfor custom locking
Dependency Injection
services.AddSingleton<IRealTreeFactory, RealTreeFactory>();
services.AddScoped<IRealTreeOperations, RealTreeOperations>();
// With logging
services.AddScoped<IRealTreeOperations>(provider =>
{
var factory = provider.GetService<IRealTreeFactory>();
var logger = provider.GetService<ILogger<RealTreeOperations>>();
return new RealTreeOperations(factory, logger);
});
Performance Considerations
- Use bulk operations for multiple related changes
- Event handlers execute in parallel but should be lightweight
- Consider unregistering delegates when no longer needed
- Path lookups are O(depth), ID lookups are O(n)
- Metadata dictionaries are not optimized for large datasets
Error Types
TreeValidationException // Base validation error
├── DuplicateNameException // Duplicate sibling names
├── CyclicReferenceException // Would create cycle
└── InvalidContainmentException // Invalid parent-child relationship
| 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. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net8.0
- Microsoft.Extensions.Logging (>= 9.0.8)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.