Изменение модификатора доступа к методу с отражением

У меня есть сценарий, в котором я использую динамический прокси-сервер замка, чтобы иметь возможность перехватывать и регистрировать вызовы сообщений для любого заданного класса (назовем его целевым классом). Я делаю это, заключая целевой класс в класс, который создает прокси класса с перехватчиком, который регистрирует все вызовы методов целевого класса. Это прекрасно работает. Единственная проблема заключается в том, что для этого все общедоступные методы целевого класса должны быть виртуальными, что по многим причинам нежелательно.

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

Что мне здесь не хватает, могу ли я это как-то заархивировать?


person iCediCe    schedule 23.07.2015    source источник


Ответы (2)


Вы не можете изменить, является ли метод виртуальным или нет, используя отражение. На самом деле вы вообще ничего не можете изменить с помощью отражения, это интерфейс только для чтения к вашей структуре типа (как и должно быть).

Ваш лучший вариант — создать интерфейс для класса, обновить ссылки на него, чтобы использовать интерфейс, и создать прокси из интерфейса. Тогда ваш класс не должен иметь виртуальные методы, но ваш прокси будет реализовывать интерфейс, и перехватчик будет работать.

person Erik    schedule 23.07.2015
comment
Ах! Это отличный ответ. Но я сделал свою оболочку так, чтобы она могла либо просто регистрировать вызовы, либо регистрировать вызовы, а вызов invocation.proceed() делал фактический вызов, будет ли это возможно при таком подходе? - person iCediCe; 23.07.2015
comment
Да, как я понимаю, с таким подходом должно работать нормально. - person Erik; 23.07.2015
comment
Потрясающе. Это будет решение. спасибо за быстрый ответ! - person iCediCe; 23.07.2015

Вы можете сделать это с помощью Mono Cecil.

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

person Elan Hasson    schedule 24.07.2015
comment
Я выбрал интерфейсное решение, но это интересно. Это, вероятно, пригодится в какой-то момент. Спасибо. - person iCediCe; 27.07.2015
comment
было бы неплохо, если бы вы написали небольшой пример, а не только ссылку. Спасибо, в любом случае - person T.Todua; 25.05.2019