Ранее я писал про механизмы 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

Теги : Unity, .NET, AOP