2017-07-11 4 views
0

私はサービスに取り組み、ビジネスロジックをそれらに抽象化し始めました。すべてが順調に進んでおり、理にかなった方法でコードを再利用できることは素晴らしいことです。ネストされたサービスでのSQLの実行を延期しますか?

私がヒットした問題は、私がまとめたいくつかのコード例で以下に説明されています。ご覧のように、人サービスは人の作成を処理し、そのプロセス中に人の作成を行います。これはすべてうまくいいですが、私は別の場所で関数を再利用したいとき、その親関数の終わりまで変更をコミットしてはなりません。問題があります。

私は上記のサービスを「ComplexService」と呼びます。このサービスでは、x人のランダムな人物を作成する機能があります。 forループの間に何らかの理由で失敗した場合、この例ではデータベースへの変更はコミットされないようにしたいと思います。どうすればこれを回すことができますか?

サービス

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 

モデル

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 

答えて

0

単純なルールがあります:あなたはそれを作成

は、あなたはそれを所有しています。

つまり、オブジェクトを作成するクラスは、オブジェクトが正しく処理されることを確認するクラスです。

あなたの場合は、所有物をPersonServiceに転送します。私の意見では、PersonServiceは、呼び出し側のクラスが意図したことを知ることができないため、間違っています。

呼び出し元のクラスが人を作成し、次に注文を作成したい場合はどうなりますか?各サービスがコミットすると、ビジネストランザクションは矛盾した状態になる可能性があります。

したがって、complexServiceとpersonServiceの両方を呼び出すコードは、すべての作業が完了したらUnitOfWorkをコミットする責任があります。責任を移すことで、説明されている問題は発生しません。私が言っている何のコメント

に応じて

更新は、トランザクション/ UOWをコミットする責任を負わなければならない現在の実行のためのエントリポイントであるということです。ビジネストランザクションがいつ行われるのか知っているのはその場所だけです。

MVCアプリケーションの場合、エントリポイントはMVCコントローラアクションです。 WCFの場合、サービス内のメソッド。 Windowsサービスアプリケーションの場合は、タイマーまたはスレッドメソッドである可能性があります。

要求された機能を完了するために、1つ、2つまたは3つの異なるサービスおよび/またはサービスメソッドを呼び出す必要があるかどうかを知っているのは、それらの場所だけです。

+0

UnitOfWork.Commit()は私のサービス内で呼び出されるべきではなく、代わりに他のサービスが呼び出せるように私のサービスによって公開された関数にラップする必要がありますか?私はそれについてどのように感じるか分かりません。そうでない場合は、単純な例を集めたり、私のコードをリファクタリングしてポイントを説明してください。 –

+0

サービスが内部サービスかWebサービスかによって異なります。あなたはそれを指定しないで質問します。 – jgauffin

+0

内部サービスです。 –

関連する問題