![]() |
VOOZH | about |
dotnet add package I-Synergy.Framework.Core --version 2026.10618.11733
NuGet\Install-Package I-Synergy.Framework.Core -Version 2026.10618.11733
<PackageReference Include="I-Synergy.Framework.Core" Version="2026.10618.11733" />
<PackageVersion Include="I-Synergy.Framework.Core" Version="2026.10618.11733" />Directory.Packages.props
<PackageReference Include="I-Synergy.Framework.Core" />Project file
paket add I-Synergy.Framework.Core --version 2026.10618.11733
#r "nuget: I-Synergy.Framework.Core, 2026.10618.11733"
#:package I-Synergy.Framework.Core@2026.10618.11733
#addin nuget:?package=I-Synergy.Framework.Core&version=2026.10618.11733Install as a Cake Addin
#tool nuget:?package=I-Synergy.Framework.Core&version=2026.10618.11733Install as a Cake Tool
Foundational library providing core abstractions, base classes, services, and utilities for building enterprise-grade .NET 10.0 applications. This package forms the foundation of the I-Synergy Framework ecosystem.
Install the package via NuGet:
dotnet add package I-Synergy.Framework.Core
Create observable objects with automatic property change notifications and dirty tracking:
using ISynergy.Framework.Core.Base;
public class Person : ObservableClass
{
public string Name
{
get => GetValue<string>();
set => SetValue(value);
}
public int Age
{
get => GetValue<int>();
set => SetValue(value);
}
}
// Usage
var person = new Person();
person.PropertyChanged += (s, e) => Console.WriteLine($"{e.PropertyName} changed");
person.Name = "John Doe"; // Triggers PropertyChanged event
Console.WriteLine(person.IsDirty); // true - object has unsaved changes
Add validation support to your models:
using ISynergy.Framework.Core.Base;
using System.ComponentModel.DataAnnotations;
public class Customer : ObservableValidatedClass
{
[Required(ErrorMessage = "Email is required")]
[EmailAddress(ErrorMessage = "Invalid email format")]
public string Email
{
get => GetValue<string>();
set => SetValue(value);
}
[Range(18, 120, ErrorMessage = "Age must be between 18 and 120")]
public int Age
{
get => GetValue<int>();
set => SetValue(value);
}
}
// Usage
var customer = new Customer { Email = "invalid-email", Age = 15 };
if (!customer.IsValid)
{
foreach (var error in customer.GetErrors())
{
Console.WriteLine(error.ErrorMessage);
}
}
Implement loosely coupled communication between components:
using ISynergy.Framework.Core.Abstractions.Services;
using ISynergy.Framework.Core.Services;
// Define a message
public record UserLoggedInMessage(string Username, DateTime LoginTime);
// Register a recipient
public class DashboardViewModel
{
private readonly IMessengerService _messenger;
public DashboardViewModel(IMessengerService messenger)
{
_messenger = messenger;
_messenger.Register<UserLoggedInMessage>(this, OnUserLoggedIn);
}
private void OnUserLoggedIn(UserLoggedInMessage message)
{
Console.WriteLine($"User {message.Username} logged in at {message.LoginTime}");
}
}
// Send a message
public class LoginService
{
private readonly IMessengerService _messenger;
public LoginService(IMessengerService messenger)
{
_messenger = messenger;
}
public async Task LoginAsync(string username)
{
// Perform login logic
_messenger.Send(new UserLoggedInMessage(username, DateTime.UtcNow));
}
}
// Configure in DI
services.AddScoped<IMessengerService, MessengerService>();
Handle operations that may fail without throwing exceptions:
using ISynergy.Framework.Core.Models;
public class UserService
{
public Result<User> GetUserById(int id)
{
var user = Database.FindUser(id);
if (user is null)
return Result<User>.Fail("User not found");
return Result<User>.Success(user);
}
public Result UpdateUser(User user)
{
try
{
Database.Update(user);
return Result.Success();
}
catch (Exception ex)
{
return Result.Fail($"Update failed: {ex.Message}");
}
}
}
// Usage
var result = userService.GetUserById(123);
if (result.IsSuccess)
{
var user = result.Value;
Console.WriteLine($"Found user: {user.Name}");
}
else
{
Console.WriteLine($"Error: {result.ErrorMessage}");
}
Manage tenant and user context across application layers:
using ISynergy.Framework.Core.Abstractions;
using ISynergy.Framework.Core.Abstractions.Services;
using ISynergy.Framework.Core.Extensions;
// Define your context
public class AppContext : IContext
{
public Guid TenantId { get; set; }
public string Username { get; set; }
public List<string> Roles { get; set; }
}
// Configure in DI
services.AddScopedContext<AppContext>();
// Use in middleware or controllers
public class TenantMiddleware
{
private readonly RequestDelegate _next;
public TenantMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext, IScopedContextService contextService)
{
var tenantId = httpContext.Request.Headers["X-Tenant-ID"].FirstOrDefault();
if (Guid.TryParse(tenantId, out var parsedTenantId))
{
contextService.SetContext(new AppContext
{
TenantId = parsedTenantId,
Username = httpContext.User.Identity?.Name ?? "Anonymous"
});
}
await _next(httpContext);
}
}
// Access context in services
public class OrderService
{
private readonly IScopedContextService _contextService;
public OrderService(IScopedContextService contextService)
{
_contextService = contextService;
}
public async Task<List<Order>> GetOrdersAsync()
{
var context = _contextService.GetContext<AppContext>();
return await Database.Orders
.Where(o => o.TenantId == context.TenantId)
.ToListAsync();
}
}
ISynergy.Framework.Core.Base/
├── ObservableClass # INotifyPropertyChanged implementation with dirty tracking
├── ObservableValidatedClass # ObservableClass + DataAnnotations validation
├── ModelClass # Base for domain models with identity
└── Property<T> # Property wrapper with change tracking
ISynergy.Framework.Core.Services/
├── MessengerService # Weak reference-based messaging
├── ScopedContextService # Request-scoped context management
├── BusyService # UI busy state management
├── InfoService # Application info (version, name, etc.)
├── LanguageService # Localization support
└── RequestCancellationService # Centralized cancellation token management
The Core library includes 35+ extension method classes:
using ISynergy.Framework.Core.Abstractions.Services;
public class DataLoadViewModel
{
private readonly IBusyService _busyService;
private readonly IDataService _dataService;
public DataLoadViewModel(IBusyService busyService, IDataService dataService)
{
_busyService = busyService;
_dataService = dataService;
}
public async Task LoadDataAsync()
{
try
{
_busyService.StartBusy("Loading data...");
var data = await _dataService.GetDataAsync();
_busyService.UpdateMessage("Processing data...");
ProcessData(data);
}
finally
{
_busyService.StopBusy();
}
}
}
// Bind to UI
<ProgressRing IsActive="{Binding BusyService.IsBusy}" />
<TextBlock Text="{Binding BusyService.BusyMessage}" />
using ISynergy.Framework.Core.Extensions;
// String extensions
string email = " john.doe@example.com ";
bool isValid = email.IsValidEmail(); // true
string clean = email.Trim().ToLower();
// DateTime extensions
var date = DateTime.Now;
var startOfWeek = date.StartOfWeek();
var endOfMonth = date.EndOfMonth();
bool isWeekend = date.IsWeekend();
// Collection extensions
var list = new List<int> { 1, 2, 3, 4, 5 };
list.RemoveWhere(x => x % 2 == 0); // Removes even numbers
var chunks = list.Chunk(2); // Split into chunks of 2
// Enum extensions
public enum OrderStatus
{
[Description("Pending approval")]
Pending,
[Description("Approved and processing")]
Approved,
Completed
}
var statuses = EnumExtensions.ToList<OrderStatus>();
string description = OrderStatus.Pending.GetDescription(); // "Pending approval"
// Object extensions
var person = new Person { Name = "John", Age = 30 };
string json = person.ToJson();
var clone = person.DeepClone();
using ISynergy.Framework.Core.Collections;
// ObservableCollection with item property change tracking
var products = new ObservableCollection<Product>();
products.CollectionChanged += (s, e) => Console.WriteLine("Collection changed");
products.ItemPropertyChanged += (s, e) =>
Console.WriteLine($"Item property {e.PropertyName} changed");
var product = new Product { Name = "Widget", Price = 9.99m };
products.Add(product);
product.Price = 12.99m; // Triggers ItemPropertyChanged
// Binary Tree
var tree = new BinaryTree<int>();
tree.Add(5);
tree.Add(3);
tree.Add(7);
tree.Add(1);
tree.Add(9);
bool contains = tree.Contains(7); // true
tree.InOrderTraversal(value => Console.WriteLine(value)); // 1, 3, 5, 7, 9
using ISynergy.Framework.Core.Extensions;
using ISynergy.Framework.Core.Abstractions.Services;
using ISynergy.Framework.Core.Services;
public void ConfigureServices(IServiceCollection services)
{
// Core services
services.AddSingleton<IMessengerService, MessengerService>();
services.AddSingleton<IBusyService, BusyService>();
services.AddSingleton<IInfoService, InfoService>();
services.AddSingleton<ILanguageService, LanguageService>();
// Context management
services.AddScopedContext<AppContext>();
// Or use lifetime attributes
services.Scan(scan => scan
.FromAssemblyOf<Startup>()
.AddClasses()
.UsingRegistrationStrategy(RegistrationStrategy.Skip)
.UsingAttributes());
}
using ISynergy.Framework.Core.Attributes;
[Lifetime(Lifetimes.Transient)]
public class TransientService : ITransientService
{
// Service implementation
}
[Lifetime(Lifetimes.Scoped)]
public class ScopedService : IScopedService
{
// Service implementation
}
[Lifetime(Lifetimes.Singleton)]
public class SingletonService : ISingletonService
{
// Service implementation
}
using ISynergy.Framework.Core.Base;
using ISynergy.Framework.Core.Validation;
public class Order : ObservableValidatedClass
{
public decimal Amount { get; set; }
public string CustomerEmail { get; set; }
protected override IEnumerable<ValidationResult> Validate()
{
// Custom validation logic
if (Amount < 0)
yield return new ValidationResult(
"Amount cannot be negative",
new[] { nameof(Amount) });
if (Amount > 10000 && string.IsNullOrEmpty(CustomerEmail))
yield return new ValidationResult(
"Email required for orders over $10,000",
new[] { nameof(CustomerEmail) });
}
}
using ISynergy.Framework.Core.Extensions;
public class NotificationService
{
public void SendNotification(string message)
{
// Fire and forget without blocking
SendEmailAsync(message).SafeFireAndForget(
onException: ex => Console.WriteLine($"Error: {ex.Message}"));
}
private async Task SendEmailAsync(string message)
{
await Task.Delay(1000);
// Send email logic
}
}
using ISynergy.Framework.Core.Extensions;
using Microsoft.Extensions.ObjectPool;
public class BufferPool
{
private readonly ObjectPool<byte[]> _pool;
public BufferPool()
{
var policy = new DefaultPooledObjectPolicy<byte[]>();
_pool = new DefaultObjectPool<byte[]>(policy);
}
public async Task ProcessDataAsync(Stream stream)
{
var buffer = _pool.Get();
try
{
await stream.ReadAsync(buffer, 0, buffer.Length);
// Process buffer
}
finally
{
_pool.Return(buffer);
}
}
}
Use ObservableClass as the base for all ViewModels and models that need property change notifications.
Always call Dispose() or use using statements with ObservableClass instances to prevent memory leaks from event handlers.
The MessengerService uses weak references by default. Set keepTargetAlive: true only when using closures in message handlers.
GetValue<T>() and SetValue() for properties that need change trackingMarkAsClean() after saving changes to reset dirty trackingRevert() to restore original values before committingMessengerService.Default singletonResult<T> for operations that may failResult.Success() and Result.Fail() factory methodsIsSuccess before accessing ValueThe Core library is designed for testability:
[Fact]
public void ObservableClass_PropertyChange_RaisesEvent()
{
// Arrange
var person = new Person();
var eventRaised = false;
person.PropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(Person.Name))
eventRaised = true;
};
// Act
person.Name = "John";
// Assert
Assert.True(eventRaised);
Assert.True(person.IsDirty);
}
[Fact]
public void Messenger_SendMessage_DeliversToRecipient()
{
// Arrange
var messenger = new MessengerService();
var received = false;
var recipient = new object();
messenger.Register<string>(recipient, msg => received = true);
// Act
messenger.Send("Test message");
// Assert
Assert.True(received);
}
For more information about the I-Synergy Framework:
For issues, questions, or contributions, please visit the GitHub repository.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
Showing the top 5 NuGet packages that depend on I-Synergy.Framework.Core:
| Package | Downloads |
|---|---|
|
I-Synergy.Framework.AspNetCore
I-Synergy Framework AspNetCore |
|
|
I-Synergy.Framework.Mvvm
I-Synergy Framework Mvvm |
|
|
I-Synergy.Framework.MessageBus
I-Synergy Framework MessageBus |
|
|
I-Synergy.Framework.Storage
I-Synergy Framework Storage |
|
|
I-Synergy.Framework.Geography
I-Synergy Framework Geography |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2026.10618.11733 | 0 | 6/18/2026 |
| 2026.10618.11702-preview | 0 | 6/18/2026 |
| 2026.10616.12121 | 231 | 6/16/2026 |
| 2026.10616.11904-preview | 227 | 6/16/2026 |
| 2026.10616.10010 | 338 | 6/15/2026 |
| 2026.10615.12240-preview | 327 | 6/15/2026 |
| 2026.10615.10047-preview | 385 | 6/14/2026 |
| 2026.10614.10112-preview | 437 | 6/13/2026 |
| 2026.10612.12341-preview | 456 | 6/12/2026 |
| 2026.10612.12110-preview | 455 | 6/12/2026 |
| 2026.10612.11941-preview | 462 | 6/12/2026 |
| 2026.10610.10831 | 533 | 6/10/2026 |
| 2026.10610.10706-preview-pr... | 523 | 6/10/2026 |
| 2026.10609.11323-preview | 530 | 6/9/2026 |
| 2026.10607.11905-preview | 535 | 6/7/2026 |
| 2026.10607.11454-preview | 528 | 6/7/2026 |
| 2026.10606.11854-preview | 561 | 6/6/2026 |
| 2026.10603.11238-preview | 529 | 6/3/2026 |
| 2026.10602.12203-preview | 520 | 6/2/2026 |
| 2026.10602.11949-preview | 510 | 6/2/2026 |