2009-02-24 2 views
4

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

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

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

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

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

+0

Не могли бы вы построить базовый тест-дело это? Вы считали вместо этого использование NHibernate.Validator? (http://nhforge.org/wikis/validator10/nhibernate-validator-1-0-0-documentation.aspx) –

+0

У меня не было, хотя я могу посмотреть на это немного больше, так как вы упомянули об этом. Нам нравится ValidationAspects специально из-за возможности AOP - вы можете выполнять проверку на уровне метода или на уровне параметров, не требуя вообще вызова каких-либо вспомогательных методов. –

+0

Даже простой тестовый сценарий, скорее всего, будет работать во многих LOC. Я знаю, что такое «проблема» - это столкновение между NH view of the world и представлением Interceptor Unity. В теории Castle Windsor + PostSharp будет работать, но я люблю Unity и хотел бы сделать это. Может потребоваться взломать источник :-( –

ответ

0

Мы используем перехват для кеширования. Таким образом, в нашем классе, который реализует 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); 
Смежные вопросы