Replace Property Setter method at runtime

岁酱吖の 提交于 2020-01-03 13:33:47

问题


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?


回答1:


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



回答2:


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




回答3:


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.



来源:https://stackoverflow.com/questions/4352537/replace-property-setter-method-at-runtime

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!