mardi 11 juillet 2017

Deferring the execution of SQL in nested services?

I've started working with services and abstracting my business logic to them. All is going well, and it's great to be able to reuse code in a way that makes sense.

The problem I have hit is demonstrated below in some example code I have put together. As you can see, the person service handles the creating of people and during that process commits the creation of the person. This is all well and good, but when I want to reuse the function elsewhere and the changes shouldn't be commited until the end of that parent function then I have a problem.

I have demonstrated the above in the below service called 'ComplexService' which has a function to create x random people. During the for loop, if it was fail for any reason I would want the changes to the database not be comitted however in this example it does. How can I get round this?

Services

Public Class PersonService
    Implements IPersonService

    Private Property UnitOfWork As IUnitOfWork

    Public Sub New(unitOfWork As IUnitOfWork)
        Me.UnitOfWork = unitOfWork
    End Sub

    Public Sub Create(model As NewPersonModel) Implements IPersonService.Create
        Dim person As New Person With {
            .Name = model.Name,
            .DateOfBirth = model.DateOfBirth,
            .CreatedAt = DateTime.Now
        }
        UnitOfWork.PersonRepository.Add(person)
        UnitOfWork.Commit()
    End Sub
End Class

Public Class ComplexService
    Implements IComplexService
    Private Property PersonService As IPersonService

    Public Sub New(personService As IPersonService)
        Me.PersonService = personService
    End Sub

    Public Sub AddXRandomPeople(x As Integer) Implements IComplexService.AddXRandomPeople
        For i = 0 To x - 1
            PersonService.Create(
                New NewPersonModel With {
                    .DateOfBirth = DateTime.Now,
                    .Name = "Test"
                }
            )
        Next
    End Function
End Class

Models

Public Class NewPersonModel

    Public Property Name As String
    Public Property DateOfBirth As Date

End Class

Public Class Person

    Public Property Name As String
    Public Property DateOfBirth As Date
    Public Property CreatedAt As Date

End Class

Aucun commentaire:

Enregistrer un commentaire