Замените метод установки свойств во время выполнения - PullRequest
5 голосов
/ 04 декабря 2010

У меня есть ряд объектов, которые имеют общий базовый класс, я хочу перехватывать все вызовы, которые устанавливают значения свойств, и записывать, если они были установлены для каждого экземпляра.

Могу ли я заменитьУстановить метод свойства во время выполнения с отражением?

Ответы [ 3 ]

6 голосов
/ 04 декабря 2010

Один из подходов состоит в том, чтобы сделать свойство виртуальным и во время выполнения создать подкласс с помощью рефлексии-emit, который переопределяет свойства, добавляя ваш код. Тем не менее, это сложный процесс, требующий от вас всегда создавать подкласс (поэтому в коде нет «нового»).

Тем не менее, Интересно, проще ли реализовать INotifyPropertyChanged и обработать событие? Другой вариант - просто встроить обработку в обычный класс. Есть несколько способов сделать это менее повторяющимся, особенно если у вас есть общий базовый класс, где вы можете добавить

protected void SetField<T>(ref T field, T value)
{
    if(!EqualityComparer<T>.Default.Equals(field,value))
    {
        field = value;
        // extra code here
    }
}

С

private int foo;
public int Foo {
    get { return foo; }
    set { SetField(ref foo, value); }
}
1 голос
/ 04 декабря 2010

Если ваш базовый класс является производным от ContextBoundObject, вы можете создавать свои объекты в другом контексте (в том же AppDomain) и перехватывать вызовы методов (что и есть свойства) и вставлять свой собственный приемник сообщений в приемник удаленного взаимодействия цепь.

вот один пример

http://www.codeproject.com/KB/cs/aspectintercept.aspx

0 голосов
/ 06 декабря 2010

Вы не можете напрямую заменить его во время выполнения.Если свойство является виртуальным, вы можете использовать DynamicProxy, как у http://www.castleproject.org/dynamicproxy/index.html Касла, чтобы создать для вас тип прокси, который расширяет ваш тип, и его фабрика может использоваться для получения класса, который может перехватывать его.методы.

В качестве альтернативы вы можете пойти по маршруту ContextBoundObject или Enterprise Libaries Policy Injection.http://msdn.microsoft.com/en-us/library/cc511729.aspx

Имейте в виду, ContextBoundObject намного медленнее, чем динамический прокси Касла, но вам не нужно объявлять ваши методы виртуальными.Внедрение политики позволяет вставлять только советы до или после вызова, поэтому вы не можете остановить вызов, если по какой-либо причине вы против.

Если вы можете справиться с этим как с этапом посткомпиляции, вы можете использовать PostSharp или Mono.Cecil.

Я лично работаю над своим собственным динамическим прокси, который позволяет заменять методы делегатами., но он почти не готов к свету лайма.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...