2017-06-19 4 views
0

私は、このarticleに記載されているように、作業単位パターンを使用しています。作業単位をサービスパターンで機能させるにはどうすればいいですか?

private readonly IUnitOfWork _unitOfWork; 

さらにサービスは、作業単位の操作をコミットするためにパブリックメソッドを持っている必要があります:

public void Save() 
{ 
    _unitOfWork.Commit(); 
} 

保存方法だけで呼び出すことができ、物品は、すべてのサービスがUnitOfWorkのを注入すべきであると説明していますサービスを呼び出す(webapi)コントローラ。

しかし、ここでは私の関心事です:

1)複数のデータベースの更新とサービス、そしてその場合には、各サービスの保存()を呼び出す必要がありますを呼び出すことができ、コントローラ?ロールバックが必要な場合はどうなりますか?

同様:

[HttpGet] 
public IHttpActionResult UpdateArchive() 
{ 
    _service1.DoUpdate(); 
    _service1.Save(); 
    _service2.DoUpdate(); 
    _service2.Save(); 
} 

何service2.Saveが失敗した場合は?

2)サービスが別のサービスを呼び出すと、どのように保存するかをコントローラがどのように知っていますか?

私はこの作業単位とちょっと混乱しています。

答えて

2

及びその場合には、サービスが同じ作業単位を共有しているかどうかに依存して、各サービス

のための保存()を呼び出す必要があります。はいの場合は、Saveのいずれかを呼び出して、操作を非常に同じUoWに委譲します。

その後、何トランザクションがなくなったので、ロールバックが

を必要とする場合、どのようにあなたは何をロールバックすることになっていますか?それは、正しく共有UOWと取引上のトランザクションの両方を処理するようTransactionScopeが非常に便利である

try 
{ 
    using (TransactionScope scope = new TransactionScope()) 
    { 
    _service1.DoUpdate(); 
    _service1.Save(); 
    _service2.DoUpdate(); 
    _service2.Save(); 

    scope.Complete(); 
    } 
} 
catch 
{ 
    // rollback occurs since the transaction was not completed 
} 

:オーケストレーション上で明示的なトランザクションを導入する一方

は、それは些細な変更をロールバックすることができます異なるサービスに注入された複数の異なるUoW上で実行されます。

service2.Saveに失敗した場合はどうなりますか?

トランザクションをロールバックしても、他のオプションはほとんどありません。

とにかく、repositories/uow over EF are disputable。あなたの問題の一部は、複数のサービスがUoWの同じインスタンスを共有するため、基本的にはSaveが電話するかどうかは関係ありません。電話番号SaveChangesは全く同じDbContextです。

私の意見は(意見がここに避けるべきであるにもかかわらず)あなたはおそらくあなたのサービスからSave Sをドロップすると、オーケストレーションの終了時に、あなたのデシベルの文脈上の単一SaveChangesにこだわるかもしれないということです。これにより意図が明確になります - サービスはUoWの内部状態を変更することですが、変更を維持する責任はコントローラにあります。

+0

最後の段落について:コントローラから直接dbコンテキストでSaveChangesを呼び出すことはありませんか?つまり、抽象化してはならないのですか? – brinch

+1

これは実際に私がDbContextを手に入れるかどうかにかかっています。そうでない場合(DIコンテナによって注入されていて、コントローラのどこにも表示されていないなど)、私はサービスの1つで 'Save'を呼び出します。 –

関連する問題