tag route page net data asp all c# aop dnx .net-core

c# - route - ¿RealProxy en dotnet core?



forms asp net core (3)

Puede usar System.Reflection.DispatchProxy o sus propias implementaciones de decorador simple. Consulte la página de patrones de Decorator en Wikipedia para ver ejemplos de implementación.

Actualmente en .NET Core no puedes usar la inyección de constructor con DispatchProxy . DispatchProxy.Create() utilizar el método de fábrica DispatchProxy.Create() y la inyección de propiedades con conversión explícita al tipo de proxy que desea usar. Para obtener más información, consulte DispachProxyTest.cs en el repositorio de .NET Core GitHub.

Este es un ejemplo de un decorador genérico simple que hereda DispatchProxy :

class GenericDecorator : DispatchProxy { public object Wrapped { get; set; } public Action<MethodInfo, object[]> Start { get; set; } public Action<MethodInfo, object[], object> End { get; set; } protected override object Invoke(MethodInfo targetMethod, object[] args) { Start?.Invoke(targetMethod, args); object result = targetMethod.Invoke(Wrapped, args); End?.Invoke(targetMethod, args, result); return result; } }

Y su uso:

class Program { static void Main(string[] args) { IEcho toWrap = new EchoImpl(); IEcho decorator = DispatchProxy.Create<IEcho, GenericDecorator>(); ((GenericDecorator)decorator).Wrapped = toWrap; ((GenericDecorator)decorator).Start = (tm, a) => Console.WriteLine($"{tm.Name}({string.Join('','', a)}) is started"); ((GenericDecorator)decorator).End = (tm, a, r) => Console.WriteLine($"{tm.Name}({string.Join('','', a)}) is ended with result {r}"); string result = decorator.Echo("Hello"); } class EchoImpl : IEcho { public string Echo(string message) => message; } interface IEcho { string Echo(string message); } }

Estoy trabajando con los espacios de nombres System.Runtime.Remoting.Proxies y System.Runtime.Remoting.Messaging para AOP en C #. Estoy tratando de portar mi aplicación desde .Net Framework 4.6 a dnxcore / dotnet core.

Intellisense dice que estos dos espacios de nombres no están disponibles con mi framework-vesion (netcoreapp1.0 / dnxcore50). ¿Alguna idea de si aparecerán estos dos espacios de nombres? ¿O alguna idea de cómo obtener el AOP como con la clase RealProxy ?

No quiero usar bibliotecas de terceros, solo quiero usar lo que .Net me ofrece.


También puede utilizar una combinación de Autofac y DynamicProxy. Este artículo tiene una buena introducción y ejemplos sobre cómo lograrlo.

AOP en .Net Core


Parece que RealProxy no llegará a .NET Core / Standard . En el problema, un desarrollador de Microsoft sugiere DispatchProxy como una alternativa.

Además, algunos marcos AOP existentes pueden admitir .NET Core ya sea o en el futuro (como se ve en los comentarios sobre la pregunta).

Una alternativa es DispatchProxy , que tiene un maravilloso ejemplo aquí: http://www.c-sharpcorner.com/article/aspect-oriented-programming-in-c-sharp-using-dispatchproxy/ .

Si simplificamos el código, esto es lo que obtenemos:

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

Entonces, si tenemos una Calculator clase de ejemplo con una interfaz correspondiente (no se muestra aquí):

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

Simplemente podemos usarlo así

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