Documentação
Todas as opções
Referência completa de cada opção, com o valor padrão e o motivo dele.
NexoOptions
O construtor de configuração que AddNexo entrega.
| Membro | Padrão | Descrição |
|---|---|---|
HandlerLifetime | Scoped | Tempo de vida dos handlers descobertos. Scoped combina com o unit of work pelo qual eles escrevem. |
MediatorLifetime | Scoped | Tempo de vida de IMediator. Singleton só é aceito com handlers singleton: um mediator singleton resolveria handlers scoped no escopo raiz, e o registro falha em vez de deixar isso acontecer. |
Services | — | A IServiceCollection, para registros que o Nexo não cobre. |
services.AddNexo(nexo =>
{
// Descoberta de handlers
nexo.AddHandlersFromAssemblyOf<Program>();
nexo.AddHandlersFromAssemblyOf<Program>(filter: t => !t.IsNested);
nexo.AddHandlersFromAssemblies(assemblyA, assemblyB);
nexo.AddHandlersFromAssemblies(filter: t => !t.IsNested, assemblyA, assemblyB);
nexo.AddHandler<UmHandlerEspecifico>();
nexo.AddGeneratedHandlers(); // gerado em tempo de compilação para este assembly
// Pipelines (registrar duas vezes não duplica)
nexo.AddLoggingPipeline(logging => { /* ... */ });
nexo.AddTimeoutPipeline(); // para [MessageTimeout]
nexo.AddEnrichmentPipeline();
nexo.AddUnitOfWorkPipeline(uow => { /* ... */ });
nexo.AddPipeline<MeuPipeline>();
nexo.AddPipeline<MeuPipeline>(ServiceLifetime.Singleton);
nexo.AddPipeline(sp => new MeuPipeline(sp.GetRequiredService<IFoo>()));
nexo.AddPipeline(new PipelineSemDependencia());
// Mediator
nexo.ConfigureMediator(m => m.EventDispatchMode = EventDispatchMode.Parallel);
// Usuário ambiente
nexo.UseCurrentUser<HttpCurrentUserAccessor>();
nexo.UseCurrentUser(sp => "sistema");
// Identificador público das entidades (padrão: UUID v7)
nexo.UseExternalIdGenerator(ExternalIdGenerators.SqlServer);
// Outros bancos, outbox e inbox (Nexo.EntityFrameworkCore)
nexo.UseDbContext<BillingDbContext>();
nexo.UseDbContext<ActivityDbContext>(session => session.UseTransactions = false);
nexo.UseOutbox(outbox => outbox.PollingInterval = TimeSpan.FromSeconds(1));
nexo.UseInbox();
});MediatorOptions
| Opção | Padrão | Descrição |
|---|---|---|
EventDispatchMode | Sequential | Como os handlers de um evento rodam. Sequencial é o padrão porque eles compartilham o escopo, e portanto o DbContext, que não é thread-safe. Parallel agrega as falhas via Task.WhenAll. |
UnitOfWorkPipelineOptions
| Opção | Padrão | Descrição |
|---|---|---|
SaveChangesOnCommand | true | Salva depois que o handler de comando retorna. É o que permite ao handler apenas parar. |
SaveChangesOnEvent | true | Salva depois de um evento publicado de fora. Eventos publicados de dentro de um comando entram no unit of work dele, independente disso. |
UseTransaction | true | Envolve handler, save e eventos numa transação, com a execution strategy do provider. Ignorado em provider sem transação. |
DispatchDomainEvents | true | Coleta os eventos das entidades alteradas — antes do save, para não perder os de uma entidade removida — e os despacha depois dele, na mesma transação. Eventos de integração vão para o outbox, se houver um. |
MaxDomainEventRounds | 4 | Quantas rodadas de cascata são permitidas. Estourar aborta a transação em vez de entrar em laço. |
WarnOnPendingQueryChanges | true | Registra warning quando um handler de query deixa mudanças pendentes — quase sempre uma escrita que vazou. |
LoggingPipelineOptions
| Opção | Padrão | Descrição |
|---|---|---|
Level | Debug | Nível das entradas de início e sucesso. |
FailureLevel | Error | Nível quando o handler lança algo inesperado. |
ExpectedFailureLevel | Information | Nível das falhas que são respostas e não incidentes: validação, não encontrado, regra de negócio, chave duplicada, conflito de concorrência, cancelamento pedido. |
IsExpectedFailure | a lista acima | Decide quais exceções são esperadas. |
LogPayload | false | Desligado de propósito. Comando carrega senha, token e dado pessoal; um default que vaza isso é passivo, não recurso. |
LogResult | false | Serializa o resultado. Raramente vale o volume. |
Serializer | System.Text.Json | Como o payload virou texto. Substitua por um serializador que redija campos. |
Todo despacho abre um escopo de log com NexoMessageKind, NexoMessageName e NexoMessageId, então qualquer linha escrita dentro do handler já sai correlacionada.
ValidationPipelineOptions
| Opção | Padrão | Descrição |
|---|---|---|
ValidateCommands | true | Comandos mudam estado. |
ValidateQueries | true | Mantém filtros e paginação sãos. |
ValidateEvents | false | Um evento descreve algo que já aconteceu; rejeitar depois do fato raramente ajuda. |
FailIfValidatorNotFound | false | Ligue quando o time decidir que todo comando tem de ter validator, e você quiser que o container cobre isso. |
DbSessionOptions
Um conjunto por contexto. services.Configure<DbSessionOptions>(…) define o padrão de todos os bancos; o callback de AddNexo<TContext> ou de UseDbContext<TContext> ajusta um deles, partindo desse padrão.
| Opção | Padrão | Descrição |
|---|---|---|
SaveBehavior | UnitOfWork | Quando as mudanças vão ao banco. Immediate salva a cada operação: conveniente num script, mas abre mão da atomicidade. |
TrackReads | true | Leituras por chave voltam rastreadas. IQueryable injetado nunca rastreia, independente disso. |
SoftDelete | true | IDelete marca entidades ISoftDeletable em vez de removê-las. |
ApplyAudit | true | Liga as estampas do AuditInterceptor. |
AssignMissingExternalIds | true | Atribui um identificador no insert quando o campo está vazio, com o gerador de UseExternalIdGenerator. |
UseTransactions | null | null detecta pelo provider: relacional sim, in-memory e MongoDB não. Defina true para um MongoDB em replica set. Sem transação, num contexto não relacional, o Nexo também desliga a transação automática do provider. |
// O padrão de todos os bancos.
services.Configure<DbSessionOptions>(session => session.TrackReads = true);
services.AddNexo<CatalogDbContext>(nexo => nexo
// Herda TrackReads = true, sobrescreve o resto.
.UseDbContext<ActivityDbContext>(session =>
{
session.UseTransactions = false;
session.SoftDelete = false;
}));
// Conferindo o que valeu, por banco:
var sessions = scope.ServiceProvider.GetRequiredService<DbSessionProvider>();
sessions.ForEntity<ActivityEntry>().Options.SoftDelete; // false
sessions.ForEntity<Product>().Options.SoftDelete; // trueOutboxOptions
Passadas em nexo.UseOutbox(outbox => …). Veja Outbox.
| Opção | Padrão | Descrição |
|---|---|---|
RunDispatcher | true | Registra o serviço em background que entrega os eventos. Desligue para chamar OutboxProcessor.ProcessAsync de um agendador seu. |
PollingInterval | 2 s | O intervalo entre passadas quando não há nada pendente. |
BatchSize | 50 | Quantos eventos uma passada tenta entregar. |
MaxAttempts | 10 | Depois disso o evento fica na tabela, com o último erro, para uma pessoa olhar. |
RetryDelay / MaxRetryDelay | 5 s / 10 min | O back-off exponencial entre tentativas. |
ClaimDuration | 1 min | Por quanto tempo uma instância reserva um evento que está entregando. |
SerializerOptions | JsonSerializerDefaults.General | Como o evento é gravado e lido. |
Um setup completo, tudo explícito
// Um AddDbContext por banco. O Nexo nunca registra o contexto por você.
builder.Services.AddDbContext<CatalogDbContext>((sp, options) => options
.UseSqlServer(
builder.Configuration.GetConnectionString("Catalog"),
sql => sql.EnableRetryOnFailure())
.UseNexo(sp));
builder.Services.AddDbContext<PurchasingDbContext>((sp, options) => options
.UseMySQL(
builder.Configuration.GetConnectionString("Purchasing")!,
mySql => mySql.EnableRetryOnFailure())
.UseNexo(sp));
builder.Services.AddDbContext<ActivityDbContext>((sp, options) => options
.UseMongoDB(builder.Configuration.GetConnectionString("Activity")!, "activity")
.UseNexo(sp));
builder.Services.AddNexo<CatalogDbContext>(
nexo =>
{
nexo.HandlerLifetime = ServiceLifetime.Scoped;
nexo.MediatorLifetime = ServiceLifetime.Scoped;
// Os outros bancos, cada um com as opções de sessão dele.
nexo.UseDbContext<PurchasingDbContext>();
nexo.UseDbContext<ActivityDbContext>(session =>
{
session.UseTransactions = false;
session.SoftDelete = false;
});
nexo.AddHandlersFromAssemblyOf<Program>();
nexo.AddValidatorsFromAssemblyOf<Program>();
nexo.UseCurrentUser<HttpCurrentUserAccessor>();
nexo.ConfigureMediator(mediator =>
mediator.EventDispatchMode = EventDispatchMode.Sequential);
nexo.AddPipeline<MetricsPipeline>(ServiceLifetime.Singleton);
},
// As opções de sessão do CatalogDbContext.
session =>
{
session.SaveBehavior = SaveBehavior.UnitOfWork;
session.TrackReads = true;
session.SoftDelete = true;
session.ApplyAudit = true;
});Configurando por appsettings
Todas as opções passam por IOptions<T>, então podem vir da configuração como qualquer outra.
{
"Nexo": {
"UnitOfWork": {
"UseTransaction": true,
"MaxDomainEventRounds": 4
},
"Logging": {
"Level": "Information",
"LogPayload": false
}
}
}builder.Services.Configure<UnitOfWorkPipelineOptions>(
builder.Configuration.GetSection("Nexo:UnitOfWork"));
builder.Services.Configure<LoggingPipelineOptions>(
builder.Configuration.GetSection("Nexo:Logging"));