Замок Dynamic Proxy хочет перехватить Object.GetType () - PullRequest
0 голосов
/ 12 июля 2011

В проекте я использую Castle Dynamic Proxy, чтобы обернуть весь код, выполняемый фасадом, в блоки try / catch (звучит странно? Объяснено здесь ).Это работает нормально, но чтобы убедиться, что все вызовы методов перехвачены, я выкидываю исключение, когда сталкиваюсь с чем-то не виртуальным, используя метод NonProxyableMemberNotification интерфейса IProxyGenerationHook:

public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo)
{
    throw new InvalidOperationException(string.Format(
          "Proxy failure. {0} {1} in {2} is not virtual.", 
          memberInfo.MemberType, memberInfo.Name, memberInfo.DeclaringType));
}

к великому учебнику Кшиштофа Кочича ; Классы объектов являются особыми случаями, и по умолчанию DynamicProxy просто игнорирует их .Проблема в том, что в моем случае они не игнорируются, как видно из следующего примера MemberInfo data:

memberInfo QuickWatch

Есть что-то, что я здесь пропустил?NonProxyableMemberNotification должен запускаться методами Object?

Я использую .Net 3.5, VS2010 и Castle Core версии 2.5.2, и я не переопределяю Object.GetType() в моем XmlDocumentBackend.

Ответы [ 2 ]

2 голосов
/ 06 ноября 2011

Учебное пособие было написано для версии DynamicProxy ... 2.1 IIRC.

Этот аспект DynamicProxy изменился в более поздней версии, так как были ситуации, когда методы в System.Object действительно необходимо было перехватить. (GerHashCode, Equals, ToString ...). По этой причине DP внутренне не помещает в черный список System.Object, который может быть перехвачен, и вместо этого полагается на реализацию по умолчанию IProxyGenerationHook (класс AllMethodsHook), чтобы сделать это (так, чтобы он мог быть переопределен при необходимости).

Так что если вы хотите, чтобы System.Object методы были предварительно отфильтрованы, просто наследуйте от этого класса и используйте реализацию base.

Хотя я могу понять, как это может сбивать с толку, поэтому я посмотрю, можно ли предварительно отфильтровать GetHasCode, являющийся особым случаем, даже до применения метода NonProxyableMemberNotification.

2 голосов
/ 31 октября 2011

Используйте эту реализацию NonProxyableMemberNotification:

public void NonProxyableMemberNotification(Type type, System.Reflection.MemberInfo memberInfo)
    {
        if (memberInfo.DeclaringType != typeof(object))
        {
            string message = string.Format("Non-proxyable member encountered - {0} (type - {1})",
                memberInfo.Name, type.FullName);
            throw new InvalidOperationException(message);
        }
    }
...