【问题标题】:Intercepting method called from a method of the same object拦截从同一对象的方法调用的方法
【发布时间】:2010-12-20 20:34:36
【问题描述】:

情况如下:

/// <summary>
/// A business logic class.
/// </summary>
public class BusinessClassWithInterceptor : BusinessClass, IBusinessClass
{
    /// <summary>
    /// Initializes a new instance of the <see cref="BusinessClassWithoutInterceptor"/> class.
    /// </summary>
    /// <param name="logger">The logger.</param>
    public BusinessClassWithInterceptor(Logger logger)
        : base(logger)
    {
    }

    /// <summary>
    /// Displays all cows.
    /// </summary>
    public void DisplayAllCows()
    {
        this.Logger.Write("Displaying all cows:");
        var repository = new CowRepository();
        foreach (CowEntity cow in repository.GetAllCows())
        {
            this.Logger.Write("    " + cow);
        }
    }

    /// <summary>
    /// Inserts a normande.
    /// </summary>
    public void InsertNormande(int id, string name)
    {
        this.DisplayAllCows();

        var repository = new CowRepository();
        repository.InsertCow(new CowEntity { Id = id, Name = name, Origin = CowOrigin.Normandie });
    }
}

使用城堡温莎,这个类被配置为用这个拦截器拦截:

/// <summary>
/// Interceptor for logging business methods.
/// </summary>
public class BusinessLogInterceptor : IInterceptor
{
    /// <summary>
    /// Intercepts the specified invocation.
    /// </summary>
    /// <param name="invocation">The invocation.</param>
    public void Intercept(IInvocation invocation)
    {
        Logger logger = ((IBusinessClass)invocation.InvocationTarget).Logger;

        var parameters = new StringBuilder();
        ParameterInfo[] methodParameters = invocation.Method.GetParameters();
        for (int index = 0; index < methodParameters.Length; index++)
        {
            parameters.AppendFormat("{0} = {1}", methodParameters[index].Name, invocation.Arguments[index]);
            if (index < methodParameters.Length - 1)
            {
                parameters.Append(", ");
            }
        }

        logger.Format("Calling {0}( {1} )", invocation.Method.Name, parameters.ToString());
        invocation.Proceed();
        logger.Format("Exiting {0}", invocation.Method.Name);
    }
}

问题发生在调用 InsertNormande 期间。 对InsertNormande的调用被很好的拦截了,但是在InsertNormande中对DisplayAllCows的调用没有被拦截...

这真的让我很困扰。

有没有办法在这种情况下实现拦截?

【问题讨论】:

    标签: c# castle-windsor aop


    【解决方案1】:

    我不认为有一种简单的方法可以做到这一点......类内部的方法调用无法被拦截,因为它们不通过代理。

    您可以通过其他方式实现所有方法的日志记录,例如像PostSharp这样的AOP框架

    【讨论】:

    • 哇,太令人失望了……不幸的是,PostSharp 不是免费的,而且它的许可政策相当痛苦。
    • 大部分是真的。您实际上可以拦截对相同对象的调用,但仅限于类代理(前提是该方法是虚拟的)。接口代理是通过包装代理目标对象创建的,因此正如 Thomas 指出的那样,它们并不是真正针对您描述的场景
    • 谢谢!类代理正在做这项工作。在我们的例子中,接口并不那么重要,所以我们放弃了它们。
    猜你喜欢
    • 1970-01-01
    • 2011-10-21
    • 2014-10-11
    • 2021-09-16
    • 1970-01-01
    • 2012-04-01
    • 1970-01-01
    • 2015-08-14
    相关资源
    最近更新 更多