Почему Windsor может перехватывать только виртуальные или интерфейсные методы?

Я читаю документацию и вижу, что если вы не используете интерфейс, то Windsor может перехватывать только виртуальные методы?

Это ограничение Windsor или просто языка C#? Я ищу подробный ответ.


person gcso    schedule 20.12.2011    source источник
comment
Я тоже новичок в этой технологии. Просто поймал эту ошибку, не сделал метод виртуальным.   -  person Johnny_D    schedule 24.04.2012


Ответы (4)


Язык C# здесь совершенно не при чем. Вопрос в том, как перехват работает на уровне выполнения.

Один из методов наследует от класса/реализует интерфейс и использует его в качестве прокси. Это, очевидно, может переопределить только виртуальные методы и методы интерфейса. Я подозреваю, что Виндзор использует эту технику. Преимущество этой техники в том, что она не требует ничего особенного. Просто создайте класс во время выполнения.

Другой способ — использовать профилирующий API. Это позволяет модифицировать IL любого метода, в том числе не виртуального. Это гораздо более навязчиво и обычно используется только при тестировании устаревшего кода.

Еще один способ — переписать IL во время сборки. Это может добавить точки перехвата в код, который вы написали, но не в код фреймворка.

person CodesInChaos    schedule 20.12.2011
comment
Вы правы, Windsor Intercepor — это динамический прокси: kozmic.pl/dynamic-proxy-tutorial - person Crixo; 29.12.2011
comment
Реально -1. Переполнение IL является стандартным также для хорошо спроектированного кода... Я не могу оставить свои классы открытыми для создания подклассов при разработке API (плохая практика программирования) только потому, что инструмент для насмешек слишком глуп, чтобы иметь дело с красиво закрытыми классами. - person TomTom; 09.01.2012

Это ограничение платформы .NET. Windsor создает динамическую реализацию, которая либо реализует интерфейс, либо переопределяет виртуальный элемент. .NET не позволяет переопределять члены, которые не являются виртуальными.

person Myles McDonnell    schedule 20.12.2011
comment
-1. Это ограничение низшей технологии на стороне насмешек. Некоторые коммерческие фреймворки делают это правильно. - person TomTom; 09.01.2012
comment
@TomTom, не могли бы вы назвать фреймворки, которые это делают, я хотел бы проверить их, спасибо - person Myles McDonnell; 09.01.2012
comment
У Telerik JustMock есть два режима - один через прокси, другой через замену IL. это тоже не очень дорого. Есть еще один, но он стоит 2500 долларов США за машину, включая серверы сборки. - person TomTom; 09.01.2012

Ни ни. Windsor работает путем создания подклассов, и вы можете только разумно переопределять виртуальные методы - или интерфейсы могут быть реализованы.

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

person TomTom    schedule 20.12.2011
comment
Я думаю, что Microsoft Moles бесплатна и может это сделать. Но я сам не пробовал. - person CodesInChaos; 24.04.2012
comment
Молес на пенсии. Теперь он называется Fakes и является частью Visual Studio 11;) research.microsoft.com/ ru/projects/кроты - person TomTom; 25.04.2012

Да, вам нужны виртуалы, но это только потому, что Microsoft испортила это поведение, если вы посмотрите, например, на Java, метод открыт для расширения по умолчанию, вы должны явно пометить его как запечатанный.

Узнайте больше о принципах SOLID, в частности о принципах Open Closed.

person Nexus    schedule 06.01.2012
comment
-1. Так как же создать подкласс метода selaed в Java? Остановите религиозную войну — есть веские причины во время тестирования имитировать закрытые методы, и хорошие фреймворки поддерживают это. - person TomTom; 09.01.2012
comment
Это не религиозная вещь TomTom, и да, если бы он поддерживал переплетение кода, все было бы здорово, я просто указываю, что может быть хорошей практикой следовать принципу открытого и закрытого в вашем коде, если вы не хотите, будьте моим гость :) - person Nexus; 09.01.2012
comment
Конечно. Просто держать классы открытыми — в нарушение требований проекта (закрытый API) только для облегчения модульного тестирования — это ограничение плохих мок-фреймворков. Хорошие даже могут заменить НОВЫЕ конструкции в классе другим классом. - person TomTom; 09.01.2012
comment
@TomTom, ты знаешь, что Виндзор - это не насмешливая структура, верно? - person Nexus; 09.01.2012