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

发布于 2024-07-13 23:05:24 字数 805 浏览 8 评论 0原文

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

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

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

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

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

I'm using Unity to resolve types dynamically for a pluggable architecture. I'm also using interception to apply business rule validation via AOP (using ValidationAspects). Finally, I'm using NHibernate as an ORM to persist domain objects.

In order for AOP to work, we use the VirtualMethodInterceptor, as interface interception doesn't work with NHibernate. I have a facade over ISession that handles casting between interface and real types for repository operations.

To make sure that all objects in the graph fetched via NHibernate are properly proxied for AOP, I made an NH IInterceptor implementation and overrode the Instantiate() method, so I could supply NH with created objects rather than have it call new(). I then use Container.Resolve() to get back proxied objects with the validation injected, and give this back to NH to populate. This works OK.

The problem comes when the session flush occurs. NHibernate gets upset because the objects it sees in the graph are of the proxy type rather than the real type. The way we're mapping (all via property, all virtual) NH should be able to get all the values it needs via the proxy, if I could override the type-checking.

What I need to know is: given a transparently proxied object created by Unity with Interception enabled, is there a) any way to obtain a direct reference to the 'real' instance it's proxying, or b) to override NH and tell it to treat objects of a proxy type as if it were of a known mapped type, dynamically at runtime?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

薯片软お妹 2024-07-20 23:05:24

我们使用拦截来进行缓存。 因此,在我们的实现 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);

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

    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 cache UpdateCallback and then resolve original service:

var service = _unityContainer.Resolve(parameters.TargetType);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文