BrainEnterprise.Core.Enums 13.0.0

Prefix Reserved
dotnet add package BrainEnterprise.Core.Enums --version 13.0.0
                    
NuGet\Install-Package BrainEnterprise.Core.Enums -Version 13.0.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="BrainEnterprise.Core.Enums" Version="13.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BrainEnterprise.Core.Enums" Version="13.0.0" />
                    
Directory.Packages.props
<PackageReference Include="BrainEnterprise.Core.Enums" />
                    
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 BrainEnterprise.Core.Enums --version 13.0.0
                    
#r "nuget: BrainEnterprise.Core.Enums, 13.0.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 BrainEnterprise.Core.Enums@13.0.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=BrainEnterprise.Core.Enums&version=13.0.0
                    
Install as a Cake Addin
#tool nuget:?package=BrainEnterprise.Core.Enums&version=13.0.0
                    
Install as a Cake Tool

BrainEnterprise.Core.Enums

Libreria di utilità per la gestione degli Enum in .NET. Fornisce helper per descrizioni leggibili e testi estesi, conversione in DataTable/List, metadata UI, colori di stato, raggruppamento, extension methods e gestione completa delle transizioni di stato.

Versione corrente: 13.0.0. Le rotture rispetto alle major precedenti sono in fondo, nella sezione Breaking changes.

Target Framework

  • .NET Standard 2.0
  • .NET Framework 4.6.2
  • .NET 9

Installazione

dotnet add package BrainEnterprise.Core.Enums

Classi principali

Classe Namespace Descrizione
EnumHelper BrainEnterprise.Core.Enums Metodi statici per convertire enum in DataTable, List<EnumItem> e proiezione per il binding
EnumItem BrainEnterprise.Core.Enums DTO con proprietà Id e SortOrder (int), Description, Hint e Group (string)
HintAttribute BrainEnterprise.Core.Enums.Attributes Attributo per il testo esteso di un valore (tooltip, help contestuale)
StatusColorAttribute BrainEnterprise.Core.Enums.Attributes Attributo per i colori di stato: tema chiaro, tema scuro, sfondo e testo del badge
EnumMetadataAttribute BrainEnterprise.Core.Enums.Attributes Attributo per metadata UI: Icon, CssClass, SortOrder, IsActive
EnumGroupAttribute BrainEnterprise.Core.Enums.Attributes Attributo per raggruppare valori enum sotto un nome logico
EnumExtensions BrainEnterprise.Core.Enums.Extensions Extension methods sui metadata: ToDescription(), ToColor() (deprecata), ToIcon(), ToCssClass(), ToSortOrder(), ToIsActive(), ToGroup(), EnumMetadataInfo()
EnumMeta BrainEnterprise.Core.Enums.Extensions Punto di accesso unico ai testi di un valore: GetTexts(), GetDescription(), GetHint()
EnumMeta.Texts BrainEnterprise.Core.Enums.Extensions Coppia immutabile Description + Hint restituita da GetTexts()
StatusColorExtensions BrainEnterprise.Core.Enums.Extensions Extension methods sui colori di stato: StatusColorInfo(), StatusColor(), StatusDarkColor(), StatusBadgeBackground(), StatusBadgeForeground()
AllowedTransitionsAttribute BrainEnterprise.Core.Enums.Transitions Attributo per dichiarare gli stati successivi consentiti
StatusTransitionHelper BrainEnterprise.Core.Enums.Transitions Helper statico per transizioni basate su attributi
TransitionRule<TEnum> BrainEnterprise.Core.Enums.Transitions Regola di transizione con condizione opzionale e descrizione
StatusMachine<TEnum> BrainEnterprise.Core.Enums.Transitions State machine configurabile con API fluent: Allow(), CanTransition(), Transition(), GetAllowedNextStatuses()

Utilizzo

Enum di esempio

using System.ComponentModel;
using BrainEnterprise.Core.Enums.Attributes;
using BrainEnterprise.Core.Enums.Transitions;

public enum OrderStatus
{
    [Description("In attesa di pagamento")]
    [Hint("L'ordine è registrato ma non ancora pagato: non viene preso in carico dal magazzino.")]
    [StatusColor("#FFA500", DarkColor = "#FBBF24", BadgeBackground = "#FEF3C7")]
    [EnumMetadata(Icon = "hourglass", CssClass = "badge-warning", SortOrder = 10)]
    [EnumGroup("Attivi")]
    [AllowedTransitions((int)Confirmed, (int)Cancelled)]
    Pending = 0,

    [Description("Confermato")]
    [StatusColor("#007BFF")]
    [EnumMetadata(Icon = "check", CssClass = "badge-info", SortOrder = 20)]
    [EnumGroup("Attivi")]
    [AllowedTransitions((int)Shipped, (int)Cancelled)]
    Confirmed = 1,

    [Description("Spedito")]
    [StatusColor("#17A2B8")]
    [EnumMetadata(Icon = "truck", CssClass = "badge-primary")]
    [EnumGroup("Attivi")]
    [AllowedTransitions((int)Delivered)]
    Shipped = 2,

    [Description("Consegnato")]
    [StatusColor("#28A745")]
    [EnumMetadata(Icon = "package", CssClass = "badge-success")]
    [EnumGroup("Chiusi")]
    Delivered = 3,

    [Description("Annullato")]
    [StatusColor("#DC3545")]
    [EnumMetadata(Icon = "x-circle", CssClass = "badge-danger", IsActive = false)]
    [EnumGroup("Chiusi")]
    Cancelled = 4
}

ToDataTable / ToList / ToItems

using BrainEnterprise.Core.Enums;

DataTable table = EnumHelper.ToDataTable<OrderStatus>();
// Id | Description
// 0  | In attesa di pagamento
// 1  | Confermato
// ...

DataTable full = EnumHelper.ToDataTable<OrderStatus>(includeHint: true, includeGroup: true);
// Id | Description            | Hint                          | Group
// 0  | In attesa di pagamento | L'ordine è registrato ma ...   | Attivi
// 1  | Confermato             | (vuoto: membro non decorato)  | Attivi

// i due flag sono indipendenti: con il solo includeGroup la colonna Group è la terza

List<EnumItem> items = EnumHelper.ToList<OrderStatus>();
// [{ Id = 0, Description = "In attesa di pagamento", Hint = "L'ordine è ...", Group = "Attivi" }, ...]

IList<EnumItem> forBinding = EnumHelper.ToItems<OrderStatus>();
// come ToList, ma ordinato per valore numerico: è la sorgente pensata per il binding
// (DevExpress ImageComboBoxEdit / LookUpEdit, dropdown ASPx), con il tooltip di riga
// agganciato a Hint senza reflection nel layer di presentazione

IList<EnumItem> byPosition = EnumHelper.ToItems<OrderStatus>(orderBySortOrder: true);
DataTable sorted = EnumHelper.ToDataTable<OrderStatus>(orderBySortOrder: true);
// ordinati per EnumMetadata.SortOrder invece che per valore numerico

Le colonne Hint e Group di ToDataTable sono opt-in: per default la tabella mantiene le sole colonne Id e Description, così le griglie che generano le colonne automaticamente non ne vedono di nuove. L'ordine è sempre Id, Description, Hint, Group, e i membri privi di testo esteso o di gruppo valgono stringa vuota, non DBNull: la tabella si aggancia ad un binding senza dover gestire il null, come già fanno le estensioni sui colori di stato. Su EnumItem le stesse proprietà restano invece a null, coerentemente con GetHint() e ToGroup().

La DataTable prende il nome del tipo enumerativo (TableName = "OrderStatus").

L'ordine di presentazione si controlla con EnumMetadataAttribute.SortOrder e il flag orderBySortOrder, disponibile sia su ToDataTable sia su ToItems. Anche questo è opt-in: per default ToItems ordina per valore numerico e ToDataTable segue l'ordine di dichiarazione, come prima. Con il flag attivo l'ordinamento è SortOrder e, a parità, il valore numerico: i membri privi di EnumMetadata valgono SortOrder 0, quindi precedono quelli con un ordinamento positivo, restando fra loro in ordine numerico. Se l'enumerativo mescola membri decorati e non, conviene decorarli tutti.

Il parametro generico è vincolato a struct, Enum: passare un tipo che non è un enumerativo è un errore di compilazione. Il valore numerico è esposto come int, quindi un enumerativo con underlying type long o ulong fuori dal range di int fa lanciare OverflowException.

Extension methods

using BrainEnterprise.Core.Enums.Attributes;
using BrainEnterprise.Core.Enums.Extensions;

OrderStatus status = OrderStatus.Pending;

string desc = status.ToDescription();   // "In attesa di pagamento"
string icon = status.ToIcon();          // "hourglass"
string css = status.ToCssClass();       // "badge-warning"
int order = status.ToSortOrder();       // 10 (0 se non specificato)
bool active = status.ToIsActive();      // true (un valore non decorato è considerato attivo)
string group = status.ToGroup();        // "Attivi"

// quando servono più metadati sullo stesso valore, una sola lettura
EnumMetadataAttribute metadata = status.EnumMetadataInfo();   // null se non decorato

Per i colori si usa StatusColor() (vedi sotto). ToColor() ed EnumMetadataAttribute.Color restano disponibili ma sono [Obsolete] dalla 13.0.0.

Testo esteso con HintAttribute

DescriptionAttribute resta l'etichetta breve mostrata in elenchi e combo; HintAttribute affianca un testo più esteso da usare come tooltip o help contestuale. I due canali sono indipendenti: aggiungere un hint non tocca ciò che già legge la descrizione.

using BrainEnterprise.Core.Enums.Extensions;

OrderStatus status = OrderStatus.Pending;

string label = status.GetDescription();   // "In attesa di pagamento"
string tooltip = status.GetHint();        // "L'ordine è registrato ma ..." (null se non decorato)

// unica lettura quando servono entrambi
EnumMeta.Texts texts = status.GetTexts();

Un valore non definito nell'enumerativo — tipicamente un intero letto da database — non lancia eccezioni: degrada su ToString() con Hint a null.

Colori di stato con StatusColorAttribute

StatusColorAttribute tiene insieme le varianti di colore di un valore — tema chiaro, tema scuro, sfondo e testo del badge — e le fa ricadere l'una sull'altra. I colori sono stringhe esadecimali, così l'assembly non è vincolato ad una specifica tecnologia di presentazione.

using BrainEnterprise.Core.Enums.Attributes;
using BrainEnterprise.Core.Enums.Extensions;

OrderStatus status = OrderStatus.Pending;

string light = status.StatusColor();               // "#FFA500"
string dark = status.StatusDarkColor();            // "#FBBF24"
string badgeBack = status.StatusBadgeBackground(); // "#FEF3C7"
string badgeFore = status.StatusBadgeForeground(); // non specificato: ricade su Color

// l'attributo completo, o null se il valore non è decorato
StatusColorAttribute info = status.StatusColorInfo();

I metodi restituiscono stringa vuota — non null — quando il valore non è decorato, per poter essere usati direttamente in un binding.

Transizioni di stato con attributi

StatusTransitionHelper utilizza AllowedTransitionsAttribute per validare le transizioni. L'assenza dell'attributo su un valore significa "stato finale".

using BrainEnterprise.Core.Enums.Transitions;

// Verifica se una transizione è consentita
bool ok = StatusTransitionHelper.CanTransition(OrderStatus.Pending, OrderStatus.Confirmed);   // true
bool ko = StatusTransitionHelper.CanTransition(OrderStatus.Pending, OrderStatus.Delivered);    // false

// Esegue la transizione o lancia InvalidOperationException
var next = StatusTransitionHelper.Transition(OrderStatus.Pending, OrderStatus.Confirmed);

// Ottiene gli stati raggiungibili
var allowed = StatusTransitionHelper.GetAllowedNextStatuses(OrderStatus.Pending);
// EnumItem completi: Id, Description e, se i membri sono decorati, anche Hint e Group
// [{ Id = 1, Description = "Confermato", Group = "Attivi" }, { Id = 4, ... }]

State machine configurabile

StatusMachine<TEnum> permette di definire transizioni a runtime con API fluent, supportando condizioni opzionali.

using BrainEnterprise.Core.Enums.Transitions;

var machine = new StatusMachine<OrderStatus>()
    .Allow(OrderStatus.Pending, OrderStatus.Confirmed, "Conferma ordine")
    .Allow(OrderStatus.Pending, OrderStatus.Cancelled, "Annullamento")
    .Allow(OrderStatus.Confirmed, OrderStatus.Shipped, "Spedizione")
    .Allow(OrderStatus.Confirmed, OrderStatus.Cancelled, "Annullamento post-conferma")
    .Allow(OrderStatus.Shipped, OrderStatus.Delivered, "Consegna avvenuta");

// Verifica transizione
bool canShip = machine.CanTransition(OrderStatus.Confirmed, OrderStatus.Shipped); // true

// Esegue la transizione o lancia InvalidOperationException
var next = machine.Transition(OrderStatus.Confirmed, OrderStatus.Shipped);

// Stati raggiungibili
var nextStates = machine.GetAllowedNextStatuses(OrderStatus.Confirmed);
// [{ Id = 2, Description = "Spedito", Group = "Attivi" }, { Id = 4, ... }]

// Transizione condizionale
bool isPaid = true;
var conditionalMachine = new StatusMachine<OrderStatus>()
    .Allow(OrderStatus.Pending, OrderStatus.Confirmed,
           "Conferma solo se pagato",
           condition: () => isPaid);

L'istanza non è thread-safe in scrittura: va configurata una sola volta, prima di essere condivisa fra più thread in lettura.

TransitionRule<TEnum> è la forma della singola regola: From, To, Description e la Condition opzionale. Serve quando le regole non si dichiarano una ad una ma arrivano da una sorgente esterna — tipicamente la configurazione — e si passano già pronte all'overload Allow(TransitionRule<TEnum>):

var rule = new TransitionRule<OrderStatus>
{
    From = OrderStatus.Pending,
    To = OrderStatus.Confirmed,
    Description = "Conferma ordine",
    Condition = () => isPaid          // opzionale
};

var machine = new StatusMachine<OrderStatus>().Allow(rule);

La regola viene copiata: modificarla dopo la chiamata non altera il comportamento della macchina a stati. Una regola null viene rifiutata con ArgumentNullException.

Cache e prestazioni

Tutte le letture di attributi passano da un'unica cache interna, indicizzata per coppia valore/tipo di attributo: la reflection viene eseguita una sola volta per valore e l'accesso è thread-safe (ConcurrentDictionary). Vale per ToDescription(), GetTexts(), i metadata di presentazione, il gruppo e i colori di stato, cioè proprio le chiamate che si ripetono ad ogni riga di una griglia.

Conseguenza da tenere presente: gli attributi restituiti da EnumMetadataInfo() e StatusColorInfo() sono istanze condivise. Vanno considerati di sola lettura — modificarne le proprietà altera il valore visto da tutti i chiamanti.

Breaking changes

13.0.0

Major di riordino: le rotture sono raccolte qui per non spezzare i consumer più volte.

  • Vincolo generico where TEnum : struct, Enum su EnumHelper, StatusTransitionHelper, StatusMachine<TEnum> e TransitionRule<TEnum>. Passare una struct che non è un enumerativo è ora un errore di compilazione (CS0315) invece di ArgumentException a runtime. Di conseguenza quei metodi non lanciano più ArgumentException: i try/catch che la intercettavano sono codice morto.
  • EnumItem è un tipo di primo livello, non più annidato in EnumHelper. I riferimenti scritti come EnumHelper.EnumItem vanno aggiornati in EnumItem; chi usa using static BrainEnterprise.Core.Enums.EnumHelper; non è impattato.
  • EnumMetadataAttribute ed EnumGroupAttribute sono passati al namespace BrainEnterprise.Core.Enums.Attributes, insieme agli altri attributi: serve aggiungere la using.
  • AllowedTransitionsAttribute.AllowedNextStatuses è IReadOnlyList<int> invece di int[]. Chi lo assegnava ad un int[] deve usare ToArray().
  • StatusMachine.GetAllowedNextStates è stato rinominato in GetAllowedNextStatuses, per allinearsi a StatusTransitionHelper. Il nome storico resta come [Obsolete] e delega al nuovo: verrà rimosso in una versione successiva.
  • EnumMetadataAttribute.Color ed EnumExtensions.ToColor() sono [Obsolete]: i colori hanno un solo canale, StatusColorAttribute / StatusColor(). Compilano ancora, con warning CS0618.
  • EnumItem ha due proprietà in più, Group e SortOrder, valorizzate da ToList(), ToItems() e dagli helper di transizione. Come per Hint nella 12.0.0, chi proietta EnumItem su una griglia con generazione automatica delle colonne vede due colonne in più. In ToDataTable() la colonna Group resta opt-in e SortOrder non viene esposta: serve solo ad ordinare, tramite il flag orderBySortOrder.

12.0.0

Nessuna firma pubblica rimossa o modificata: chi aggiornava da 11.0.0 non doveva toccare il codice. Cambiavano però alcuni comportamenti.

  • Gli attributi restituiti sono istanze condivise. EnumMetadataInfo() e StatusColorInfo() restituiscono l'istanza in cache invece di una nuova ad ogni chiamata. Codice che ne modificava le proprietà dopo la lettura influenza tutti i chiamanti.
  • ToDescription() su un valore null non lancia più NullReferenceException: restituisce stringa vuota.
  • EnumItem ha una proprietà in più (Hint), valorizzata anche da ToList(), GetAllowedNextStatuses(). Chi proietta EnumItem su una griglia con generazione automatica delle colonne vede una colonna in più. ToDataTable() non è cambiato: espone sempre e solo Id e Description. Dalla 13.0.0 le colonne opzionali si richiedono esplicitamente con ToDataTable<TEnum>(includeHint: true, includeGroup: true).
  • I pacchetti Debug non contengono più i simboli (DebugType=none), allineandosi alle altre librerie del workspace. I simboli restano nei pacchetti Release.

In entrambi i major cambia l'AssemblyVersion, quindi i consumer su .NET Framework devono aggiornare gli eventuali binding redirect.

Licenza

MIT - 2026 Brain Enterprise S.r.l.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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 is compatible.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 is compatible.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETFramework 4.6.2

    • No dependencies.
  • .NETStandard 2.0

    • No dependencies.
  • net9.0

    • No dependencies.

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
13.0.0 95 8/23/2026
11.0.0 112 7/30/2026
10.0.0 136 3/29/2026
1.0.0 159 3/28/2026