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

时间:2009-02-24 18:42:02

标签: nhibernate unity-container aop unity-interception

我正在使用Unity为可插拔架构动态解析类型。我也使用拦截来通过AOP应用业务规则验证(使用ValidationAspects)。最后,我使用NHibernate作为ORM来持久保存域对象。

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

为了确保通过NHibernate获取的图形中的所有对象都正确代理AOP,我进行了NH IInterceptor实现并覆盖了Instantiate()方法,因此我可以为NH提供创建的对象而不是而不是叫它new()。然后我使用Container.Resolve()来获取注入验证的代理对象,并将其返回给NH填充。这很好用。

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

我需要知道的是:给定Unity启用拦截创建的透明代理对象,是否有a)任何方式获得对它所代理的'真实'实例的直接引用,或b)覆盖NH并告知它可以在运行时动态地处理代理类型的对象,就好像它是一个已知的映射类型一样?

1 个答案:

答案 0 :(得分: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);