开发者

Replace Property Setter method at runtime

开发者 https://www.devze.com 2023-01-29 07:35 出处:网络
I have a number of objects that all share a common base class, I wish to intercept开发者_如何学编程 all calls that set Property values and record if these have been set on a per instance basis.

I have a number of objects that all share a common base class, I wish to intercept开发者_如何学编程 all calls that set Property values and record if these have been set on a per instance basis.

Can I replace the Set Method of a Property at runtime with Reflection?


One approach there is to make the property virtual, and at runtime create a subclass via reflection-emit that override the properties, adding your code. However, this is advanced, and requires you always make sure to create the subclass (so no "new" in code).

However; I wonder if simply implementing INotifyPropertyChanged and handling the event is simpler. The other option is to just build the handling into the regular class in the first place. There are some ways of making this less repetitive, especially if you have a common base-class where you could add a

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

With

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


If your base class derives from ContextBoundObject you can create your objects in a different Context (within the same AppDomain) and intercept method calls (which is what properties are) and insert your own message sink into the remoting sink chain.

heres one example

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


You cannot directly replace it at runtime. If the property is virtual, you can use a DynamicProxy like Castle's http://www.castleproject.org/dynamicproxy/index.html , to create a proxy type for you that extends your type and it's factory can be used to get a class that has a way to intercept it's methods.

Alternatively you can go down the ContextBoundObject route, or Enterprise Libaries Policy Injection. http://msdn.microsoft.com/en-us/library/cc511729.aspx

Be warned ContextBoundObject is much slower than Castle's dynamic proxy, but you don't have to declare your methods virtual. Policy Injection only allows you to insert before or after invocation advices, so you can't stop the invocation if you are against it for whatever reason.

If you can deal with doing this as a post compilation step you can use either PostSharp or Mono.Cecil.

I'm personally working on my own Dynamic Proxy that allows replacing methods with Delegates, but its not nearly ready for the lime light.

0

精彩评论

暂无评论...
验证码 换一张
取 消