2011-06-27 13 views
0

従来のコードでは、ビジネスロジックと混在する大量のトランザクションdbアクセスコードがあります。 私はそれをサービスとリポジトリに分け、トランザクションの制御をサービスの外に置いて、テスト容易化のためにトランザクションを抽象化したいと考えています。サービス/リポジトリ/ユニットワークとのトランザクション

問題は、私はのIDbConnectionパラメータを持っている必要があります、あり、両方のサービスとリポジトリ層内のすべてのメソッドシグネチャのために、トランザクションに参加し、そしてそれは、私は確かに好きではないです:

void Process(Stuff s, IDbConnection connection); 

私が欲しいです

void Process(Stuff stuff, User u) 
{ 
using(var UoW = ???) // Start transaction 
{ 
    // various operations in the same transaction 
    if(AuthorizationService.AuthorizesUserForStuff(u,stuff)) 
    { 
    StuffService.Process(stuff); 
    AuditService.Success(u, stuff); 
    } 
    else 
    AuditService.Failure(u,stuff); 
    UoW.Commit(); 
} 
} 

リポジトリ:

void Process(Stuff s) 
{ 
IDbCommand command = ??? //aware of current UnitOfWork 
... 
command.ExecuteNonQuery(); 
} 
トップレベルの方法ではこのような何かを持っている方法を把握します

レガシーコードはORMを使用していません。ストアドプロシージャとカスタムSQLコードが多く、データベースへのラウンドトリップが必要な操作もあります。単体でオブジェクトを登録してコミット操作を行うことはできません方法。

この状況では、いくつかの永続性の無知のためにどのパターンを使用できるかを提案し、最上位レベルでトランザクションを制御できるようにしてください。

答えて

0

このためにORマッピングを使用しています。そのため、私たちのソリューションは異なって見えます。しかし、同じことを達成するための1つの方法は、抽象的な永続コンテキストを使用して具体的なデータベースを処理し、これを使用するすべてのサービスクラスにこれを注入し、このコンテキストから作業レベルを「プロセス」レベルで作成し、 UoWインスタンスがコンテキストインスタンスと連携してトランザクションの状態と接続を管理できるようにします。

実際にDB-ものをやったとき、あなたの状況では、あなたの(注入)コンテキストインスタンスからのDB接続をAQUIREう

 using (var unitOfWork = Context.CreateUnitOfWork()) 
     { 
      // access injected services and repositories to modify stuff 

      unitOfWork.Complete(); 
     } 

、この

 using (var conn = Context.AquireDbConnection()) 
     using (var command = conn.CreateDbCommand()) 
     { 
      // do db stuff 

      command.ExecuteNonQuery(); 
     } 

あなたの具体的なユニットのようなもののようなものにアクティブなアンビエントビジネストランザクションが存在するかどうかに基づいて、返される接続が新しい接続または周囲接続であるかどうかを認識するために、ここで十分にスマートでなければなりません。

明らかに、このメカニズムにはリクエストごとの分離が必要であり、コンテキストインスタンスのライフタイムは要求ごとに発生することは明らかです。

1

実際の作業単位のないリポジトリが表示される唯一の方法は、Static gateway patternです。私はあなたの欲求不満を理解していますが、私はこのようにするのははるかに優れているとは思いません。 ユニットテストも難しくなり、コードの可読性も向上します。

私は非常に他の方法でintestedされます。

関連する問題