2017-09-04 1 views
15

Ich migriere meine Anwendung von .NET Framework 4.5.1 auf Dot Net Core. Ich war RealProxy Klasse unter Verwendung für die Protokollierung von Benutzerinformationen und Parametern auf BeforeExecute und AfterExecute (wie diese link)AOP im Dotnet-Core: Dynamischer Proxy mit Real Proxy im Dotnet-Core

Nun scheint es, gibt es keine solche Sache in Dot core.Plus Ich will nicht dritten parties.I verwenden fand diese link, die Actionfilter verwendet, aber es wird nicht den Job machen.

meine Frage ist Wie kann ich dynamische Proxy in Dot net-Core implementieren? Gibt es eine Alternative für die RealProxy-Klasse?

Antwort

0

Wie ich bereits in RealProxy in dotnet core? beantwortet, hat Realproxy nicht in .NET-Core existieren. Eine Alternative ist die DispatchProxy, die hier ein wunderbares Beispiel hat: http://www.c-sharpcorner.com/article/aspect-oriented-programming-in-c-sharp-using-dispatchproxy/.

Wenn wir den Code zu vereinfachen, ist es das, was wir bekommen:

public class LoggingDecorator<T> : DispatchProxy 
{ 
    private T _decorated; 

    protected override object Invoke(MethodInfo targetMethod, object[] args) 
    { 
     try 
     { 
      LogBefore(targetMethod, args); 

      var result = targetMethod.Invoke(_decorated, args); 

      LogAfter(targetMethod, args, result); 
      return result; 
     } 
     catch (Exception ex) when (ex is TargetInvocationException) 
     { 
      LogException(ex.InnerException ?? ex, targetMethod); 
      throw ex.InnerException ?? ex; 
     } 
    } 

    public static T Create(T decorated) 
    { 
     object proxy = Create<T, LoggingDecorator<T>>(); 
     ((LoggingDecorator<T>)proxy).SetParameters(decorated); 

     return (T)proxy; 
    } 

    private void SetParameters(T decorated) 
    { 
     if (decorated == null) 
     { 
      throw new ArgumentNullException(nameof(decorated)); 
     } 
     _decorated = decorated; 
    } 

    private void LogException(Exception exception, MethodInfo methodInfo = null) 
    { 
     Console.WriteLine($"Class {_decorated.GetType().FullName}, Method {methodInfo.Name} threw exception:\n{exception}"); 
    } 

    private void LogAfter(MethodInfo methodInfo, object[] args, object result) 
    { 
     Console.WriteLine($"Class {_decorated.GetType().FullName}, Method {methodInfo.Name} executed, Output: {result}"); 
    } 

    private void LogBefore(MethodInfo methodInfo, object[] args) 
    { 
     Console.WriteLine($"Class {_decorated.GetType().FullName}, Method {methodInfo.Name} is executing"); 
    } 
} 

Wenn wir also ein Beispiel Klasse Calculator mit einer entsprechenden Schnittstelle (hier nicht dargestellt):

public class Calculator : ICalculator 
{ 
    public int Add(int a, int b) 
    { 
     return a + b; 
    } 
} 

können wir verwenden Sie es einfach so

static void Main(string[] args) 
{ 
    var decoratedCalculator = LoggingDecorator<ICalculator>.Create(new Calculator()); 
    decoratedCalculator.Add(3, 5); 
    Console.ReadKey(); 
} 

Und Sie erhalten die gewünschte Protokollierung.

+1

"Wie ich bereits in ... antwortete" Warum hast du die Frage dann nicht als Duplikat markiert? –

Verwandte Themen