使用NHibernate在Unity拦截下从代理获取真实实例

使用NHibernate在Unity拦截下从代理获取真实实例,nhibernate,unity-container,aop,unity-interception,Nhibernate,Unity Container,Aop,Unity Interception,我使用Unity动态解析可插拔体系结构的类型。我还使用拦截通过AOP(使用)应用业务规则验证。最后,我使用NHibernate作为ORM来持久化域对象 为了让AOP工作,我们使用了VirtualMethodInterceptor,因为接口拦截不适用于NHibernate。我在ISession上有一个facade,用于处理存储库操作的接口和实际类型之间的转换 为了确保通过NHibernate获取的图形中的所有对象都被正确地代理为AOP,我做了一个NHIInterceptor实现,并重写了Insta

我使用Unity动态解析可插拔体系结构的类型。我还使用拦截通过AOP(使用)应用业务规则验证。最后,我使用NHibernate作为ORM来持久化域对象

为了让AOP工作,我们使用了
VirtualMethodInterceptor
,因为接口拦截不适用于NHibernate。我在
ISession
上有一个facade,用于处理存储库操作的接口和实际类型之间的转换

为了确保通过NHibernate获取的图形中的所有对象都被正确地代理为AOP,我做了一个NH
IInterceptor
实现,并重写了
Instantiate()
方法,因此我可以为NH提供创建的对象,而不是让它调用
new()
。然后,我使用
Container.Resolve()
返回插入验证的代理对象,并将其返回给NH进行填充。这样行

出现会话刷新时会出现问题。NHibernate会感到不安,因为它在图中看到的对象是代理类型而不是真实类型。如果我可以覆盖类型检查,我们映射(全部通过属性,全部通过虚拟)NH的方式应该能够通过代理获取它所需的所有值


我需要知道的是:给定一个由Unity创建的透明代理对象并启用了拦截,是否有a)任何方法可以直接引用它代理的“真实”实例,或者b)覆盖NH并告诉它将代理类型的对象视为已知映射类型,在运行时动态地?

我们使用拦截进行缓存。在我们的类中,实现了
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放入cache UpdateCallback中,然后解析原始服务:

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

你能为这个建立一个基本的测试用例吗?你有没有考虑过用NHibernate.Validator来代替这个?)我没有,不过自从你提到这件事以后,我可能会多看一看。我们特别喜欢ValidationSpect,因为它具有AOP功能—您可以执行方法或参数级验证,而无需调用任何辅助方法。即使是一个简单的测试用例也可能运行到许多LOC。我知道“问题”是什么——这是NH世界观和Unity Interceptor观之间的冲突。理论上说,温莎城堡+波斯夏普是可行的,但我喜欢团结,我想尝试一下。可能必须破解源代码:-(好的,nhibernate.validator通过事件侦听器注册,所以您不需要调用任何帮助器methodsHanks,我会仔细查看。