Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Commands depending on other commands when using the decorator pattern for transaction #11

Open
ghost opened this issue May 24, 2017 · 3 comments
Labels

Comments

@ghost
Copy link

ghost commented May 24, 2017

Hi,

I've been using your TransactionCommandHandlerDecorator and I came across a small problem when using this in conjunction with a command that has a dependency on another command as it is creating a second transaction block for the other command when I want it to share the same transaction?

Here is some code to demonstrate the problem.

Public Class TransactionCommandHandlerDecorator(Of TCommand)
    Implements ICommandHandler(Of TCommand)

    Private ReadOnly _decorated As ICommandHandler(Of TCommand)
    Private ReadOnly _context As ApplicationDBContext

    Public Sub New(context As ApplicationDBContext, decorated As ICommandHandler(Of TCommand))
        _context = context
        _decorated = decorated
    End Sub

    Public Sub Handle(command As TCommand) Implements ICommandHandler(Of TCommand).Handle
        Using transaction = _context.Database.BeginTransaction()
            Try
                _decorated.Handle(command)
                transaction.Commit()
            Catch ex As Exception
                transaction.Rollback()
                Throw
            End Try
        End Using
    End Sub
End Class
Public Class CreateProcedureTemplateDetailQuestionTypeHandler
    Implements ICommandHandler(Of CreateProcedureTemplateDetailQuestionTypeCommand)

    Private ReadOnly _context As ApplicationDBContext
    Private ReadOnly _handler As ICommandHandler(Of CreateProcedureTemplateDetailCommand)

    Public Sub New(context As ApplicationDBContext, handler As ICommandHandler(Of CreateProcedureTemplateDetailCommand))
        _context = context
        _handler = handler
    End Sub

    Public Sub Handle(command As CreateProcedureTemplateDetailQuestionTypeCommand)
        Implements ICommandHandler(Of CreateProcedureTemplateDetailQuestionTypeCommand).Handle
        _handler.Handle(command.DetailCommand)

        'Do other stuff specific to this command
    End Sub
End Class

But once I call handle inside of CreateProcedureTemplateDetailQuestionTypeHandler.Handle() I get an exception as it tries to create another transaction scope. What is the best way of dealing with this, should I just new up instance inside of the CreateProcedureTemplateDetailQuestionTypeHandler and not use DI for that case?

@dotnetjunkie
Copy link
Owner

ith a command that has a dependency on another command

This is the core of your problem. My advise is to treat commands as holistic abstractions. This means that command handlers should not depend on other command handlers, especially not within the context of the same abstraction. You should use a different abstraction when dealing with 'sub commands'. This could be as well a generic abstraction, or you use normal non-generic interfaces for them.

@ghost
Copy link
Author

ghost commented May 24, 2017

What I have done is created a ICommandStrategyHandler and this is to be used by my sub command and the ICommandHandler is still decorated by the transaction. My instance of ICommandHandler then has a dependency on the new interface for it's sub command. This seems to have sorted it, but was checking to see if this is what you meant? This means that every instance of ICommandHandler will use the transaction but the other interface won't.

@dotnetjunkie
Copy link
Owner

Seems legit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant