4

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

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

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

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

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

4

1 回答 1

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);
于 2015-08-13T14:32:33.353 回答