Franz.Common.Aras 2.3.0

dotnet add package Franz.Common.Aras --version 2.3.0
                    
NuGet\Install-Package Franz.Common.Aras -Version 2.3.0
                    
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="Franz.Common.Aras" Version="2.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Franz.Common.Aras" Version="2.3.0" />
                    
Directory.Packages.props
<PackageReference Include="Franz.Common.Aras" />
                    
Project file
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 Franz.Common.Aras --version 2.3.0
                    
#r "nuget: Franz.Common.Aras, 2.3.0"
                    
#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 Franz.Common.Aras@2.3.0
                    
#: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=Franz.Common.Aras&version=2.3.0
                    
Install as a Cake Addin
#tool nuget:?package=Franz.Common.Aras&version=2.3.0
                    
Install as a Cake Tool
# Franz.Common.Aras � v1.5.0 ??

**Franz.Common.Aras** integrates **ARAS Innovator** into the **Franz Framework** with clean, DDD-driven abstractions.  
It lets you treat ARAS as just another persistence provider � with **Entities**, **Aggregates**, **Unit of Work**, **Snapshots**, **Diagnostics**, and an **InMemory provider for testing**.

---

## ?? What�s New in v1.5.0

- ? **Concrete ARAS Innovator provider** (REST API)  
- ? **Fluent mapping layer** (field ? property, ignores, conversions)  
- ? **Unit of Work** (commit entities + aggregates atomically)  
- ? **Snapshotting** (optimize large aggregates, replay only post-snapshot events)  
- ? **Diagnostics decorators** (logging + OpenTelemetry tracing)  
- ? **InMemory provider** (unit testing without ARAS)  
- ? **AddArasInnovator bootstrapper** (EF-style DI registration)  
- ? **Full samples** for Entities, Aggregates, UoW, Testing, and Snapshots  

Current Version: v2.3.0

?? Installation

dotnet add package Franz.Common.Aras

If you�re in a class library (not ASP.NET Core), also add:

dotnet add package Microsoft.Extensions.Http

?? Setup

Register ARAS Innovator with dependency injection:

using Franz.Common.Aras.Innovator;
using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();

services.AddArasInnovator(options =>
{
    options.BaseUrl = "https://aras.server/InnovatorServer";
    options.Database = "InnovatorSolutions";
    options.UserName = "admin";
    options.Password = "innovator";

    // Optional:
    options.UseDiagnostics = true;
    options.SnapshotFrequency = 50; // every 50 events
});

?? Entities (CRUD)

Entities are simple Entity<Guid> models.

public class PartEntity : Entity<Guid>
{
    public string PartNumber { get; set; } = default!;
    public string Description { get; set; } = default!;
}

Define a repository:

public class PartRepository : ArasEntityRepository<PartEntity>
{
    public PartRepository(IArasEntityContext context) : base(context) { }
}

Usage sample:

var repo = provider.GetRequiredService<PartRepository>();

// Create
var part = new PartEntity { PartNumber = "PN-1000", Description = "Widget" };
await repo.AddAsync(part);

// Read
var fetched = await repo.GetByIdAsync(part.Id);
Console.WriteLine($"Fetched {fetched.PartNumber} - {fetched.Description}");

// Update
fetched.Description = "Updated Widget";
await repo.UpdateAsync(fetched);

// Delete
await repo.DeleteAsync(fetched.Id);

?? Aggregates (DDD + Events)

Aggregates inherit from AggregateRoot<TEvent> and model behavior with domain events.

public record PartCreated(Guid PartId, string PartNumber) : BaseDomainEvent;

public class PartAggregate : AggregateRoot<PartCreated>
{
    public string PartNumber { get; private set; } = default!;

    public void Create(string number)
    {
        ApplyChange(new PartCreated(Id, number));
    }

    protected override void When(PartCreated e)
    {
        Id = e.PartId;
        PartNumber = e.PartNumber;
    }
}

Usage sample:

var aggregates = provider.GetRequiredService<IArasAggregateContext>();

var partAgg = new PartAggregate();
partAgg.Create("PN-2000");

await aggregates.SaveAggregateAsync(partAgg);

// Load again (replay events or snapshot)
var loaded = await aggregates.GetAggregateAsync<PartAggregate, PartCreated>(partAgg.Id);

Console.WriteLine($"Loaded aggregate with PartNumber = {loaded.PartNumber}");

?? Unit of Work

Commit entities + aggregates in one go:

using var uow = provider.GetRequiredService<IArasUnitOfWork>();

// Entities
uow.Entities.Add(new PartEntity { PartNumber = "PN-3000", Description = "Bolt" });

// Aggregates
var partAgg = new PartAggregate();
partAgg.Create("PN-4000");
uow.Aggregates.TrackAggregate(partAgg);

// Commit atomically
await uow.CommitAsync();
Console.WriteLine("UoW committed successfully");

Rollback clears tracked changes:

await uow.RollbackAsync();
Console.WriteLine("UoW rolled back");

?? InMemory Provider (Testing)

Use the in-memory contexts without ARAS server:

services.AddInMemoryAras();

var context = provider.GetRequiredService<IArasEntityContext>();

await context.SaveEntityAsync(new PartEntity { PartNumber = "TEST-1" });

var parts = await context.QueryEntitiesAsync<PartEntity>("all");

foreach (var part in parts)
    Console.WriteLine($"InMemory part: {part.PartNumber}");

Aggregate testing:

var aggregates = provider.GetRequiredService<IArasAggregateContext>();

var agg = new PartAggregate();
agg.Create("TEST-AGG");
await aggregates.SaveAggregateAsync(agg);

var reloaded = await aggregates.GetAggregateAsync<PartAggregate, PartCreated>(agg.Id);
Console.WriteLine($"Reloaded aggregate: {reloaded.PartNumber}");

?? Snapshots (Performance)

Aggregates are snapshotted automatically every N events (default 50):

var agg = await aggregates.GetAggregateAsync<PartAggregate, PartCreated>(id);
// Replays only events after last snapshot

You can configure snapshot frequency in ArasInnovatorOptions:

options.SnapshotFrequency = 25;

?? Diagnostics

Enable structured logging + tracing with decorators:

services.AddLogging(b => b.AddConsole());
services.AddOpenTelemetryTracing();

services.Decorate<IArasEntityContext, DiagnosticEntityContextDecorator>();
services.Decorate<IArasAggregateContext, DiagnosticAggregateContextDecorator>();

You�ll get logs for:

  • Entity queries, saves, deletes
  • Aggregate tracking, saving, committing
  • Event publishing
  • Snapshot operations

Sample log:

[INF] Querying entities of type PartEntity
[INF] Saving aggregate PartAggregate/PN-2000 with 1 new events
[INF] Published event PartCreated { PartId = ..., PartNumber = "PN-2000" }

? Summary

  • Entities ? simple CRUD
  • Aggregates ? DDD + event sourcing
  • Unit of Work ? atomic batch commit
  • InMemory ? testing without ARAS
  • Snapshots ? scalable performance
  • Diagnostics ? enterprise observability
  • Bootstrapper ? one-liner service registration

?? Samples

This repo includes a samples/ folder with ready-to-run console apps:

  • Sample.Entities ? CRUD with PartEntity
  • Sample.Aggregates ? Domain events with PartAggregate
  • Sample.UoW ? Entities + aggregates in one transaction
  • Sample.InMemory ? Tests without ARAS
  • Sample.Diagnostics ? Logs + tracing

Franz.Common.Aras v1.5.0 � bringing ARAS into the DDD world.

Version 1.6.20

  • Updated to .NET 10.0

v2.0.1 � Internal Modernization

  • Messaging and infrastructure refactored for async, thread-safety, and modern .NET 10 patterns.
  • All APIs remain fully backward compatible.
  • Tests, listeners, and pipeline components modernized.
Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.3.0 117 7/21/2026
2.2.19 110 7/19/2026
2.2.18 97 7/19/2026
2.2.17 102 7/12/2026
2.2.16 112 7/2/2026
2.2.15 121 6/29/2026
2.2.14 112 6/29/2026
2.2.13 113 6/29/2026
2.2.12 109 6/28/2026
2.2.11 108 6/28/2026
2.2.10 119 6/28/2026
2.2.9 111 6/28/2026
2.2.8 108 6/28/2026
2.2.7 117 6/7/2026
2.2.6 126 6/6/2026
2.2.5 120 6/4/2026
2.2.4 113 6/3/2026
2.2.3 115 6/2/2026
2.2.2 117 6/2/2026
2.2.1 111 5/24/2026
Loading failed