Идентификация прокси-классы NHibernate

Я не пользователь NHibernate; я пишу библиотеку утилиты сериализации. Пользователь зарегистрировал запрос новых функций, что я должен обработать прокси-классы NHibernate, рассматривая их то же как фактический тип. В данный момент мой код рассматривает их как неожиданное наследование и выдает исключение.

Код не будет знать заранее о NHibernate (включая никакую ссылку, но я не aftaid отражения;-p)

Существует ли устойчивое / гарантировано способ обнаружить такие типы прокси? По-видимому, DataContractSerializer дескрипторы этот штраф, таким образом, я надеюсь, что это - что-то довольно простое. Возможно, некоторый интерфейс или [attribute] художественное оформление.

Кроме того, во время десериализации; в данный момент я создал бы исходный тип (не тип NHibernate). Это хорошо для целей персистентности? Или тип прокси требуется? Если последний; что требуется, чтобы создавать экземпляр типа прокси?

37
задан Marc Gravell 18 April 2010 в 22:28
поделиться

5 ответов

Вы можете определить, является ли класс прокси-сервером NHibernate, преобразовав его (что неудивительно) в INHibernateProxy .

Если вам нужно получить базовый «реальный» объект, используйте:

Session.GetSessionImplementation().PersistenceContext.Unproxy(proxiedObject)

Вам не нужно тестировать прокси для вызова Unproxy ; он возвращает исходный параметр, если это не прокси.

Изменить: Теперь я использую другой подход для получения базового объекта, в основном для работы с отложенной загрузкой и наследованием: http://sessionfactory.blogspot.com/2010/08/hacking-lazy- loaded-inheritance.html

49
ответ дан 27 November 2019 в 04:31
поделиться

NHibernate 2.1+ позволяет установить динамический прокси-провайдер посредством конфигурации. Известные мне реализации: Castle (по умолчанию), LinFu и Spring. NHibernate не требует интерфейса или атрибута. Я думаю, что это делает практически невозможным надежное определение того, является ли объект прокси.

Как ответил s1mm0t, создание фактического типа при десериализации - это нормально.

1
ответ дан 27 November 2019 в 04:31
поделиться

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

Подойдет десериализация до исходного типа.

1
ответ дан 27 November 2019 в 04:31
поделиться

Я предполагаю, что вы действительно не хотите получать доступ к фактическому сеансу Nhibernate. Этот код может лучше соответствовать вашим потребностям:

/// <summary>
/// Returns the real type of the given proxy. If the object is not a proxy, it's normal type is returned.
/// </summary>
internal static Type GetRealType(this object proxy)
{
    if (proxy is INHibernateProxy)
    {
        var lazyInitialiser = ((INHibernateProxy)proxy).HibernateLazyInitializer;
        return lazyInitialiser.PersistentClass;
    }
    else
    {
        return proxy.GetType();
    }
}

Надеюсь, что это поможет.

16
ответ дан 27 November 2019 в 04:31
поделиться

Если вы пишете универсальную служебную библиотеку сериализации, я не думаю, что вам вообще следует обрабатывать этот конкретный случай. Ваш код не должен зависеть от NHibernate. Что вам нужно сделать, так это предоставить хуки, которые клиентский код может использовать для влияния на работу вашей библиотеки.

1
ответ дан 27 November 2019 в 04:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: