Перехватывать Unity 2.0 HandlerAttribute без интерфейса - PullRequest
2 голосов
/ 02 сентября 2010

Я впервые пользуюсь функциями AOP в Unity 2.0 и хотел бы получить совет. Моя цель - записывать вызовы методов на странице ASPX, например:

public partial class Page2 : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        [Log]
        private void Testing()
        {

        }
    }

Вот код для LogAttribute:

public class LogAttribute : HandlerAttribute
{
    public override ICallHandler CreateHandler(IUnityContainer container)
    {
        return new LogHandler(Order);
    }
}

Теперь LogHandler:

public class LogHandler : ICallHandler
{
    public LogHandler(int order)
    {
        Order = order;
    }

    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        string className = input.MethodBase.DeclaringType.Name;
        string methodName = input.MethodBase.Name;

        string preMethodMessage = string.Format("{0}.{1}", className, methodName);
        System.Diagnostics.Debug.WriteLine(preMethodMessage); 

        return getNext()(input, getNext);
    }

    public int Order { get; set; }
}

У меня проблема в том, как использовать атрибут [Log]. Я видел множество примеров того, как настроить параметры перехвата, например:

container.AddNewExtension<Interception>();
container.Configure<Interception>().SetDefaultInterceptorFor<ILogger>(new InterfaceInterceptor());

Но это означает, что у меня есть интерфейс для перехвата, чего у меня нет. У меня есть страница ASPX, которая использует атрибут [Log].

так, как я могу настроить Unity для использования атрибута [Log]? Я сделал это перед использованием PostSharp и хотел бы иметь возможность использовать Unity для того же.

Приветствия. Иак.

1 Ответ

6 голосов
/ 03 сентября 2010

К сожалению, вы не сможете заставить это работать на странице ASP.NET с перехватом Unity.

Перехват Unity использует модель перехвата во время выполнения. В зависимости от выбранного вами перехватчика вы получите либо подкласс с переопределениями виртуальных методов для вызова обработчиков вызовов (VirtualMethodInterceptor), либо отдельный прокси-объект (Interface или TransparentProxyInterceptor), которые выполняют обработчики вызовов и затем пересылаются к реальному объекту.

Вот в чем проблема - ASP.NET контролирует создание и вызовы на вашу страницу, и нет простого способа подключиться к ним. Без управления созданием объекта страницы вы не можете использовать VirtualMethodInterceptor, потому что для этого необходимо создать экземпляр подкласса. И вы также не можете использовать версию прокси, потому что вам нужен ASP.NET для звонков через прокси.

PostSharp справляется с этим, потому что фактически переписывает ваш IL во время компиляции.

Предполагая, что вы можете подключиться к созданию объекта страницы, вам придется использовать VirtualMethodInterceptor здесь. Это закрытый метод, поэтому вы хотите войти в систему "самостоятельных" вызовов (вызовы из одного метода объекта в другой метод того же объекта). Перехватчики на основе прокси не могут их видеть, поскольку прокси - это отдельный экземпляр.

Я предполагаю, что где-то есть ловушка для настройки того, как ASP.NET создает объект - может быть, BuildManager? Но я не знаю достаточно о деталях, и я ожидаю, что потребуется довольно серьезный взлом, чтобы получить работу.

Итак, как вы справляетесь с этим? Моя рекомендация (на самом деле я бы порекомендовал это в любом случае) - использовать шаблон Model-View-Presenter для ваших страниц ASP.NET. Сделайте объект страницы самим тупым. Все, что он делает, это переадресация вызовов на отдельный объект, Presenter. Presenter - это то, где находится ваша настоящая логика, и он не зависит от деталей ASP.NET. Вы получаете огромный выигрыш в тестируемости и можете перехватывать звонки на докладчике безо всяких трудностей, которые дает вам ASP.NET.

...