Handling PropertyChanging/PropertyChanged via Castle's DynamicProxy

女生的网名这么多〃 提交于 2019-12-22 00:42:25

问题


I currently have a setter method which looks like this:

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

        }
    }

I have implemented this with help from Dr Wily's Apprentice (http://stackoverflow.com/a/8578507/981225), with a custom Changing handler that keeps track of the old and current value, as well as the ability to set the Changing event as 'Cancelled', such that the PropertyChange will not occur.

This works perfectly. However, we have hundreds of properties and this is a lot of code the duplicate.

I have used Castle's DynamicProxy in the past, to avoid having to write 'OnPropertyChanged("A")'.

How can I implement the logic within this setter, as part of the Proxy's Intercept method? Is it possible? Thank you.


回答1:


Maybe I'm a bit late, but I came across a similar task in the Linq-To-SharePoint model. I sketched some code if some one's still wondering.

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

    }
}


来源:https://stackoverflow.com/questions/8580307/handling-propertychanging-propertychanged-via-castles-dynamicproxy

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