2010-12-20 11 views
0

Hier ist die Situation:Intercepting Verfahren aus einem Verfahren des gleichen Objekts namens

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

Mit Schloss windsor, ist diese Klasse konfiguriert mit diesem Abfangjäger abgefangen zu werden:

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

Die Ausgabe erfolgt während des Anrufs zu InsertNormande. Der Aufruf von InsertNormande ist gut abgefangenen, aber der Aufruf von DisplayAllCows in InsertNormande abgefangen wird nicht ...

Es stört mich wirklich.

Gibt es eine Möglichkeit, in diesem Szenario Abfangen zu erreichen?

Antwort

0

Ich glaube nicht, dass es einen einfachen Weg gibt ... Methodenaufrufe, die intern in der Klasse sind, können nicht abgefangen werden, da sie nicht über den Proxy laufen.

Sie könnten Protokollierung aller Methoden mit anderen Mitteln, wie zum Beispiel ein AOP Framework wie PostSharp

+0

wow erreichen, dass enttäuschend ist ... Leider Postsharp ist nicht frei, und seine Lizenzpolitik ist sehr schmerzhaft. – Roubachof

+1

Meistens wahr. Sie können Aufrufe für die gleichen Objekte abfangen, jedoch nur für den Klassenproxy (sofern die Methode virtuell ist). Interface-Proxies werden durch das Wrapping des Proxy-Zielobjekts erstellt, so wie Thomas darauf hingewiesen hat, dass sie nicht auf Szenarien wie das von Ihnen beschriebene gerichtet sind. –

+0

Danke! Class Proxy macht die Arbeit. Schnittstellen in unserem Fall waren nicht so wichtig, also haben wir sie fallengelassen. – Roubachof

Verwandte Themen