2016-09-12 7 views
2

Я работаю (поддерживаю) на сборке dll, которая действует как уровень доступа к данным, существует много методов, требующих обработки транзакций, а многие другие нет, это в настоящее время " функциональной "dll, без какого-либо метода обработки транзакций, мне нужно добавить его, поэтому я ищу простой способ добавления обработчика транзакций.Как создать декоратор аспекта для обработки транзакций EF

Мне интересно, можно ли использовать АОП для создания декоратора, который я могу добавить к методам, требующим транзакции.

Я хотел бы иметь что-то вроде этого:

[Transaction] 
void MyDbMethod() 
{ 
    //DoSomething 
    myContext.SaveChanges(); 
} 

Для определения EF модели я использую Code First, текущий проект использует рамки Unity для некоторых других задач Д.И., может эта структура будет использоваться для это?

+0

Возможно смотреть на это http://stackoverflow.com/questions/13211261/using-attributes-to -call-methods, то вы можете проверить 'System.Transactions.Transaction.Current! = null' и решить продолжить или нет. – Wurd

ответ

1

Если кто-то сталкивается с этим же вопросом, я не нашел какое-либо «вручную» решения, вместо этого я использовал PostSharp библиотеки и ее класс OnMethodBoundaryAspect, но будьте осторожны, в этот момент свободен/экспресс лицензия имеет ограничение по поводу количество классов, где вы можете его использовать, поэтому внимательно прочитайте его ограничения.

using System.Transactions; 
using PostSharp.Aspects; 
using PostSharp.Serialization; 

namespace MyProject 
{ 
    [PSerializable] 
    public class Transaction : OnMethodBoundaryAspect 
    { 
     public Transaction() 
     { 
      //Required if the decorated method is async 
      ApplyToStateMachine = true; 
     } 

     public override void OnEntry(MethodExecutionArgs args) 
     { 
      //TransactionScopeAsyncFlowOption.Enabled => Required if the decorated method is async 
      var transactionScope = new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled); 
      args.MethodExecutionTag = transactionScope; 
     } 

     public override void OnSuccess(MethodExecutionArgs args) 
     { 
      var transactionScope = (TransactionScope)args.MethodExecutionTag; 
      transactionScope.Complete(); 
     } 

     public override void OnExit(MethodExecutionArgs args) 
     { 
      var transactionScope = (TransactionScope)args.MethodExecutionTag; 
      transactionScope.Dispose(); 
     } 
    } 
} 
1

Вы можете сделать это, используя NConcern .NET AOP Framework.

Это среда AOP с открытым исходным кодом, на которой я активно работаю.

public class DataAccessLayer : IAspect 
{ 
    public IEnumerable<IAdvice> Advise(MethodInfo method) 
    { 
     //define how to rewrite method 
     yield return Advice.Basic.Arround(invoke => 
     { 
      using (var transaction = new TransactionScope(...)) 
      { 
       invoke(); //invoke original code 
       transaction.Complete(); 
      } 
     }); 
    } 
} 

Ваш бизнес

public class MyBusiness 
{ 
    [Transaction] 
    void MyDbMethod() 
    { 
    } 
} 

Приложить сделки области видимости аспект вам бизнес

Aspect.Weave<DataAccessLayer>(method => method.IsDefined(typeof(TransactionAttribute), true); 
+0

Не знал об этом проекте, кажется довольно приятной «стартовой» альтернативой postharp и fody. На странице упоминается, что она выполняет переплетение во время выполнения; как это влияет на производительность в сравнении со временем компиляции или с помощью двоичных файлов с Cecil? – easuter

+1

Спектакль в основном изменяется в «время огня» не в номинальное время. В моем собственном бенчмарке он может быть быстрее, чем PostSharp в номинальном использовании. –

+0

Приятно слышать; Я вроде как искал что-то подобное, так как Postsharp является чрезмерно дорогим, а расширения Fody имеют очень непоследовательное качество. Спасибо, что нашли время, чтобы опубликовать здесь! :) – easuter