2011-05-29 14 views

Respuesta

0

La técnica que está buscando se llama AOP - Programación Orientada a Aspectos. Puedes encontrar varios frameworks para C# si haces un poco de goggle.

actualización: Usted puede encontrar un montón de enlaces y la información en esta pregunta: Built-in AOP in C# - is it on the way?

+0

He buscado en Google y no puedo encontrar nada, ¿pueden señalarme en la dirección correcta? – Avery3R

+0

Actualizado con el enlace. –

+0

Nada de esto se parece a lo que quiero, estoy buscando una manera de interceptar una función cada vez que se llama y ejecutar mi propio código, y ejecutar opcionalmente el código original – Avery3R

2

¿Quieres conectar en tiempo de ejecución o quieres parchear el binario?

para enganchar en tiempo de ejecución puede utilizar la API de perfiles (relativamente difícil): http://msdn.microsoft.com/en-us/magazine/cc188743.aspx

Para gancho en tiempo de compilación puede utilizar un rewriter IL, tal como PostSharp.

+0

Quiero enlazar en tiempo de ejecución, pero la API de creación de perfiles parece que está en C++, quiero conectar un C# función de C# – Avery3R

+0

Suena problemático ya que está manipulando la misma trepidación que necesita para compilar su propio código C#. Tal vez una envoltura administrada y varios dominios de aplicación pueden ayudar. Pero eso parece ser más problemático que mezclar C/C++ nativo con C#. – CodesInChaos

7

.NET Profiler API es la forma más cercana "aprobada por Microsoft" de interceptar métodos en tiempo de ejecución. Como ya se mencionó, esto es algo difícil de implementar y no conozco una biblioteca que lo haga fácil de implementar usando un código puramente administrado.

Al investigar las opciones para este yo hace unos meses, tropecé con CLR Method Injection, que es un artículo con código fuente que explica cómo interceptar métodos en tiempo de ejecución. Consideré usarlo yo mismo, e incluso tuve el proyecto de muestra funcionando, pero finalmente concluí que necesitaba algo más que la interceptación del método y necesitaría una solución diferente. Sin embargo, este enfoque responde directamente a su pregunta.

Por último, lo que terminó haciendo fue desarrollar Afterthought como una alternativa de código abierto a PostSharp, que se ejecuta como un paso posterior a la compilación y le permite modificar los métodos existentes para llamar a otro código, o reemplazar las implementaciones de métodos por completo. Estoy trabajando ahora en una nueva sintaxis fluida, que voy a incluir una muestra de ahora para proporcionar un ejemplo para ayudarle a ver cómo este enfoque AOP podría satisfacer sus necesidades:

Methods 
    .Named("Sum") 
    .WithParams<int[]>() 
    .Before((T instance, ref int[] values) 
     => { var s = new Stopwatch(); s.Start(); return s; }) 
    .After((instance, stopwatch, values) 
     => instance.Result = (int)stopwatch.ElapsedMilliseconds); 

En este caso, mientras se modifica una ya existente escriba con un método Sum Estoy introduciendo código antes y después del método para medir el tiempo de ejecución. Después de ejecutar Afterthought contra la clase compilada original, el método Sum resultante tendría llamadas a estas expresiones lambda (el compilador de C# simplemente las convierte en métodos estáticos) antes y después del cuerpo del método. Podría haber llamado Implement y haber reemplazado toda la implementación del método.

Espero que uno de estos enfoques satisfaga sus necesidades. En mi caso, fui a la ruta AOP porque quería hacer algo más que interceptar, como implementar interfaces, agregar nuevos métodos/propiedades, etc. También quería algo que no introdujera dependencias en el tiempo de ejecución o preocupaciones sobre la estabilidad o el rendimiento en el entorno de tiempo de ejecución: el procesamiento en tiempo de compilación es más seguro y más fácil de probar.

+0

¿Pensaría que funcionaría si la función que estoy enganchando está en otro ensamblaje, que no tengo el código fuente? – Avery3R

+0

Sí. La idea posterior funciona de manera un poco diferente de PostSharp, ya que le permite crear enmiendas (como la anterior, una descripción del código de sus cambios) en un ensamblaje y apuntar a otro ensamblaje para aplicar los cambios. Eche un vistazo al [Ejemplo de registro] (https://github.com/vc3/Afterthought/tree/master/Examples/Logging). Describe las modificaciones en el ensamblaje Logging.Amender, que luego se aplican al ensamblado Logging.UnitTest.Target. Esto también tiene la ventaja de permitirle modificar un ensamblaje sin establecer una referencia a Afterthought en sí mismo, convirtiéndolo en solo una herramienta. –

+0

¿Afterthought usa la interceptación de .NET Profiler? Estoy buscando una herramienta que lo haga – orellabac

Cuestiones relacionadas