Ранее я писал про механизмы AOP в Unity 1.0 (или 1.2 на тот момент). Недавно увидел этот пост, с примером для Unity 2.0.
В первой версии было фактически две возможности для задания перехватчиков вызовов: это атрибуты на классах или сложный код (или xml), задающий условия по которым будут срабатывать обработчики вызовов.
Оба варианта довольно плохие, первый заставляет править существующий код, второй просто неподъемный. В Unity 2.0 исправили ситуацию с помощью так называемых InterceptionBehavior.
Пример кода из поста в новом стиле.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Practices.Unity; using Microsoft.Practices.Unity.InterceptionExtension; using System.Transactions; namespace Unity20Interception { public interface IAccountService { // Хотим чтобы метод Withdraw выполнялся под транзакцией, // Но ничего помечать не будем. void Withdraw(decimal amount); } public class AccountService : IAccountService { public void Withdraw(decimal amount) { if (amount < 0 || amount > 1000) throw new ArgumentOutOfRangeException("amount"); } } //Собственно класс обработчика вызовов public class TransactionBehavior: IInterceptionBehavior { #region IInterceptionBehavior Members public IEnumerable<Type> GetRequiredInterfaces() { return Enumerable.Empty<Type>(); } public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) { using (TransactionScope transaction = new TransactionScope()) { var result = getNext()(input, getNext); if (result.Exception == null) { // исключений не возникло, завершим транзакцию transaction.Complete(); Console.WriteLine("Transaction commited"); } return result; } } public bool WillExecute { get { return true; } } #endregion } class Program { static void Main(string[] args) { var container = new UnityContainer().AddNewExtension<Interception>(); container .RegisterType<IAccountService, AccountService>( //Устанавливаем способ перехвата new Interceptor<InterfaceInterceptor>(), //Устанавливаем обработчик new InterceptionBehavior<TransactionBehavior>() ); var service = container.Resolve<IAccountService>(); service.Withdraw(33); // транзакция пройдет успешно service.Withdraw(-6); } }
Также новых механизм перехвата позволяет добавлять к сгенерированному классу-перехватчику необходимые интерфейсы. Например можно сделать таким образом behavior, который добавляет реализацию INotifyPropertyChanged.
http://msdn.microsoft.com/en-us/library/ff660851(v=PandP.20).aspx