Intercepting method called from a method of the same object
Asked Answered
A

1

0

Here's the situation:

/// <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 });
    }
}

With castle windsor, this class is configured to be intercepted with this interceptor:

/// <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);
    }
}

The issue takes place during the call to InsertNormande. The call to InsertNormande is well intercepted, but the call to DisplayAllCows in InsertNormande is not intercepted...

It really bothers me.

Is there a way to achieve interception in this scenario ?

Avestan answered 20/12, 2010 at 11:20 Comment(0)
M
0

I don't think there's an easy way of doing it... method calls that are internal to the class can't be intercepted, since they don't go through the proxy.

You could achieve logging of all methods by other means, such as an AOP framework like PostSharp

Me answered 20/12, 2010 at 12:34 Comment(3)
wow, that's disappointing... Unfortunately, PostSharp is not free, and its licensing policy is quite painful.Avestan
Mostly true. You actually can intercept calls on the same objects, but only for class proxy (provided the method is virtual). Interface proxies are created by wrapping proxy target object, so as Thomas pointed out they are not really targeted towards scenarios like the one you describeVestryman
Thanks! Class proxy is doing the job. Interfaces in our case weren't that important, so we dropped them.Avestan

© 2022 - 2024 — McMap. All rights reserved.