2017-06-19 2 views
0

Ich verwende das Muster der Arbeitseinheit, wie es in dieser article beschrieben wird. Der Artikel erklärt, dass jeder Dienst eine UnitOfWork injizieren sollte:Wie funktioniert die Einheit mit dem Dienstmuster?

private readonly IUnitOfWork _unitOfWork; 

Des Weiteren muss ein Dienst eine öffentliche Methode haben zu begehen unit-of-Arbeitsvorgänge:

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

Die Save-Methode darf nur von

aufgerufen werden der (Webapi) -Controller, der den Dienst aufruft.

Aber hier sind meine Bedenken:

1) Die Steuerung kann mehr als einen Dienst mit Datenbank-Updates nennen, und in diesem Fall sollte es Save() für jeden Dienst anrufen? Was ist dann, wenn ein Rollback benötigt wird?

Like:

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

Was passiert, wenn service2.Save ausfällt?

2) Was ist, wenn ein Service einen anderen Service anruft? Wie weiß der Controller, welche Save zu callen ist?

Ich bin ein bisschen verwirrt mit dieser Einheit der Arbeit.

Antwort

2

und in diesem Fall sollte es Save() für jeden Dienst

nennen, der davon abhängt, ob Dienste die gleiche Arbeitseinheit teilen. Wenn ja, rufen Sie Save auf einer von ihnen, es delegiert die Operation auf die gleiche UOW.

Was dann, wenn ein Zurücksetzen

benötigt wird Da es keine Transaktionen sind, wie soll man etwas zurück rollen?

Auf der anderen Seite, eine explizite Transaktion über die Orchestrierung Einführung macht es trivial Änderungen rückgängig zu machen:

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 
} 

Die TransactionScope ist recht praktisch, da es richtig sowohl eine Transaktion auf einem gemeinsamen UOW und eine Transaktion behandeln soll über mehrere verschiedene UoWs in verschiedene Dienste injiziert.

Was ist, wenn service2.Save fehlschlägt?

Sie Rollback der Transaktion, es gibt kaum eine andere Option hier.

Wie auch immer, repositories/uow over EF are disputable. Teil Ihres Problems ist, dass mehrere Dienste die gleiche Instanz der UoW ​​teilen, also ist es grundsätzlich egal, welche Save Sie anrufen, rufen sie alle SaveChanges auf der gleichen DbContext.

Meine Meinung (obwohl Meinungen hier vermieden werden sollten) ist, dass Sie möglicherweise Save s von Ihren Diensten fallen und mit dem einzigen SaveChanges auf Ihrem DB-Kontext am Ende der Orchestrierung bleiben können. Dies würde die Intention klarer machen - Dienste sollen den internen Zustand der UOW verändern, aber die Verantwortung, Änderungen beizubehalten, liegt beim Controller.

+0

Über Ihren letzten Absatz: Sie würden nicht SaveChanges auf DB Kontext direkt von der Steuerung aufrufen, würden Sie? Ich meine, sollte es nicht abstrahiert werden? – brinch

+1

Das würde wirklich davon abhängen, ob ich den DbContext zur Hand haben würde. Wenn nicht (z. B. wird es von einem DI-Container injiziert und Sie sehen es nicht irgendwo im Controller) würde ich 'Save' auf einem der Dienste aufrufen. –

Verwandte Themen