Getting a real instance from a proxy in Unity Interception using NHibernate

I use Unity for dynamic type resolution for pluggable architecture. I also use interception to apply business rule validation through AOP (using ValidationAspects ). Finally, I use NHibernate as an ORM to save domain objects.

For AOP to work, we use VirtualMethodInterceptor , since interface hooking does not work with NHibernate. I have a facade over ISession that handles casting between an interface and real types for repository operations.

To make sure that all the objects in the graph retrieved via NHibernate are correctly proxied for AOP, I made an NH IInterceptor implementation and redefined the Instantiate() method, so I could supply the NH with the created objects instead of calling new() . Then I use Container.Resolve() to return proxied objects with validation entered and return them to NH for filling. This is working fine.

The problem occurs when the session fails. NHibernate is frustrated because the objects that it sees on the chart are of a proxy type, not a real type. The way we map (everything through the property, all virtual), NH should be able to get all the values ​​that it needs through the proxy, if I could override the type checking.

What I need to know: if a transparent proxy object created by Unity with interception enabled is: a) any way to get a direct link to the "real" instance that it is proxing, or b) redefine NH and tell it to process proxy type objects as if it were of a known display type dynamically at runtime?

+4
source share
1 answer

We use interception for caching. So, in our class that implements ICallHandler , we have this code:

  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); } 

We put cacheRefreshingItemParameters in the UpdateCallback cache, and then enable the original service:

 var service = _unityContainer.Resolve(parameters.TargetType); 
0
source

All Articles