Поскольку это очень распространенная проблема и хорошая причина выбрать подход AOP, как предложил Мигель, я создал пример для Afterthought , который демонстрирует реализацию INotifyPropertyChanged (перехватывает наборы свойств ввызвать событие).
Afterthought позволяет очень легко описать перехваты для свойств и, в частности, упрощает перехват набора свойств, предоставляя вам значения свойства до и после.Вы должны сделать что-то вроде этого, чтобы определить свойства для перехвата:
public override void Amend<TProperty>(Property<TProperty> property)
{
// Raise property change notifications
if (property.PropertyInfo.CanRead && property.PropertyInfo.CanWrite)
property.AfterSet = NotificationAmender<T>.OnPropertyChanged<TProperty>;
}
, который в этом случае вызывает статический метод OnPropertyChanged
, который выглядит следующим образом:
public static void OnPropertyChanged<P>(INotifyPropertyChangedAmendment instance, string property, P oldValue, P value, P newValue)
{
// Only raise property changed if the value of the property actually changed
if ((oldValue == null ^ newValue == null) || (oldValue != null && !oldValue.Equals(newValue)))
instance.OnPropertyChanged(new PropertyChangedEventArgs(property));
}
Так что если вашИсходное свойство выглядело так:
string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
Это будет выглядеть после применения вышеуказанной поправки с помощью Afterthought:
string name;
public string Name
{
get
{
return name;
}
set
{
string oldValue = Name;
name = value;
NotificationAmender<ConcreteClass>.OnPropertyChanged<string>(
this, "Name", oldValue, value, Name);
}
}
В вашем случае статический метод вызывается после (или до)сеттер может быть назван как угодно и делать что угодно.Это всего лишь пример конкретной и хорошо известной причины перехвата установщиков свойств.Учитывая, что вы знаете, что свойства не виртуальные, невозможно создать прокси-подклассы для выполнения перехвата, поэтому я думаю, что AOP-подходы, такие как Afterthought или PostSharp, - ваш лучший выбор.
Кроме того, с Afterthought вы можетереализуйте перехват таким образом, чтобы у получающихся сборок не было никаких ссылок или зависимостей от Afterthought, и если ваша логика перехвата фактически не добавляет / не изменяет API для ваших целевых типов, нет никакой причины, по которой «владелец» конкретного класса имел быпроблема с результатом.