Перехват методов, вызываемых средством Startable с Castle Windsor 3.0 - PullRequest
3 голосов
/ 05 января 2012

Я использую Castle Windsor 3.0.

У меня есть компонент, который должен запускаться автоматически после фазы регистрации. Я также хотел бы перехватывать исключения из методов Start / Stop и регистрировать их детали.

Чтобы сделать мой компонент запускаемым, я использовал средство запуска, которое идет в комплекте с Windsor:

container.AddFacility<StartableFacility>(f => f.DeferredStart());

Я создал собственный перехватчик, подобный этому:

class ExceptionLoggerInterceptor : IInterceptor
{
    IExceptionLogger m_ExceptionLogger;

    public ExceptionLoggerInterceptor(IExceptionLogger exceptionLogger)
    {
        if (exceptionLogger == null)
            throw new ArgumentNullException("exceptionLogger");

        m_ExceptionLogger = exceptionLogger;
    }

    public void Intercept(IInvocation invocation)
    {
        try
        {
            invocation.Proceed();
        }
        catch (Exception ex)
        {
            m_ExceptionLogger.Write(ex, invocation.Method.Name, invocation.TargetType.Name);
        }
    }
}

и я зарегистрировал компонент следующим образом:

Component.For<IExceptionLogger>()
 .ImplementedBy<EnterpriseLibraryExceptionLogger>()
 .LifeStyle.Singleton,

Component.For<ExceptionLoggerInterceptor>()
 .LifeStyle.Singleton,

Component.For<IWorkflowService>()
 .ImplementedBy<WorkflowService>()
 .LifeStyle.Singleton
 .StartUsingMethod(c => c.Start)
 .StopUsingMethod(c => c.Stop)
 .Interceptors(InterceptorReference.ForType<ExceptionLoggerInterceptor>()).Anywhere

Для проверки я кодировал грязный

throw new Exception(); 

в реализации метода Start компонента. На этапе регистрации, когда Windsor автоматически вызывает метод Start для компонента, генерируется исключение, но он никогда не перехватывается моим пользовательским перехватчиком.

Я провел еще один тест, на этот раз, не используя средство Startable, а скорее вызвав метод Start вручную. Исключение было выдано и было перехвачено моим пользовательским перехватчиком.

Итак, как следует из заголовка этого поста, есть ли способ перехватить методы, вызываемые средством Startable с помощью Windsor?

Привет

Луи-Пьер Бомон

1 Ответ

2 голосов
/ 10 января 2012

Я собираюсь частично ответить на свой вопрос:

Я не нашел способа перехватить метод Start в компоненте при использовании средства Startable.Похоже, что объект использует не прокси, созданный для объекта для выполнения вызова, а сам объект.

Специальная статья представляет проблему здесь .

В любом случае, я быстро понял, что выполнение AOP с объектами Proxy имеет свои ограничения.Вот почему я перешел в SheepAspect, IL-Weaving AOP Framework.

Я смешал SheepAspect с Castle Windsor, и теперь, когда метод Start моего компонента вызывается средством Castle Startable, все мои аспекты также называются!

Вот как я написал свой ExceptionAspect сSheepAspect:

[SingletonAspect]
public class ExceptionAspect
{
    IExceptionLogger m_ExceptionLogger;

    public ExceptionAspect(IExceptionLogger exceptionLogger)
    {
        if (exceptionLogger == null)
            throw new ArgumentNullException("exceptionLogger");

        m_ExceptionLogger = exceptionLogger;
    }

    [SelectTypes(typeof(WorkflowService))]
    void Targets() { }

    [Around("Execute")]
    [SelectMethods("Name:('Start') & InType:@Targets")]
    public void Execute(MethodJointPoint jp)
    {
        object result = null;

        try
        {
            result = jp.Execute();
        }
        catch (Exception ex)
        {
            m_ExceptionLogger.Write(ex, jp.Method.Name, jp.Method.ReflectedType.Name);
        }

        return result;
    }
}
...