2014-09-18 2 views
0

У меня есть CommandHandler, который реализует некоторую логику для объекта и фиксирует контекст (в моем случае RavenDb IDocumentSession). Мне нужно реализовать ту же логику для коллекции объектов. Первая идея - создать новый CommandHandler, который будет вызывать первый CommandHandler для каждого объекта в foreach. Но это приведет к обращению с N-базами данных.Команда повторного использования объекта в команде для коллекции объектов

Лучшей идеей, к которой я пришел, было создание базового CommandHandler с самой логикой, но без коммита. Что-то вроде этого:

internal class AuditProductCommandHandler : AuditProductCommandHandlerBase, ICommandHandler<AuditProductCommand> 
{ 
    private readonly IDocumentSession _documentSession; 

    public AuditProductCommandHandler(IDocumentSession documentSession) 
    { 
     _documentSession = documentSession; 
    } 

    public void Execute(AuditProductCommand command) 
    { 
     AuditProduct(command.Product); 

     _documentSession.SaveChanges(); 
    } 
} 

internal class AuditProductsCommandHandler : AuditProductCommandHandlerBase, ICommandHandler<AuditProductsCommand> 
{ 
    private readonly IDocumentSession _documentSession; 

    public AuditProductsCommandHandler(IDocumentSession documentSession) 
    { 
     _documentSession = documentSession; 
    } 

    public void Execute(AuditProductsCommand command) 
    { 
     foreach (var product in command.Products) 
     { 
      AuditProduct(product); 
     } 

     _documentSession.SaveChanges(); 
    } 
} 

internal class AuditProductCommandHandlerBase 
{ 
    protected void AuditProduct(Product product) 
    { 
     //logic itself 
    } 
} 

По какой-то причине мне неудобно об этом решении. Есть ли лучшие варианты?

ответ

1

Я бы предложил удалить _documentSession.SaveChanges() в целом из реализации обработчика команд и передать ответственность вызывающему. Затем вызывающий может решить, нужно ли им связывать несколько обработчиков команд или несколько операций с БД, а затем вызывать SaveChanges() после этого. Поскольку вызывающий абонент несет ответственность за создание/отправку объекта IDocumentSession, они могут взять на себя ответственность за сохранение и удаление его.