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 ?

Roubachof
  • 3,351
  • 3
  • 23
  • 34

1 Answers1

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

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • wow, that's disappointing... Unfortunately, PostSharp is not free, and its licensing policy is quite painful. – Roubachof Dec 20 '10 at 13:17
  • 1
    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 describe – Krzysztof Kozmic Dec 20 '10 at 13:49
  • Thanks! Class proxy is doing the job. Interfaces in our case weren't that important, so we dropped them. – Roubachof Dec 20 '10 at 15:46