2010-12-04 16 views
5

Tengo una cantidad de objetos que comparten una clase base común, deseo interceptar todas las llamadas que establecen valores de propiedad y registrar si se han establecido por instancia.Reemplazar el método Property Setter en tiempo de ejecución

¿Puedo reemplazar el método de configuración de una propiedad en tiempo de ejecución con Reflection?

Respuesta

6

Un enfoque que hay que hacer que la propiedad virtual y en tiempo de ejecución crear una subclase través de la reflexión-emiten que modifique las propiedades, añadiendo su código. Sin embargo, esto es avanzado, y requiere que siempre se asegure de crear la subclase (para que no haya "nuevo" en el código).

Sin embargo; Me pregunto si simplemente implementar INotifyPropertyChanged y manejar el evento es más simple. La otra opción es simplemente construir el manejo en la clase regular en primer lugar. Hay algunas maneras de hacer esto menos repetitivo, especialmente si usted tiene una clase base común donde se puede añadir un

protected void SetField<T>(ref T field, T value) 
{ 
    if(!EqualityComparer<T>.Default.Equals(field,value)) 
    { 
     field = value; 
     // extra code here 
    } 
} 

Con

private int foo; 
public int Foo { 
    get { return foo; } 
    set { SetField(ref foo, value); } 
} 
+0

Esto está muy cerca de lo que tengo ahora, gracias. Esto realmente hace el trabajo pero significa que tengo que interceptar manualmente todas las llamadas. – IanNorton

1

Si su clase base deriva de ContextBoundObject puede crear sus objetos en un Contexto diferente (dentro del mismo AppDomain) y llamadas a métodos de interceptación (que son las propiedades) e inserte su propio receptor de mensajes en la cadena de sumidero remoto.

heres un ejemplo

http://www.codeproject.com/KB/cs/aspectintercept.aspx

+0

El artículo es realmente excesivo pero destaca que se puede hacer, intentaré esto, pero sin los atributos. Gracias, publicaré algunas actualizaciones cuando sepa más. – IanNorton

0

No se puede reemplazar directamente en tiempo de ejecución. Si la propiedad es virtual, puede usar un DynamicProxy como Castle http://www.castleproject.org/dynamicproxy/index.html , para crear un tipo de proxy para usted que amplíe su tipo y su fábrica se puede utilizar para obtener una clase que tenga una manera de interceptar sus métodos.

También puede ir por la ruta ContextBoundObject, o Enterprise Libaries Policy Injection. http://msdn.microsoft.com/en-us/library/cc511729.aspx

Advertencia: ContextBoundObject es mucho más lento que el proxy dinámico de Castle, pero no tiene que declarar sus métodos como virtuales. Inyección de política solo le permite insertar antes o después de los avisos de invocación, por lo que no puede detener la invocación si está en contra de ella por cualquier motivo.

Si puede hacer esto como un paso de compilación de publicaciones, puede usar PostSharp o Mono.Cecil.

Personalmente estoy trabajando en mi propio Dynamic Proxy que permite reemplazar los métodos con Delegates, pero no está listo para la luz de lima.

Cuestiones relacionadas