C# 处理财产变更/通过Castle和#x27进行的财产变更;s DynamicProxy
我目前有一个setter方法,如下所示:C# 处理财产变更/通过Castle和#x27进行的财产变更;s DynamicProxy,c#,.net,inotifypropertychanged,castle,C#,.net,Inotifypropertychanged,Castle,我目前有一个setter方法,如下所示: private string _a; public virtual string A { get { return _a; } set { if (_a!= value) { if (this.OnPropertyChanging("A", _a, value)) {
private string _a;
public virtual string A
{
get { return _a; }
set
{
if (_a!= value)
{
if (this.OnPropertyChanging("A", _a, value))
{
var previousValue = _a;
_a = value;
this.OnPropertyChanged("A", previousValue, value);
}
}
}
}
我在Wily博士的徒弟的帮助下实现了这一点(http://stackoverflow.com/a/8578507/981225),具有跟踪旧值和当前值的自定义更改处理程序,以及将更改事件设置为“已取消”的功能,以便不会发生PropertyChange
这很好用。然而,我们有数百个属性,这是大量重复的代码
我过去曾使用Castle的DynamicProxy,以避免写“OnPropertyChanged(“A”)”
如何在这个setter中实现逻辑,作为代理的拦截方法的一部分?可能吗?谢谢。也许我有点晚了,但我在Linq到SharePoint模型中遇到了类似的任务。我草拟了一些代码,如果有人还在想的话
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Castle.DynamicProxy;
using System.Reflection;
using System.ComponentModel;
namespace DemoSpace
{
public abstract class EntityBase : INotifyPropertyChanged, INotifyPropertyChanging
{
public virtual void OnPropertyChanging(string propertyName, object value)
{
if ((null != PropertyChanging))
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
public virtual void OnPropertyChanged(string propertyName)
{
if ((null != PropertyChanged))
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangingEventHandler PropertyChanging;
}
public class DemoInterceptor<T> : IInterceptor where T : EntityBase
{
private T _target;
public DemoInterceptor(T target)
{
_target = target;
}
public void Intercept(IInvocation invocation)
{
if (invocation.Method.IsPublic && invocation.Method.Name.StartsWith("set_"))
{
string propertyName = invocation.Method.Name.Substring(4);
string privateFieldName = ResolvePropName(propertyName);
object original_value =
typeof(T).GetField(privateFieldName, BindingFlags.NonPublic | BindingFlags.Instance).GetValue(_target);
_target.OnPropertyChanging(propertyName, original_value);
invocation.Method.Invoke(_target, invocation.Arguments);
_target.OnPropertyChanged(propertyName);
}
else
{
invocation.ReturnValue = invocation.Method.Invoke(_target, invocation.Arguments);
}
}
public virtual string ResolvePropName(string propertyName)
{
return "_" + propertyName.Substring(0, 1).ToLower() + propertyName.Substring(1);
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用Castle.DynamicProxy;
运用系统反思;
使用系统组件模型;
名称空间
{
公共抽象类EntityBase:INotifyPropertyChanged,INotifyPropertyChanged
{
公共虚拟void onPropertyChange(字符串propertyName,对象值)
{
if((null!=属性更改))
{
PropertyChange(这是新的PropertyChangingEventArgs(propertyName));
}
}
公共虚拟void OnPropertyChanged(字符串propertyName)
{
如果((null!=PropertyChanged))
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共事件属性更改事件处理程序属性更改;
公共事件属性更改EventHandler属性更改;
}
公共类DemoInterceptor:IInterceptor,其中T:EntityBase
{
私人目标;
公共拦截器(T目标)
{
_目标=目标;
}
公共无效拦截(IInvocation调用)
{
if(invocation.Method.IsPublic&&invocation.Method.Name.StartsWith(“set”))
{
string propertyName=invocation.Method.Name.Substring(4);
字符串privateFieldName=ResolvePropName(propertyName);
对象原始值=
typeof(T).GetField(privateFieldName,BindingFlags.NonPublic | BindingFlags.Instance).GetValue(_目标);
_target.onPropertyChange(propertyName,原始值);
invocation.Method.Invoke(_target,invocation.Arguments);
_target.OnPropertyChanged(propertyName);
}
其他的
{
invocation.ReturnValue=invocation.Method.Invoke(_target,invocation.Arguments);
}
}
公共虚拟字符串ResolvePropName(字符串属性名称)
{
返回“389;”+propertyName.Substring(0,1).ToLower()+propertyName.Substring(1);
}
}
}
也许我有点晚了,但我在Linq到SharePoint模型中遇到了类似的任务。我草拟了一些代码,如果有人还在想的话
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Castle.DynamicProxy;
using System.Reflection;
using System.ComponentModel;
namespace DemoSpace
{
public abstract class EntityBase : INotifyPropertyChanged, INotifyPropertyChanging
{
public virtual void OnPropertyChanging(string propertyName, object value)
{
if ((null != PropertyChanging))
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
public virtual void OnPropertyChanged(string propertyName)
{
if ((null != PropertyChanged))
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangingEventHandler PropertyChanging;
}
public class DemoInterceptor<T> : IInterceptor where T : EntityBase
{
private T _target;
public DemoInterceptor(T target)
{
_target = target;
}
public void Intercept(IInvocation invocation)
{
if (invocation.Method.IsPublic && invocation.Method.Name.StartsWith("set_"))
{
string propertyName = invocation.Method.Name.Substring(4);
string privateFieldName = ResolvePropName(propertyName);
object original_value =
typeof(T).GetField(privateFieldName, BindingFlags.NonPublic | BindingFlags.Instance).GetValue(_target);
_target.OnPropertyChanging(propertyName, original_value);
invocation.Method.Invoke(_target, invocation.Arguments);
_target.OnPropertyChanged(propertyName);
}
else
{
invocation.ReturnValue = invocation.Method.Invoke(_target, invocation.Arguments);
}
}
public virtual string ResolvePropName(string propertyName)
{
return "_" + propertyName.Substring(0, 1).ToLower() + propertyName.Substring(1);
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用Castle.DynamicProxy;
运用系统反思;
使用系统组件模型;
名称空间
{
公共抽象类EntityBase:INotifyPropertyChanged,INotifyPropertyChanged
{
公共虚拟void onPropertyChange(字符串propertyName,对象值)
{
if((null!=属性更改))
{
PropertyChange(这是新的PropertyChangingEventArgs(propertyName));
}
}
公共虚拟void OnPropertyChanged(字符串propertyName)
{
如果((null!=PropertyChanged))
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共事件属性更改事件处理程序属性更改;
公共事件属性更改EventHandler属性更改;
}
公共类DemoInterceptor:IInterceptor,其中T:EntityBase
{
私人目标;
公共拦截器(T目标)
{
_目标=目标;
}
公共无效拦截(IInvocation调用)
{
if(invocation.Method.IsPublic&&invocation.Method.Name.StartsWith(“set”))
{
string propertyName=invocation.Method.Name.Substring(4);
字符串privateFieldName=ResolvePropName(propertyName);
对象原始值=
typeof(T).GetField(privateFieldName,BindingFlags.NonPublic | BindingFlags.Instance).GetValue(_目标);
_target.onPropertyChange(propertyName,原始值);
invocation.Method.Invoke(_target,invocation.Arguments);
_target.OnPropertyChanged(propertyName);
}
其他的
{
invocation.ReturnValue=invocation.Method.Invoke(_target,invocation.Arguments);
}
}
公共虚拟字符串ResolvePropName(字符串属性名称)
{
返回“389;”+propertyName.Substring(0,1).ToLower()+propertyName.Substring(1);
}
}
}
这是一个好主意,但如果有人决定使用auto属性而不是带有支持字段的属性,结果可能会非常糟糕。这是一个好主意,但如果有人决定使用auto属性而不是带有支持字段的属性,结果可能会非常糟糕。