Utilizzo del delegato per gestire i problemi trasversali

1

Sto pianificando di scrivere una libreria net-core per l'utilizzo con un'architettura n-tier. In questa architettura, voglio gestire i problemi trasversali (audit, gestione degli errori, registrazione, convalida, gestione delle transazioni, ecc.) Per i comandi (significa il comando di cqrs).

Attualmente sto usando mvc5 con la seguente architettura dell'applicazione (il livello cqrs è simile al livello servizio / applicazione):

  • Sample.Core (Business)
  • Sample.Data (Entity Framework)
  • Sample.Cqrs (comandi, query, gestori di comandi, gestori di query)
  • Sample.Web

Questa struttura mi consente di gestire i problemi trasversali del dispatcher generico come di seguito:

public CommandResult Dispatch<TParameter>(TParameter command) where TParameter : ICommand
{
    ValidateCommand(command); // if command is not valid throw exception
    var handler = _serviceLocator.Resolve<ICommandHandler<TParameter>>(); // resolve handler for command
    var auditService = _serviceLocator.Resolve<IAuditService>();
    using (var unitOfWork = new UnitOfWork())
    {
        try
        {
            var result = handler.Execute(command);
            if (result != null)
            {
                return result;// business validation
            }
            auditService.CreateAudit(command);//create audit for command
            unitOfWork.Commit();
            return new CommandResult(true);// success
        }
        catch
        {
            unitOfWork.Rollback();
            HandleException(e);
            throw;
        }
    }
}

Questo codice funziona come previsto. Ma per ragioni di semplicità ho deciso di ridefinire l'architettura con le seguenti modifiche:

  • Rimozione del livello Sample.Cqrs
  • Trasportare il codice CommandHandlers nei metodi di azione
  • Esecuzione di comandi e query per visualizzare modelli

Quindi, sto cercando qualsiasi modello per gestire i problemi trasversali nei metodi di azione invece di dispatcher. Due opzioni possibili che mi vengono in mente (ho eliminato il pattern di decoratore e l'intercettazione del metodo):

Uso di ActionFilter Uso del delegato (la mia domanda è per questa opzione) Per la seconda opzione il codice di esempio è come di seguito:

public CommandResult Execute(object command, Func<CommandContainer, CommandResult> handle)
{
    var container = new CommandContainer();// CommandContainer is for carrying audit data 
    ValidateCommand(command); // if command is not valid throw exception
    using(var unitOfWork = new UnitOfWork())
    {
        try
        {
            var result = handle(container);
            if (result != null)
            {
                return result;// business validation
            }
            _auditService.Save(command);
            unitOfWork.Commit();
            return new CommandResult(true);// success
         }
         catch(Exception ex)
         {
             unitOfWork.Rollback();
             _logger.Log(ex);
             throw;
         }
     }
 }

Quindi nel metodo action:

var result = _handler.Execute(command, (container) =>
             {
                 container.Comment = "dfsdf";
                 // Application logic
                 //return result;
             });

Domanda : se la mia decisione (rimozione del livello cqrs) non è negativa, la seconda opzione è l'approccio accettabile? Qualche altro suggerimento?

    
posta adem caglin 26.04.2016 - 22:44
fonte

0 risposte

Leggi altre domande sui tag