C# 处理财产变更/通过Castle和#x27进行的财产变更;s DynamicProxy

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)) {

我目前有一个setter方法,如下所示:

 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属性而不是带有支持字段的属性,结果可能会非常糟糕。