2011-01-15 4 views
0

In einer Service-Klasse mit Spring.NET konfiguriert. DoWork unterstützt zwei Aufgaben, die in zwei Transaktionen ausgeführt werden sollten. Aber Spring.NET scheint kein Transaktions-AOP-Verhalten aufzurufen. Ich muss DoWork() mit dem Transaktionsattribut kommentieren, aber das würde beide Aufgaben in eine Transaktion einbinden, die ich nicht möchte. Wie kann ich das Problem lösen?spring.net-Transaktionsattribut funktioniert nur für Methoden, die von außerhalb aufgerufen werden

IMyService service.DoWork(); 

public class MyServiceImpl : IMyService 
{ 

public DoWork() 
{ 
    Task1(); 
    Task2(); 
} 

[Transaction(ReadOnly=false)] 
protected void Task1() 
{ 
    // do it 
} 

[Transaction(ReadOnly=false)] 
protected void Task2() 
{ 
    // do it 
} 
} 
+0

Related to [diese ähnliche Frage] (http://stackoverflow.com/questions/4280143/asp-net-mvc-controller-declarative-aop-with-spring-net/4346791#4346791) antwortete ich vor einem Monat. Die Antwort von A. ist korrekt und die verknüpfte Antwort gibt Ihnen möglicherweise weitere Hintergrundinformationen. – Marijn

Antwort

2

Wie ich sehe here wird Spring.NET über eine Schnittstelle basierte dynamischen proxying seine "AOP-ness" zu erreichen. Schnittstellenbasierte Proxys funktionieren wie decorator pattern. Task1 und Task2 Methoden sind keine Bestandteile der Schnittstelle. Daher kann Spring.NET Aufrufe dieser Methoden nicht dekorieren, sodass kein Verhalten angewendet werden kann.

Ändern Task1 und Task2 an öffentlichen und es an die Schnittstelle hinzugefügt wird auch nicht in Ihrem Szenario helfen, wie DoWork Anrufe this.Task1() und this.Task2(), wo this für konkretes Objekt stehen, nicht ein AOP-Proxy.

Die einzige Lösung in Ihrem Szenario unterscheidet AOP Technik, entweder Basisklassenbasierte dynamisches proxying zur Laufzeit (ich weiß nicht, ob Spring.NET dies erlaubt, kann es also geschehen. Mit Unity Interception) verwenden oder kompilieren Weben (wie PostSharp).

+0

Es ist eine Lösung, aber nicht die _only_ Lösung. Außerdem scheint spring.net einen vererbungsbasierten Proxy von Version 1.3.1 zu unterstützen, der helfen könnte. – Marijn

1

A. stimmt mit seiner Beobachtung überein.

Allerdings würde ich empfehlen, die beiden Aufgaben in zwei separaten Klassen zu extrahieren, die in eine Klasse mit der DoWork() Routine injiziert werden.

public class MyServiceImpl : IMyService 
{ 
    // use property injection to set Task1 and Task2 
    public DoWork() 
    { 
    Task1.Process(); 
    Task2.Process(); 
    } 

} 

public class Task1 
{ 
    [Transaction(ReadOnly=false)] 
    protected void Process() 
    { 
    // do it 
    } 
} 

public class Task2 
{ 
    [Transaction(ReadOnly=false)] 
    protected void Process() 
    { 
    // do it 
    } 
} 
Verwandte Themen