Получение реального экземпляра с прокси под Unity Interception с помощью NHibernate

Я использую Unity для динамического разрешения типов для подключаемой архитектуры. Я также использую перехват для проверки бизнес-правил через АОП (используя ValidationAspects). Наконец, я использую NHibernate в качестве ORM для сохранения объектов домена.

Для работы АОП мы используем VirtualMethodInterceptor, так как перехват интерфейса не работает с NHibernate. У меня есть фасад над ISession, который обрабатывает приведение между интерфейсными и реальными типами для операций репозитория.

Чтобы убедиться, что все объекты в графе, полученные через NHibernate, правильно проксируются для АОП, я сделал реализацию NH IInterceptor и переопределил метод Instantiate(), чтобы я мог предоставлять NH созданные объекты, а не вызывать new(). Затем я использую Container.Resolve(), чтобы вернуть проксированные объекты с введенной проверкой, и возвращаю их в NH для заполнения. Это работает нормально.

Проблема возникает, когда происходит сброс сеанса. NHibernate расстраивается, потому что объекты, которые он видит в графе, относятся к типу прокси, а не к реальному типу. То, как мы отображаем (все через свойства, все виртуальные), NH должен иметь возможность получать все необходимые значения через прокси, если бы я мог переопределить проверку типов.

Что мне нужно знать, так это: учитывая прозрачно проксируемый объект, созданный Unity с включенным перехватом, есть ли а) какой-либо способ получить прямую ссылку на «реальный» экземпляр, который он проксирует, или б) переопределить NH и сказать ему обработать объекты прокси-типа, как если бы они были известного сопоставленного типа, динамически во время выполнения?


person Neil Hewitt    schedule 24.02.2009    source источник
comment
Не могли бы вы построить базовый тестовый пример этого? Рассматривали ли вы возможность использования NHibernate.Validator вместо этого? (nhforge.org/wikis/validator10/)   -  person Mauricio Scheffer    schedule 25.02.2009
comment
Я не имел, хотя я могу посмотреть на это немного больше, так как вы упомянули об этом. Нам нравится ValidationAspects именно из-за возможностей АОП — вы можете выполнять проверку методов или параметров без необходимости вообще вызывать какие-либо вспомогательные методы.   -  person Neil Hewitt    schedule 25.02.2009
comment
Даже простой тестовый пример, скорее всего, будет работать со многими LOC. Я знаю, в чем «проблема» — это конфликт между взглядом на мир NH и взглядом Unity Interceptor. Теоретически Castle Windsor + PostSharp будет работать, но мне нравится Unity, и я хотел бы попробовать. Возможно, придется взломать источник :-(   -  person Neil Hewitt    schedule 25.02.2009
comment
Ну, nhibernate.validator регистрируется через прослушиватели событий, поэтому вам не нужно вызывать какие-либо вспомогательные методы.   -  person Mauricio Scheffer    schedule 25.02.2009
comment
Спасибо, посмотрю внимательнее.   -  person Neil Hewitt    schedule 25.02.2009
comment
Я проголосовал за то, чтобы закрыть этот вопрос, потому что я пошел другим путем, и я не думаю, что ответ будет в целом полезен для других...   -  person Neil Hewitt    schedule 27.02.2009


Ответы (1)


Мы используем перехват для кэширования. Итак, в нашем классе, который реализует ICallHandler, у нас есть такой код:

    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        //...
        var nextHandler = getNext();

        var realReturn = nextHandler(input, getNext);

        var cacheRefreshingItemParameters = new CacheRefreshingItemParameters
        {
            InterfaceMethod = input.MethodBase,
            InterfaceType = input.MethodBase.DeclaringType,
            TargetType = input.Target.GetType() //remember original type
        };
        _cacheProvider.Add(cacheKey, realReturn.ReturnValue, cacheRefreshingItemParameters);

        //...
        return (cachedReturn);
    }

Мы помещаем cacheRefreshingItemParameters в кеш UpdateCallback, а затем разрешаем оригинальный сервис:

var service = _unityContainer.Resolve(parameters.TargetType);
person Backs    schedule 13.08.2015